import { each } from './each';
/**
 * Misc Utils
 */
export const _u = {
    // Returns the size of an object or array
    size(obj) {
        if (Array.isArray(obj))
            return obj.length;
        else
            return Object.keys(obj).length;
    },
    // Returns the first item in an object or array
    first(obj) {
        return obj[Object.keys(obj)[0]];
    },
    // Returns the last item in an object or array
    last(obj) {
        return obj[Object.keys(obj)[Object.keys(obj).length - 1]];
    },
    // Returns the first key in an object
    firstKey(obj) {
        return Object.keys(obj)[0];
    },
    // Clone an object using JSON
    clone(obj) {
        let rv;
        try {
            rv = JSON.parse(JSON.stringify(obj));
        }
        catch (err) {
            rv = obj;
        }
        return rv;
    },
    // Turn an object into an array
    objectToArray(obj) {
        const arr = [];
        each(obj, (o, key) => {
            o.key = key;
            arr.push(o);
        });
        return arr;
    },
    // Turn an array into an object
    arrayToObject(arr) {
        const obj = {};
        each(arr, (key) => {
            obj[key] = key;
        });
        return obj;
    },
    // Turn an array into an object with the value being the index
    sortByKey(array, key, order) {
        return array.sort((a, b) => {
            const x = typeof a[key].getMonth === 'function' ? a[key].getTime() : a[key];
            const y = typeof b[key].getMonth === 'function' ? b[key].getTime() : b[key];
            if (order === 'desc') {
                return x > y ? -1 : x < y ? 1 : 0;
            }
            return x < y ? -1 : x > y ? 1 : 0;
        });
    },
    // Filter an array by key
    filterArray(arrayToFilter, key, val) {
        return arrayToFilter.filter(item => item[key] === val);
    },
    // Shuffle order of an array
    shuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
        return array;
    },
    // Compare two arrays
    arraysEqual(a1, a2) {
        /* WARNING: arrays must not contain {objects} or behavior may be undefined */
        return JSON.stringify(a1) === JSON.stringify(a2);
    },
    // Check if an input is falsey
    isFalse(input) {
        let rv = false;
        if (typeof input === 'undefined')
            rv = true;
        else if (input === false)
            rv = true;
        else if (input === '')
            rv = true;
        else if (input === null)
            rv = true;
        return rv;
    },
    // Check if an input is truthy
    isTrue(input) {
        return !_u.isFalse(input);
    },
    // Check if an input is a number
    isNumeric(input) {
        return !isNaN(input);
    },
    // Check if an input is a string
    isString(input) {
        return typeof input === 'string';
    },
    // Check if an input is an object
    isObject(input) {
        return typeof input === 'object';
    },
    // Check if an input is an array
    isArray(input) {
        return Array.isArray(input);
    },
    // Get query param from URL
    request(param) {
        return _u.getQuery(param);
    },
    // Get query param from URL, too
    getQuery(param) {
        return new URLSearchParams(window.location.search).get(param);
    },
    // Set query param in URL
    setQuery(param, value) {
        var qp = new URLSearchParams(window.location.search);
        qp.set(param, value);
        history.replaceState(null, '', '?' + qp.toString());
    },
    // Calculate the progress between two number based on a progress value
    progressBetween: (start, end, progress) => {
        if (progress > 1)
            progress = 1;
        if (progress < 0)
            progress = 0;
        return start + (end - start) * progress;
    },
    // Copy text to clipboard
    copyClipBoard(text) {
        /* Get the text field */
        var copyEl = document.createElement('input');
        copyEl.value = text;
        /* Select the text field */
        copyEl.select();
        copyEl.setSelectionRange(0, 99999); /* For mobile devices */
        /* Copy the text inside the text field */
        navigator.clipboard.writeText(copyEl.value);
    },
    // Set to store generated IDs to prevent duplicates
    idSet: new Set(),
    // Generate a unique ID as a number
    getId() {
        const idLength = 10; // length of the ID
        const maxNumber = Math.pow(10, idLength) - 1; // maximum number based on the length
        // loop until a unique ID is generated
        while (true) {
            const randomNumber = Math.floor(Math.random() * maxNumber);
            if (!_u.idSet.has(randomNumber)) {
                _u.idSet.add(randomNumber);
                return randomNumber;
            }
        }
    },
    // Generate a unique ID as a string, in the style of YouTube IDs
    getIdString() {
        const idLength = 11; // length of the ID
        const possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
        let uniqueId = '';
        for (let i = 0; i < idLength; i++) {
            // get a random character from the possible characters
            const randomChar = possibleChars.charAt(Math.floor(Math.random() * possibleChars.length));
            uniqueId += randomChar;
        }
        return uniqueId;
    },
    // Generated an id based on a string, can be used for HTML ids
    stringToID(val) {
        val = val.toLowerCase();
        val = val.replace(/[^(!_)a-zA-Z 0-9]+/g, '');
        val = val.replace(/^\s+|\s+$/gm, '');
        val = val.split(' ').join('_');
        return val;
    },
    // Check if a string is uppercase
    isUpperCase(str) {
        let isLowerCase = str == str.toLowerCase() && str != str.toUpperCase();
        return !isLowerCase;
    },
    // Good for turning for examples ids into better looking labels
    fancify(str) {
        // Cut of everything behind the last double underscore
        let last_ = str.lastIndexOf('_');
        if (last_ > -1) {
            if (str.substr(last_ - 1, 2) === '__') {
                str = str.substr(0, last_ - 1);
            }
        }
        // Convert camelCase to spaces
        let unCameledStr = '';
        for (let index = 0; index < str.length; index++) {
            let char = str.charAt(index);
            if (_u.isUpperCase(char) && !_u.isNumeric(char)) {
                unCameledStr += ' ' + char;
            }
            else {
                unCameledStr += char;
            }
        }
        str = unCameledStr;
        str = str.replaceAll('_', ' ');
        str = str.replaceAll('$', '.'); // Use dollar sign as dot
        str = str.replaceAll('  ', ' ');
        str = str.replaceAll('  ', ' ');
        str = str.substr(0, 1).toUpperCase() + str.substr(1);
        return str;
    },
    // Cast anything into a proper type
    stringCast(s) {
        if (typeof s !== 'string') {
            return s;
        }
        const check = function (s) {
            if (s.toLowerCase() === 'true') {
                return true;
            }
            if (s.toLowerCase() === 'false') {
                return false;
            }
            if (!isNaN(s.replace(',', '.'))) {
                s = s.replace(',', '.');
                if (s.indexOf('.')) {
                    return parseFloat(s);
                }
                return parseInt(s);
            }
            return s;
        };
        if (s === '') {
            return '';
        }
        if (s.indexOf('{') === -1) {
            return check(s);
        }
        try {
            const o = JSON.parse(s);
            if (o && typeof o === 'object' && o !== null) {
                return o;
            }
        }
        catch (e) {
            check(s);
        }
    },
};
//# sourceMappingURL=_u.js.map