import { WeekTo } from './at-parts';
import { Interval } from './interval/interval';
import { buildIntervalData } from './interval/interval-forge';
export function addSubTime(at, intervalArg, direction) {
    const ainterval = buildIntervalData(intervalArg);
    direction = direction * (ainterval.inversed ? -1 : 1);
    const cloneAt = new Date(at.getTime());
    if (ainterval.Y) {
        cloneAt.setFullYear(cloneAt.getFullYear() + (ainterval.Y * direction));
    }
    if (ainterval.M) {
        cloneAt.setMonth(cloneAt.getMonth() + (ainterval.M * direction));
    }
    if (ainterval.W) {
        cloneAt.setDate(cloneAt.getDate() + (ainterval.W * WeekTo.days * direction));
    }
    if (ainterval.D) {
        cloneAt.setDate(cloneAt.getDate() + (ainterval.D * direction));
    }
    if (ainterval.h) {
        cloneAt.setUTCHours(cloneAt.getUTCHours() + (ainterval.h * direction));
    }
    if (ainterval.m) {
        cloneAt.setUTCMinutes(cloneAt.getUTCMinutes() + (ainterval.m * direction));
    }
    if (ainterval.s) {
        cloneAt.setUTCSeconds(cloneAt.getUTCSeconds() + (ainterval.s * direction));
    }
    if (ainterval.ms) {
        cloneAt.setUTCMilliseconds(cloneAt.getUTCMilliseconds() + (ainterval.ms * direction));
    }
    return cloneAt;
}
export function addTime(at, intervalArg) {
    return addSubTime(at, intervalArg, 1);
}
export function addTimeFromNow(interval) {
    return addSubTime(new Date(), interval, 1);
}
export function subTime(at, interval) {
    return addSubTime(at, interval, -1);
}
export function subTimeFromNow(interval) {
    return addSubTime(new Date(), interval, -1);
}
/**
 * Retourne les secondes arrondies d'une dates
 */
export function getRoundSeconds(at) {
    return Math.round(at.getTime() / 1000);
}
/**
 * Détermine si deux date sont équivalentes à la seconde près
 */
export function equal(at1, at2) {
    return getRoundSeconds(at1) === getRoundSeconds(at2);
}
/**
 * Retourne l'interval entre deux object Date
 * Si le premier est plus récent que le second, l'interval
 * n'est pas "inversed", sinon il l'est.
 */
export function diff(at1, at2) {
    let diffAt = at1.getTime() - at2.getTime();
    let inversed = false;
    if (diffAt < 0) {
        inversed = true;
        diffAt *= -1;
    }
    const at = new Date(diffAt);
    // Suppression du décalage horaire
    return new Interval({
        Y: at.getFullYear() - 1970,
        M: at.getMonth(),
        W: 0,
        D: at.getDate() - 1,
        h: at.getHours() + (at.getTimezoneOffset() / 60),
        m: at.getMinutes(),
        s: at.getSeconds(),
        ms: at.getMilliseconds(),
        inversed: inversed
    });
}
export function getAt(spec) {
    if (typeof spec === 'object') {
        return spec;
    }
    const timestamp = Date.parse(spec);
    if (isNaN(timestamp)) {
        return null;
    }
    return new Date(timestamp);
}
/**
 * @deprecated
 */
export function safeParse(spec) {
    return getAt(spec);
}
export function isValid(at) {
    return at && !isNaN(at.getTime());
}
export function atToDayBegin(at) {
    at.setHours(0, 0, 0, 0);
}
export function atToDayEnd(at) {
    at.setHours(23, 59, 59, 999);
}
export function atToMonthBegin(at) {
    at.setDate(1);
    atToDayBegin(at);
}
export function atToMonthEnd(at) {
    at.setDate(15);
    at.setMonth(at.getMonth() + 1);
    atToMonthBegin(at);
    at.setMilliseconds(at.getMilliseconds() - 1);
}
export function atToYearBegin(at) {
    at.setMonth(0);
    atToMonthBegin(at);
}
export function atToYearEnd(at) {
    at.setMonth(11);
    atToMonthEnd(at);
}
export function getDayBeginAt(at) {
    const cAt = new Date(at);
    atToDayBegin(cAt);
    return cAt;
}
export function getDayEndAt(at) {
    const cAt = new Date(at);
    atToDayEnd(cAt);
    return cAt;
}
export function getMonthBeginAt(at) {
    const cAt = new Date(at);
    atToMonthBegin(cAt);
    return cAt;
}
export function getMonthEndAt(at) {
    const cAt = new Date(at);
    atToMonthEnd(cAt);
    return cAt;
}
export function getYearBeginAt(at) {
    const cAt = new Date(at);
    atToYearBegin(cAt);
    return cAt;
}
export function getYearEndAt(at) {
    const cAt = new Date(at);
    atToYearEnd(cAt);
    return cAt;
}
