MODULE = Date                PACKAGE = Date
PROTOTYPES: DISABLE
#///////////////////////////// STATIC FUNCTIONS ///////////////////////////////////

DateInt* idate (SV* arg1, SV* arg2 = NULL) {
    RETVAL = new DateInt(sv2dateint(arg1, arg2));
}

#///////////////////////////// OBJECT METHODS ///////////////////////////////////
MODULE = Date                PACKAGE = Date::Int
PROTOTYPES: DISABLE

DateInt* new (SV*, SV* arg1, SV* arg2 = NULL) {
    RETVAL = new DateInt(sv2dateint(arg1, arg2));
}

void DateInt::set (SV* arg1, SV* arg2 = NULL) {
    *THIS = sv2dateint(arg1, arg2);
}

string DateInt::to_string (...) : ALIAS(as_string=1, string=2) {
    RETVAL = THIS->to_string();
    PERL_UNUSED_VAR(ix);
}

Date* DateInt::from (SV* fromSV = NULL) {
    if (fromSV) {
        THIS->from().set(sv2date(fromSV));
        XSRETURN_UNDEF;
    }
    RETVAL = new Date(THIS->from());
}

Date* DateInt::till (SV* tillSV = NULL) {
    if (tillSV) {
        THIS->till().set(sv2date(tillSV));
        XSRETURN_UNDEF;
    }
    RETVAL = new Date(THIS->till());
}

ptime_t DateInt::sec () : ALIAS(secs=1, second=2, seconds=3, duration=4) {
    RETVAL = THIS->sec();
    PERL_UNUSED_VAR(ix);
}

ptime_t DateInt::imin () : ALIAS(imins=1, iminute=2, iminutes=3) {
    RETVAL = THIS->imin();
    PERL_UNUSED_VAR(ix);
}

double DateInt::min () : ALIAS(mins=1, minute=2, minutes=3) {
    RETVAL = THIS->min();
    PERL_UNUSED_VAR(ix);
}

ptime_t DateInt::ihour () : ALIAS(ihours=1) {
    RETVAL = THIS->ihour();
    PERL_UNUSED_VAR(ix);
}

double DateInt::hour () : ALIAS(hours=1) {
    RETVAL = THIS->hour();
    PERL_UNUSED_VAR(ix);
}

ptime_t DateInt::iday () : ALIAS(idays=1) {
    RETVAL = THIS->iday();
    PERL_UNUSED_VAR(ix);
}

double DateInt::day () : ALIAS(days=1) {
    RETVAL = THIS->day();
    PERL_UNUSED_VAR(ix);
}

ptime_t DateInt::imonth () : ALIAS(imon=1, imons=2, imonths=3) {
    RETVAL = THIS->imonth();
    PERL_UNUSED_VAR(ix);
}

double DateInt::month () : ALIAS(mon=1, mons=2, months=3) {
    RETVAL = THIS->month();
    PERL_UNUSED_VAR(ix);
}

ptime_t DateInt::iyear () : ALIAS(iyears=1) {
    RETVAL = THIS->iyear();
    PERL_UNUSED_VAR(ix);
}

double DateInt::year () : ALIAS(years=1) {
    RETVAL = THIS->year();
    PERL_UNUSED_VAR(ix);
}

DateRel* DateInt::relative () {
    RETVAL = new DateRel(THIS->relative());
}

bool DateInt::to_bool (...) {
    RETVAL = THIS->duration() != 0;
}

ptime_t DateInt::to_number (...) {
    RETVAL = THIS->duration();
}

int DateInt::compare (Sv arg, bool reverse = false) {
    if (arg.is_object_ref())       RETVAL = THIS->compare(*xs::in<DateInt*>(arg));
    else if (arg.is_like_number()) RETVAL = THIS->duration() - xs::in<ptime_t>(arg);
    else                           RETVAL = THIS->compare(sv2dateint(arg));
    if (reverse) RETVAL = -RETVAL;
    if      (RETVAL < 0) RETVAL = -1;
    else if (RETVAL > 0) RETVAL = 1;
}

bool DateInt::is_same (Sv arg, ...) : ALIAS(equals=1) {
    if (ix == 1) warn("equals() is deprecated, use is_same() instead");
    RETVAL = THIS->is_same(sv2dateint(arg));
}

int DateInt::includes (Sv arg, bool reverse = false) {
    RETVAL = THIS->includes(sv2date(arg));
    if (reverse) RETVAL = -RETVAL;
}

DateInt* DateInt::sum (Sv arg, ...) : ALIAS(add_new=1) {
    if (ix == 1) warn("add_new() is deprecated, use sum() instead");
    RETVAL = new DateInt(*THIS + sv2daterel(arg));
    PROTO = Object(ST(0)).stash();
}

SV* DateInt::add (Sv arg, ...) {
    *THIS += sv2daterel(arg); 
    XSRETURN(1);
}

DateInt* DateInt::difference (Sv arg, bool reverse = false) : ALIAS(subtract_new=1) {
    if (ix == 1) warn("subtract_new() is deprecated, use difference() instead");
    if (reverse) throw "cannot subtract interval from something";
    RETVAL = new DateInt(*THIS - sv2daterel(arg));
    PROTO = Object(ST(0)).stash();
}

SV* DateInt::subtract (Sv arg, ...) {
    *THIS -= sv2daterel(arg);
    XSRETURN(1);
}

DateInt* DateInt::negated (...) : ALIAS(negative_new=1) {
    if (ix == 1) warn("negative_new() is deprecated, use negated() instead");
    RETVAL = new DateInt(THIS->negated());
    PROTO = Object(ST(0)).stash();
}

SV* DateInt::negate () : ALIAS(negative=1) {
    if (ix == 1) warn("negative() is deprecated, use negate() instead");
    THIS->negate();
    XSRETURN(1);
}

DateInt* DateInt::clone () {
    RETVAL = new DateInt(*THIS);
    PROTO = Object(ST(0)).stash();
}