import absFloor from '../utils/abs-floor';

import { cloneWithOffset } from '../units/offset';

import { normalizeUnits } from '../units/aliases';



export function diff (input, units, asFloat) {

    var that,

        zoneDelta,

        delta, output;



    if (!this.isValid()) {

        return NaN;

    }



    that = cloneWithOffset(input, this);



    if (!that.isValid()) {

        return NaN;

    }



    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;



    units = normalizeUnits(units);



    switch (units) {

        case 'year': output = monthDiff(this, that) / 12; break;

        case 'month': output = monthDiff(this, that); break;

        case 'quarter': output = monthDiff(this, that) / 3; break;

        case 'second': output = (this - that) / 1e3; break; // 1000

        case 'minute': output = (this - that) / 6e4; break; // 1000 * 60

        case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60

        case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst

        case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst

        default: output = this - that;

    }



    return asFloat ? output : absFloor(output);

}



function monthDiff (a, b) {

    // difference in months

    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),

        // b is in (anchor - 1 month, anchor + 1 month)

        anchor = a.clone().add(wholeMonthDiff, 'months'),

        anchor2, adjust;



    if (b - anchor < 0) {

        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');

        // linear across the month

        adjust = (b - anchor) / (anchor - anchor2);

    } else {

        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');

        // linear across the month

        adjust = (b - anchor) / (anchor2 - anchor);

    }



    //check for negative zero, return zero if negative zero

    return -(wholeMonthDiff + adjust) || 0;

}

