const weekday = [
        'Sunday',
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday'
    ],
    abrWeekday = [
        'Sun',
        'Mon',
        'Tue',
        'Wed',
        'Thu',
        'Fri',
        'Sat',
        'Sun'
    ],
    month = [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December'
    ],
    abrMonth = [
        'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec'
    ],
    RIGHT_PAD = 0,
    LEFT_PAD = 1;

export function strPad(val, len, dir = RIGHT_PAD, str = '0') {
    const _val = ('' + val).slice(0, len);

    if (dir === LEFT_PAD) {
        return Array(len - _val.length + 1).join(str) + _val;
    }

    return _val + Array(len - _val.length + 1).join(str);
}

export function padMoney(val, delimiter = ',', decimal = '.', grouping = 3) {
    const _val = '' + (Math.round((Math.abs(val) || 0) * 100) / 100),
        parts = [];
    let idx = _val.indexOf('.'),
        dollars,
        i;

    if (idx < 0) {
        idx = _val.length;
    }

    dollars = _val.slice(0, idx);

    const cents = strPad(_val.slice(idx + 1), 2, RIGHT_PAD);
    const digits = dollars.split('');

    i = digits.length - 1;

    while (i >= 0) {
        const counter = digits.length - i - 1;

        if (counter && counter % grouping === 0) {
            parts.push(delimiter);
        }

        parts.push(digits[i]);
        i --;
    }

    dollars = parts.reverse().join('');

    return `${dollars}${decimal}${cents}`;
}

export function moneyFormatter(locale) {
    let prefix = '',
        suffix = '',
        delimiter = ',',
        decimal = '.';

    switch (locale) {
        default:
            prefix = '$';
            suffix = '';
            delimiter = ',';
            decimal = '.';
            break;
    }

    return function(val) {
        return prefix + padMoney(val, delimiter, decimal) + suffix;
    };
}

/**\

    Date Formatting
        just call .date(new Date(), '%b %Y'). All of the format string
        options are as follows:

        %y - year without century as a decimal number [00,99].
        %Y - year with century as a decimal number.
        %b - abbreviated month name.
        %B - full month name.
        %m - month as a decimal number [1,12].
        %n - zero-padded month as a decimal number [01,12].
        %c - day of the month as a decimal number [1, 31].
        %d - zero-padded day of the month as a decimal number [01,31].
        %e - space-padded day of the month as a decimal number [ 1,31].
        %a - abbreviated weekday name.
        %A - full weekday name.
        %w - weekday as a decimal number [0(Sunday),6].
        %H - hour (24-hour clock) as a decimal number [00,23].
        %I - hour (12-hour clock) as a decimal number [01,12].
        %M - minute as a decimal number [00,59].
        %p - either AM or PM.
        %S - second as a decimal number [00,59].

\**/
export function date(inDate, format = '%b. %e, %Y, %I:%M %p') {
    const _inDate = inDate instanceof Date ? inDate : new Date(inDate),
        day = _inDate.getDay(),
        _month = _inDate.getMonth(),
        _date = _inDate.getDate(),
        hour = _inDate.getHours(),
        littleHour = (hour % 12) === 0 ? 12 : hour % 12,
        min = _inDate.getMinutes(),
        sec = _inDate.getSeconds(),
        year = '' + _inDate.getFullYear();

    return format.replace(/%a/, abrWeekday[day], 'g')
        .replace(/%A/, weekday[day], 'g')
        .replace(/%w/, day, 'g')
        .replace(/%b/, abrMonth[_month], 'g')
        .replace(/%B/, month[_month], 'g')
        .replace(/%c/, _date, 'g')
        .replace(/%d/, strPad(_date, 2, LEFT_PAD), 'g')
        .replace(/%e/, strPad(_date, 2, LEFT_PAD, ' '), 'g')
        .replace(/%H/, strPad(hour, 2, LEFT_PAD), 'g')
        .replace(/%I/, strPad(littleHour, 2, LEFT_PAD), 'g')
        .replace(/%m/, _month + 1, 'g')
        .replace(/%n/, strPad(_month + 1, 2, LEFT_PAD), 'g')
        .replace(/%M/, strPad(min, 2, LEFT_PAD), 'g')
        .replace(/%p/, (hour > 11 ? 'PM' : 'AM'), 'g')
        .replace(/%S/, strPad(sec, 2, LEFT_PAD), 'g')
        .replace(/%y/, year.slice(2), 'g')
        .replace(/%Y/, year, 'g');
}
