/*
 **********************************************************************
 * Copyright (c) 2003-2008, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 * Author: Alan Liu
 * Created: September 2 2003
 * Since: ICU 2.8
 **********************************************************************
 */

#include "gregoimp.h"

#if !UCONFIG_NO_FORMATTING

#include "starboard/client_porting/poem/assert_poem.h"
#include "unicode/ucal.h"
#include "uresimp.h"
#include "cstring.h"
#include "uassert.h"

#if defined(U_DEBUG_CALDATA)
#include <stdio.h>
#endif

U_NAMESPACE_BEGIN

int32_t ClockMath::floorDivide(int32_t numerator, int32_t denominator) {
    return (numerator >= 0) ?
        numerator / denominator : ((numerator + 1) / denominator) - 1;
}

int32_t ClockMath::floorDivide(double numerator, int32_t denominator,
                          int32_t& remainder) {
    double quotient;
    quotient = uprv_floor(numerator / denominator);
    remainder = (int32_t) (numerator - (quotient * denominator));
    return (int32_t) quotient;
}

double ClockMath::floorDivide(double dividend, double divisor,
                         double& remainder) {
    // Only designed to work for positive divisors
    U_ASSERT(divisor > 0);
    double quotient = floorDivide(dividend, divisor);
    remainder = dividend - (quotient * divisor);
    // N.B. For certain large dividends, on certain platforms, there
    // is a bug such that the quotient is off by one.  If you doubt
    // this to be true, set a breakpoint below and run cintltst.
    if (remainder < 0 || remainder >= divisor) {
        // E.g. 6.7317038241449352e+022 / 86400000.0 is wrong on my
        // machine (too high by one).  4.1792057231752762e+024 /
        // 86400000.0 is wrong the other way (too low).
        double q = quotient;
        quotient += (remainder < 0) ? -1 : +1;
        if (q == quotient) {
            // For quotients > ~2^53, we won't be able to add or
            // subtract one, since the LSB of the mantissa will be >
            // 2^0; that is, the exponent (base 2) will be larger than
            // the length, in bits, of the mantissa.  In that case, we
            // can't give a correct answer, so we set the remainder to
            // zero.  This has the desired effect of making extreme
            // values give back an approximate answer rather than
            // crashing.  For example, UDate values above a ~10^25
            // might all have a time of midnight.
            remainder = 0;
        } else {
            remainder = dividend - (quotient * divisor);
        }
    }
    U_ASSERT(0 <= remainder && remainder < divisor);
    return quotient;
}

const int32_t JULIAN_1_CE    = 1721426; // January 1, 1 CE Gregorian
const int32_t JULIAN_1970_CE = 2440588; // January 1, 1970 CE Gregorian

const int16_t Grego::DAYS_BEFORE[24] =
    {0,31,59,90,120,151,181,212,243,273,304,334,
     0,31,60,91,121,152,182,213,244,274,305,335};

const int8_t Grego::MONTH_LENGTH[24] =
    {31,28,31,30,31,30,31,31,30,31,30,31,
     31,29,31,30,31,30,31,31,30,31,30,31};

double Grego::fieldsToDay(int32_t year, int32_t month, int32_t dom) {

    int32_t y = year - 1;

    double julian = 365 * y + ClockMath::floorDivide(y, 4) + (JULIAN_1_CE - 3) + // Julian cal
        ClockMath::floorDivide(y, 400) - ClockMath::floorDivide(y, 100) + 2 + // => Gregorian cal
        DAYS_BEFORE[month + (isLeapYear(year) ? 12 : 0)] + dom; // => month/dom

    return julian - JULIAN_1970_CE; // JD => epoch day
}

