import { DropDownOption } from '../entity/dropDownOption';

export class ArrayUtils {

    public static Equals(array1, array2) {
        // if the other array is a falsy value, return
        if (!array2)
            return false;

        // compare lengths - can save a lot of time 
        if (array1.length != array2.length)
            return false;

        for (var i = 0, l = array1.length; i < l; i++) {
            // Check if we have nested arrays
            if (array1[i] instanceof Array && array2[i] instanceof Array) {
                // recurse into the nested arrays
                if (!ArrayUtils.Equals(array1[i], array2[i]))
                    return false;
            }
            else if (array1[i] != array2[i]) {
                // Warning - two different object instances will never be equal: {x:20} != {x:20}
                return false;
            }
        }
        return true;
    }

    public static ToDropDownOptions<T>(array: T[], keyProperty: (value: T) => any, valueProperty: (value: T) => any): DropDownOption[] {


        return array.map(element => new DropDownOption(keyProperty(element), valueProperty(element)));
    }
    public static MoveItem(arr: any[], old_index, new_index) {
        if (new_index >= arr.length) {
            var k = new_index - arr.length + 1;
            while (k--) {
                arr.push(undefined);
            }
        }
        arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
    };
    public static Shuffle(array) {
        let currentIndex = array.length, randomIndex;

        // While there remain elements to shuffle.
        while (currentIndex > 0) {

            // Pick a remaining element.
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex--;

            // And swap it with the current element.
            [array[currentIndex], array[randomIndex]] = [
                array[randomIndex], array[currentIndex]];
        }

        return array;
    }
    public static orderByThenBy<T>(
        array: T[],
        ...criteria: ((a: T, b: T) => number)[]
    ): T[] {
        return array.sort((a, b) => {
            for (const compare of criteria) {
                const result = compare(a, b);
                if (result !== 0) return result;
            }
            return 0;
        });
    }
}