import { daysInYear } from './year';

import { createLocal } from '../create/local';

import { createUTCDate } from '../create/date-from-array';



// start-of-first-week - start-of-year

function firstWeekOffset(year, dow, doy) {

    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)

        fwd = 7 + dow - doy,

        // first-week day local weekday -- which local weekday is fwd

        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;



    return -fwdlw + fwd - 1;

}



// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday

export function dayOfYearFromWeeks(year, week, weekday, dow, doy) {

    var localWeekday = (7 + weekday - dow) % 7,

        weekOffset = firstWeekOffset(year, dow, doy),

        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,

        resYear, resDayOfYear;



    if (dayOfYear <= 0) {

        resYear = year - 1;

        resDayOfYear = daysInYear(resYear) + dayOfYear;

    } else if (dayOfYear > daysInYear(year)) {

        resYear = year + 1;

        resDayOfYear = dayOfYear - daysInYear(year);

    } else {

        resYear = year;

        resDayOfYear = dayOfYear;

    }



    return {

        year: resYear,

        dayOfYear: resDayOfYear

    };

}



export function weekOfYear(mom, dow, doy) {

    var weekOffset = firstWeekOffset(mom.year(), dow, doy),

        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,

        resWeek, resYear;



    if (week < 1) {

        resYear = mom.year() - 1;

        resWeek = week + weeksInYear(resYear, dow, doy);

    } else if (week > weeksInYear(mom.year(), dow, doy)) {

        resWeek = week - weeksInYear(mom.year(), dow, doy);

        resYear = mom.year() + 1;

    } else {

        resYear = mom.year();

        resWeek = week;

    }



    return {

        week: resWeek,

        year: resYear

    };

}



export function weeksInYear(year, dow, doy) {

    var weekOffset = firstWeekOffset(year, dow, doy),

        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);

    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;

}