void Grego::dayToFields(double day, int32_t& year, int32_t& month,
                        int32_t& dom, int32_t& dow, int32_t& doy) {

    // Convert from 1970 CE epoch to 1 CE epoch (Gregorian calendar)
    day += JULIAN_1970_CE - JULIAN_1_CE;

    // Convert from the day number to the multiple radix
    // representation.  We use 400-year, 100-year, and 4-year cycles.
    // For example, the 4-year cycle has 4 years + 1 leap day; giving
    // 1461 == 365*4 + 1 days.
    int32_t n400 = ClockMath::floorDivide(day, 146097, doy); // 400-year cycle length
    int32_t n100 = ClockMath::floorDivide(doy, 36524, doy); // 100-year cycle length
    int32_t n4   = ClockMath::floorDivide(doy, 1461, doy); // 4-year cycle length
    int32_t n1   = ClockMath::floorDivide(doy, 365, doy);
    year = 400*n400 + 100*n100 + 4*n4 + n1;
    if (n100 == 4 || n1 == 4) {
        doy = 365; // Dec 31 at end of 4- or 400-year cycle
    } else {
        ++year;
    }
    
    UBool isLeap = isLeapYear(year);
    
    // Gregorian day zero is a Monday.
    dow = (int32_t) uprv_fmod(day + 1, 7);
    dow += (dow < 0) ? (UCAL_SUNDAY + 7) : UCAL_SUNDAY;

    // Common Julian/Gregorian calculation
    int32_t correction = 0;
    int32_t march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
    if (doy >= march1) {
        correction = isLeap ? 1 : 2;
    }
    month = (12 * (doy + correction) + 6) / 367; // zero-based month
    dom = doy - DAYS_BEFORE[month + (isLeap ? 12 : 0)] + 1; // one-based DOM
    doy++; // one-based doy
}

void Grego::timeToFields(UDate time, int32_t& year, int32_t& month,
                        int32_t& dom, int32_t& dow, int32_t& doy, int32_t& mid) {
    double millisInDay;
    double day = ClockMath::floorDivide((double)time, (double)U_MILLIS_PER_DAY, millisInDay);
    mid = (int32_t)millisInDay;
    dayToFields(day, year, month, dom, dow, doy);
}

int32_t Grego::dayOfWeek(double day) {
    int32_t dow;
    ClockMath::floorDivide(day + UCAL_THURSDAY, 7, dow);
    return (dow == 0) ? UCAL_SATURDAY : dow;
}

int32_t Grego::dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom) {
    int32_t weekInMonth = (dom + 6)/7;
    if (weekInMonth == 4) {
        if (dom + 7 > monthLength(year, month)) {
            weekInMonth = -1;
        }
    } else if (weekInMonth == 5) {
        weekInMonth = -1;
    }
    return weekInMonth;
}

/* ---- CalendarData ------ */

#define U_CALENDAR_KEY "calendar"
#define U_GREGORIAN_KEY "gregorian"
#define U_FORMAT_KEY "format"
#define U_DEFAULT_KEY "default"
#define U_CALENDAR_DATA ((char*)0)


// CalendarData::CalendarData(const Locale& loc, UErrorCode& status) 
//   : fFillin(NULL), fBundle(NULL), fFallback(NULL) {
//   initData(loc.getBaseName(), (char*) "???", status);
// }

CalendarData::CalendarData(const Locale& loc, const char *type, UErrorCode& status)
  : fFillin(NULL), fOtherFillin(NULL), fBundle(NULL), fFallback(NULL) {
  initData(loc.getBaseName(), type, status);
}

void CalendarData::initData(const char *locale, const char *type, UErrorCode& status) {
  fOtherFillin = ures_open(U_CALENDAR_DATA, locale, &status);
  fFillin = ures_getByKey(fOtherFillin, U_CALENDAR_KEY, fFillin, &status);

  if((type != NULL) && 
     (*type != '\0') && 
     (uprv_strcmp(type, U_GREGORIAN_KEY)))
  {
    fBundle = ures_getByKeyWithFallback(fFillin, type, NULL, &status);
    fFallback = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status);

#if defined (U_DEBUG_CALDATA)
    fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback(%p, %s)=%s\n", 
            this, locale, type, u_errorName(status), fBundle, type, fBundle?ures_getLocale(fBundle, &status):"", 
            fFallback, U_GREGORIAN_KEY, fFallback?ures_getLocale(fFallback, &status):"");
