/**
 * 判断是否是类型化数组
 * @param {*} object 
 */
export function isTypedArray(object: any): boolean {
    return ArrayBuffer.isView(object) &&
        !(object instanceof DataView);
}

/**
 * 截取数组
 * @param array 
 * @param from 
 * @param to 
 */
export function arraySlice(array, from: number, to?: number) {
    if (isTypedArray(array)) {
        // in ios9 array.subarray(from, undefined) will return empty array
        // but array.subarray(from) or array.subarray(from, len) is correct
        return new array.constructor(array.subarray(from, to !== undefined ? to : array.length));
    }
    return array.slice(from, to);
}

// converts an array to a specific type
export function convertArray(array, type, forceClone?: boolean) {
    if (!array || // let 'undefined' and 'null' pass
        !forceClone && array.constructor === type) return array;
    if (typeof type.BYTES_PER_ELEMENT === 'number') {
        return new type(array); // create typed array
    }
    return Array.prototype.slice.call(array); // create Array
}

// function for parsing AOS keyframe formats
export function flattenJSON(jsonKeys, times, values, valuePropertyName) {

    var i = 1, key = jsonKeys[0];

    while (key !== undefined && key[valuePropertyName] === undefined) {

        key = jsonKeys[i++];

    }

    if (key === undefined) return; // no data

    var value = key[valuePropertyName];
    if (value === undefined) return; // no data

    if (Array.isArray(value)) {

        do {

            value = key[valuePropertyName];

            if (value !== undefined) {

                times.push(key.time);
                values.push.apply(values, value); // push all elements

            }

            key = jsonKeys[i++];

        } while (key !== undefined);

    } else if (value.toArray !== undefined) {

        // ...assume THREE.Math-ish

        do {

            value = key[valuePropertyName];

            if (value !== undefined) {

                times.push(key.time);
                value.toArray(values, values.length);

            }

            key = jsonKeys[i++];

        } while (key !== undefined);

    } else {

        // otherwise push as-is

        do {

            value = key[valuePropertyName];

            if (value !== undefined) {

                times.push(key.time);
                values.push(value);

            }

            key = jsonKeys[i++];

        } while (key !== undefined);

    }

}

// returns an array by which times and values can be sorted
export function getKeyframeOrder(times) {

    function compareTime(i, j) {

        return times[i] - times[j];

    }

    var n = times.length;
    var result = new Array(n);
    for (var i = 0; i !== n; ++i) result[i] = i;

    result.sort(compareTime);

    return result;

}

// uses the array previously returned by 'getKeyframeOrder' to sort data
export function sortedArray(values, stride, order) {
    var nValues = values.length;
    var result = new values.constructor(nValues);

    for (var i = 0, dstOffset = 0; dstOffset !== nValues; ++i) {

        var srcOffset = order[i] * stride;

        for (var j = 0; j !== stride; ++j) {

            result[dstOffset++] = values[srcOffset + j];

        }

    }

    return result;

}

export var InterpolateDiscrete = 2300;
export var InterpolateLinear = 2301;
export var InterpolateSmooth = 2302;