#endif

  } else {
    fBundle = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status);
#if defined (U_DEBUG_CALDATA)
    fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback = NULL\n",
            this, locale, type, u_errorName(status), fBundle, U_GREGORIAN_KEY, fBundle?ures_getLocale(fBundle, &status):"" );
#endif
  }
}

CalendarData::~CalendarData() {
    ures_close(fFillin);
    ures_close(fBundle);
    ures_close(fFallback);
    ures_close(fOtherFillin);
}

UResourceBundle*
CalendarData::getByKey(const char *key, UErrorCode& status) {
    if(U_FAILURE(status)) {
        return NULL;
    }

    if(fBundle) {
        fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: get %s -> %s - from MAIN %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
#endif
    }
    if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
        status = U_ZERO_ERROR; // retry with fallback (gregorian)
        fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: get %s -> %s - from FALLBACK %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
#endif
    }
    return fFillin;
}

UResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UErrorCode& status) {
    if(U_FAILURE(status)) {
        return NULL;
    }

    if(fBundle) {
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: //\n");
#endif
        fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
        fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
        fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status));
#endif
    }
    if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
        status = U_ZERO_ERROR; // retry with fallback (gregorian)
        fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
        fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
        fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status));
#endif
    }

//// handling of 'default' keyword on failure: Commented out for 3.0.
//   if((status == U_MISSING_RESOURCE_ERROR) && 
//      uprv_strcmp(subKey,U_DEFAULT_KEY)) { // avoid recursion
// #if defined (U_DEBUG_CALDATA)
//     fprintf(stderr, "%p: - attempting fallback -\n", this);
//     fflush(stderr);
// #endif
//     UErrorCode subStatus = U_ZERO_ERROR;
//     int32_t len;
//     char kwBuf[128] = "";
//     const UChar *kw;
//     /* fFillin = */ getByKey2(key, U_DEFAULT_KEY, subStatus);
//     kw = ures_getString(fFillin, &len, &subStatus);
//     if(len>126) { // too big
//       len = 0;
//     }
//     if(U_SUCCESS(subStatus) && (len>0)) {
//       u_UCharsToChars(kw, kwBuf, len+1);
//       if(*kwBuf && uprv_strcmp(kwBuf,subKey)) {
// #if defined (U_DEBUG_CALDATA)
//         fprintf(stderr, "%p: trying  %s/format/default -> \"%s\"\n",this, key, kwBuf);
// #endif
//         // now try again with the default
//         status = U_ZERO_ERROR;
//         /* fFillin = */ getByKey2(key, kwBuf, status);
//       }
// #if defined (U_DEBUG_CALDATA)
//     } else {
//       fprintf(stderr, "%p: could not load  %s/format/default  - fail out (%s)\n",this, key, kwBuf, u_errorName(status));
// #endif
//     }
//   }

    return fFillin;
}

UResourceBundle* CalendarData::getByKey3(const char *key, const char *contextKey, const char *subKey, UErrorCode& status) {
    if(U_FAILURE(status)) {
        return NULL;
    }

    if(fBundle) {
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: //\n");
#endif
        fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
        fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status);
        fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: get %s/%s/%s -> %s - from MAIN %s\n", this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin, &status));
#endif
    }
    if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
        status = U_ZERO_ERROR; // retry with fallback (gregorian)
        fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
        fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status);
        fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
        fprintf(stderr, "%p: get %s/%s/%s -> %s - from FALLBACK %s\n",this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin,&status));
#endif
    }

    return fFillin;
}

U_NAMESPACE_END

#endif
//eof
