/*
*******************************************************************************
* Copyright (C) 1997-2001, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File CALENDAR.CPP
*
* Modification History:
*
*   Date        Name        Description
*   02/03/97    clhuang     Creation.
*   04/22/97    aliu        Cleaned up, fixed memory leak, made 
*                           setWeekCountData() more robust.  
*                           Moved platform code to TPlatformUtilities.
*   05/01/97    aliu        Made equals(), before(), after() arguments const.
*   05/20/97    aliu        Changed logic of when to compute fields and time
*                           to fix bugs.
*   08/12/97    aliu        Added equivalentTo.  Misc other fixes.
*   07/28/98    stephen     Sync up with JDK 1.2
*   09/02/98    stephen     Sync with JDK 1.2 8/31 build (getActualMin/Max)
*   03/17/99    stephen     Changed adoptTimeZone() - now fAreFieldsSet is
*                           set to FALSE to force update of time.
*******************************************************************************
*/

#include "cpputils.h"
#include "unicode/resbund.h"
#include "unicode/gregocal.h"
#include "unicode/calendar.h"

// Resource bundle tags read by this class
const char* Calendar::kDateTimeElements = "DateTimeElements";

// Data flow in Calendar
// ---------------------

// The current time is represented in two ways by Calendar: as UTC
// milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
// fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
// millis from the fields, and vice versa.  The data needed to do this
// conversion is encapsulated by a TimeZone object owned by the Calendar.
// The data provided by the TimeZone object may also be overridden if the
// user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
// keeps track of what information was most recently set by the caller, and
// uses that to compute any other information as needed.

// If the user sets the fields using set(), the data flow is as follows.
// This is implemented by the Calendar subclass's computeTime() method.
// During this process, certain fields may be ignored.  The disambiguation
// algorithm for resolving which fields to pay attention to is described
// above.

//   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
//           |
//           | Using Calendar-specific algorithm
//           V
//   local standard millis
//           |
//           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
//           V
//   UTC millis (in time data member)

// If the user sets the UTC millis using setTime(), the data flow is as
// follows.  This is implemented by the Calendar subclass's computeFields()
// method.

//   UTC millis (in time data member)
//           |
//           | Using TimeZone getOffset()
//           V
//   local standard millis
//           |
//           | Using Calendar-specific algorithm
//           V
//   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)

// In general, a round trip from fields, through local and UTC millis, and
// back out to fields is made when necessary.  This is implemented by the
// complete() method.  Resolving a partial set of fields into a UTC millis
// value allows all remaining fields to be generated from that value.  If
// the Calendar is lenient, the fields are also renormalized to standard
// ranges when they are regenerated.

// -------------------------------------

Calendar::Calendar(UErrorCode& success)
:   fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fNextStamp(kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    clear();
    fZone = TimeZone::createDefault();
    setWeekCountData(Locale::getDefault(), success);
}

// -------------------------------------

Calendar::Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
:   fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fNextStamp(kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    if(zone == 0) {
        success = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    clear();    
    fZone = zone;
    
    setWeekCountData(aLocale, success);
}

// -------------------------------------

Calendar::Calendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& success)
:   fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fNextStamp(kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    clear();
    fZone = zone.clone();
    setWeekCountData(aLocale, success);
}

// -------------------------------------

Calendar::~Calendar()
{
    delete fZone;
}

// -------------------------------------

Calendar::Calendar(const Calendar &source)
{
    fZone = 0;
    *this = source;
}

// -------------------------------------

Calendar &
Calendar::operator=(const Calendar &right)
{
    if (this != &right)
    {
        uprv_arrayCopy(right.fFields, fFields, FIELD_COUNT);
        uprv_arrayCopy(right.fIsSet, fIsSet, FIELD_COUNT);
        uprv_arrayCopy(right.fStamp, fStamp, FIELD_COUNT);
        fTime                     = right.fTime;
        fIsTimeSet                 = right.fIsTimeSet;
        fAreAllFieldsSet         = right.fAreAllFieldsSet;
        fAreFieldsSet             = right.fAreFieldsSet;
        fLenient                 = right.fLenient;
        delete fZone;
        fZone                    = right.fZone->clone();
        fFirstDayOfWeek         = right.fFirstDayOfWeek;
        fMinimalDaysInFirstWeek = right.fMinimalDaysInFirstWeek;
        fNextStamp                 = right.fNextStamp;
    }
    
    return *this;
}

// -------------------------------------

Calendar*
Calendar::createInstance(UErrorCode& success)
{
    if (U_FAILURE(success)) return 0;
    // right now, createInstance will always return an instance of GregorianCalendar
    Calendar* c = new GregorianCalendar(success);
    if (U_FAILURE(success)) { delete c; c = 0; }
    return c;
}

// -------------------------------------

Calendar*
Calendar::createInstance(const TimeZone& zone, UErrorCode& success)
{
    if (U_FAILURE(success)) return 0;
    // since the Locale isn't specified, use the default locale
    Calendar* c = new GregorianCalendar(zone, Locale::getDefault(), success);
    if (U_FAILURE(success)) { delete c; c = 0; }
    return c;
}

// -------------------------------------

Calendar*
Calendar::createInstance(const Locale& aLocale, UErrorCode& success)
{
    if (U_FAILURE(success)) return 0;
    // since the TimeZone isn't specfied, use the default time zone
    Calendar* c = new GregorianCalendar(TimeZone::createDefault(), aLocale, success);
    if (U_FAILURE(success)) { delete c; c = 0; }
    return c;
}

// -------------------------------------

Calendar*
Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
{
    if (U_FAILURE(success)) {
        delete zone;
        return 0;
    }
    Calendar* c = new GregorianCalendar(zone, aLocale, success);
    if (c == 0) {
        success = U_MEMORY_ALLOCATION_ERROR;
        delete zone;
    } else if (U_FAILURE(success)) {
        delete c;
        c = 0;
    }
    return c;
}

// -------------------------------------

Calendar*
Calendar::createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode& success)
{
    if (U_FAILURE(success)) return 0;
    Calendar* c = new GregorianCalendar(zone, aLocale, success);
    if (U_FAILURE(success)) { delete c; c = 0; }
    return c;
}

// -------------------------------------

UBool
Calendar::operator==(const Calendar& that) const
{
    UErrorCode status = U_ZERO_ERROR;
    // {sfb} is this correct? (Java equals)
    return (getDynamicClassID() == that.getDynamicClassID() && 
        getTimeInMillis(status) == that.getTimeInMillis(status) &&
        fLenient == that.fLenient &&
        fFirstDayOfWeek == that.fFirstDayOfWeek &&
        fMinimalDaysInFirstWeek == that.fMinimalDaysInFirstWeek &&
        *fZone == *(that.fZone));

    // As it stands, this is a very narrowly defined ==, since the
    // Calendars must not only represent the same time; they must
    // also be in exactly the same state.  This would be looser if
    // we forced field or fTime computation, and then did the comparison.
/*
    if (this == &that) return TRUE;
    for (int32_t i=0; i<FIELD_COUNT; ++i)
    {
        if (fFields[i] != that.fFields[i] ||
            fIsSet[i] != that.fIsSet[i]) return FALSE;
    }
    return (getDynamicClassID() == that.getDynamicClassID() &&
            fTime == that.fTime &&
            fIsTimeSet == that.fIsTimeSet &&
            fAreAllFieldsSet == that.fAreAllFieldsSet &&
            fAreFieldsSet == that.fAreFieldsSet &&
            fLenient == that.fLenient &&
            (!fIsSet[ZONE_OFFSET] || (fUserSetZoneOffset == that.fUserSetZoneOffset)) &&
            (!fIsSet[DST_OFFSET] || (fUserSetDSTOffset == that.fUserSetDSTOffset)) &&
            fFirstDayOfWeek == that.fFirstDayOfWeek &&
            fMinimalDaysInFirstWeek == that.fMinimalDaysInFirstWeek &&
            *fZone == *(that.fZone));
*/
}

// -------------------------------------

UBool
Calendar::equals(const Calendar& when, UErrorCode& status) const
{
    return (this == &when ||
            getTime(status) == when.getTime(status));
}

// -------------------------------------

UBool
Calendar::before(const Calendar& when, UErrorCode& status) const
{
    return (this != &when &&
            getTimeInMillis(status) < when.getTimeInMillis(status));
}

// -------------------------------------

UBool
Calendar::after(const Calendar& when, UErrorCode& status) const
{
    return (this != &when &&
            getTimeInMillis(status) > when.getTimeInMillis(status));
}

// {sfb} not in Java API, but looks similar to operator==
UBool 
Calendar::equivalentTo(const Calendar& other) const
{
    // Return true if another Calendar object is equivalent to this one.  An equivalent
    // Calendar will behave exactly as this one does (i.e., it will have be the same subclass
    // of Calendar, and have the same time zone, week-count values, and leniency level), 
    // but may be set to a different time.
    return getDynamicClassID() == other.getDynamicClassID() &&
        fLenient                == other.fLenient &&
        fFirstDayOfWeek         == other.fFirstDayOfWeek &&
        fMinimalDaysInFirstWeek == other.fMinimalDaysInFirstWeek &&
        *fZone                  == *other.fZone;
}

// -------------------------------------


const Locale*
Calendar::getAvailableLocales(int32_t& count)
{
    return Locale::getAvailableLocales(count);
}

// -------------------------------------

UDate
Calendar::getNow()
{
    return (UDate)uprv_getUTCtime() * U_MILLIS_PER_SECOND; // return as milliseconds
}

// -------------------------------------

/**
 * Gets this Calendar's current time as a long.
 * @return the current time as UTC milliseconds from the epoch.
 */
double 
Calendar::getTimeInMillis(UErrorCode& status) const
{
    if(U_FAILURE(status)) 
        return 0.0;

    if ( ! fIsTimeSet) 
        ((Calendar*)this)->updateTime(status);
    return fTime;
}

// -------------------------------------

/**
 * Sets this Calendar's current time from the given long value.
 * @param date the new time in UTC milliseconds from the epoch.
 */
void 
Calendar::setTimeInMillis( double millis, UErrorCode& status ) {
    if(U_FAILURE(status)) 
        return;

    fIsTimeSet = TRUE;
    fTime = millis;

    fAreFieldsSet = FALSE;

    computeFields(status);
    fAreFieldsSet = TRUE;
    fAreAllFieldsSet = TRUE;
}

// -------------------------------------

int32_t
Calendar::get(EDateFields field, UErrorCode& status) const
{
    // field values are only computed when actually requested; for more on when computation
    // of various things happens, see the "data flow in Calendar" description at the top
    // of this file
    if (U_SUCCESS(status)) ((Calendar*)this)->complete(status); // Cast away const
    return U_SUCCESS(status) ? fFields[field] : 0;
}

// -------------------------------------

void
Calendar::set(EDateFields field, int32_t value)
{
    fIsTimeSet         = FALSE;
    fFields[field]     = value;
    fStamp[field]     = fNextStamp++;
    fAreFieldsSet     = FALSE;
    fIsSet[field]     = TRUE; // Remove later
}

// -------------------------------------

void
Calendar::set(int32_t year, int32_t month, int32_t date)
{
    set(YEAR, year);
    set(MONTH, month);
    set(DATE, date);
}

// -------------------------------------

void
Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute)
{
    set(YEAR, year);
    set(MONTH, month);
    set(DATE, date);
    set(HOUR_OF_DAY, hour);
    set(MINUTE, minute);
}

// -------------------------------------

void
Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, int32_t second)
{
    set(YEAR, year);
    set(MONTH, month);
    set(DATE, date);
    set(HOUR_OF_DAY, hour);
    set(MINUTE, minute);
    set(SECOND, second);
}

// -------------------------------------

void
Calendar::clear()
{
    for (int32_t i=0; i<FIELD_COUNT; ++i) {
        fFields[i]     = 0; // Must do this; other code depends on it
        fIsSet[i]     = FALSE;
        fStamp[i]     = kUnset;
    }
    
    fAreFieldsSet         = FALSE;
    fAreAllFieldsSet    = FALSE;
    fIsTimeSet             = FALSE;
}

// -------------------------------------

void
Calendar::clear(EDateFields field)
{
    fFields[field]         = 0;
    fStamp[field]         = kUnset;
    fAreFieldsSet         = FALSE;
    fAreAllFieldsSet     = FALSE;
    fIsSet[field]         = FALSE; // Remove later
    fIsTimeSet             = FALSE;
}

// -------------------------------------

UBool
Calendar::isSet(EDateFields field) const
{
    return fStamp[field] != kUnset;
}

// -------------------------------------

void
Calendar::complete(UErrorCode& status)
{
    if (!fIsTimeSet) 
        updateTime(status);
    if (!fAreFieldsSet) {
        computeFields(status); // fills in unset fields
        fAreFieldsSet         = TRUE;
        fAreAllFieldsSet     = TRUE;
    }
}

// -------------------------------------

int32_t Calendar::fieldDifference(UDate when, EDateFields field, UErrorCode& status) {
    if (U_FAILURE(status)) return 0;
    int32_t result = 0;
    double ms = getTimeInMillis(status);
    if (ms < when) {
        while (U_SUCCESS(status)) {
            add(field, 1, status);
            double newMs = getTimeInMillis(status);
            if (newMs > when) {
                setTimeInMillis(ms, status);
                break;
            }
            ms = newMs;
            ++result;
        }
    } else if (ms > when) {
        while (U_SUCCESS(status)) {
            add(field, -1, status);
            double newMs = getTimeInMillis(status);
            if (newMs < when) {
                setTimeInMillis(ms, status);
                break;
            }
            ms = newMs;
            --result;
        }
    }
    return result;
}

// -------------------------------------

void
Calendar::adoptTimeZone(TimeZone* zone)
{
    // Do nothing if passed-in zone is NULL
    if (zone == NULL) return;

    // fZone should always be non-null
    if (fZone != NULL) delete fZone;
    fZone = zone;

    // if the zone changes, we need to recompute the time fields
    fAreFieldsSet = FALSE;
}

// -------------------------------------
void
Calendar::setTimeZone(const TimeZone& zone)
{
    adoptTimeZone(zone.clone());
}

// -------------------------------------

const TimeZone&
Calendar::getTimeZone() const
{
    return *fZone;
}

// -------------------------------------

TimeZone*
Calendar::orphanTimeZone()
{
    TimeZone *z = fZone;
    // we let go of the time zone; the new time zone is the system default time zone
    fZone = TimeZone::createDefault();
    return z;
}

// -------------------------------------

void
Calendar::setLenient(UBool lenient)
{
    fLenient = lenient;
}

// -------------------------------------

UBool
Calendar::isLenient() const
{
    return fLenient;
}

// -------------------------------------

void
Calendar::setFirstDayOfWeek(EDaysOfWeek value)
{
    fFirstDayOfWeek = value;
}

// -------------------------------------

Calendar::EDaysOfWeek
Calendar::getFirstDayOfWeek() const
{
    return fFirstDayOfWeek;
}

// -------------------------------------

void
Calendar::setMinimalDaysInFirstWeek(uint8_t value)
{
    fMinimalDaysInFirstWeek = value;
}

// -------------------------------------

uint8_t
Calendar::getMinimalDaysInFirstWeek() const
{
    return fMinimalDaysInFirstWeek;
}

// -------------------------------------

int32_t
Calendar::getActualMinimum(EDateFields field, UErrorCode& status) const
{
    int32_t fieldValue = getGreatestMinimum(field);
    int32_t endValue = getMinimum(field);

    // if we know that the minimum value is always the same, just return it
    if (fieldValue == endValue) {
        return fieldValue;
    }

    // clone the calendar so we don't mess with the real one, and set it to
    // accept anything for the field values
    Calendar *work = (Calendar*)this->clone();
    work->setLenient(TRUE);

    // now try each value from getLeastMaximum() to getMaximum() one by one until
    // we get a value that normalizes to another value.  The last value that
    // normalizes to itself is the actual minimum for the current date
    int32_t result = fieldValue;

    do {
        work->set(field, fieldValue);
        if (work->get(field, status) != fieldValue) {
            break;
        } 
        else {
            result = fieldValue;
            fieldValue--;
        }
    } while (fieldValue >= endValue);

    delete work;
    return result;
}

// -------------------------------------

int32_t
Calendar::getActualMaximum(EDateFields field, UErrorCode& status) const
{
    int32_t fieldValue = getLeastMaximum(field);
    int32_t endValue = getMaximum(field);

    // if we know that the maximum value is always the same, just return it
    if (fieldValue == endValue) {
        return fieldValue;
    }

    // clone the calendar so we don't mess with the real one, and set it to
    // accept anything for the field values
    Calendar *work = (Calendar*)this->clone();
    work->setLenient(TRUE);

    // if we're counting weeks, set the day of the week to Sunday.  We know the
    // last week of a month or year will contain the first day of the week.
    if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH)
        work->set(DAY_OF_WEEK, fFirstDayOfWeek);

    // now try each value from getLeastMaximum() to getMaximum() one by one until
    // we get a value that normalizes to another value.  The last value that
    // normalizes to itself is the actual maximum for the current date
    int32_t result = fieldValue;

    do {
        work->set(field, fieldValue);
        if(work->get(field, status) != fieldValue) {
            break;
        } 
        else {
            result = fieldValue;
            fieldValue++;
        }
    } while (fieldValue <= endValue);

    delete work;
    return result;
}

// -------------------------------------

int32_t Calendar::stringToDayNumber(const UnicodeString& string, UErrorCode& status)
{
    // Convert a UnicodeString to a long integer, using the standard C library.
    // Return both the value obtained, and a UErrorCode indicating success or failure.
    // We fail if the string is zero length, of if strtol() does not parse all
    // of the characters in the string, or if the value is not in the range
    // 1..7.  (This is used to read the week-count data from the resource files;
    // ResourceBundle returns all data in string form, so we have to convert it here.)
    if (U_FAILURE(status)) return 0;

    int32_t len = string.length();
    char *number = new char[1 + len];
    if (number == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
    }
    char *end;

    string.extract(0, len, number);
    number[len] = 0;
    int32_t value = (int32_t)strtol(number, &end, 10); // Radix 10

    if (end-number != len || len == 0 || value < 1 || value > 7)
        status = U_INVALID_FORMAT_ERROR;

    delete[] number;

    return value;
}

// -------------------------------------

void
Calendar::setWeekCountData(const Locale& desiredLocale, UErrorCode& status)
{
    // Read the week count data from the resource bundle.  This should
    // have the form:
    //
    //   DateTimeElements {
    //      "1",    // first day of week
    //      "1"     // min days in week
    //   }


    if (U_FAILURE(status)) return;
    ResourceBundle resource((char *)0, desiredLocale, status);

    // If the resource data doesn't seem to be present at all, then use last-resort
    // hard-coded data.
    if (U_FAILURE(status))
    {
        status = U_USING_FALLBACK_ERROR;
        fFirstDayOfWeek = Calendar::SUNDAY;
        fMinimalDaysInFirstWeek = 1;
        return;
    }

    //dateTimeElements = resource.getStringArray(kDateTimeElements, count, status);
    ResourceBundle dateTimeElements = resource.get(kDateTimeElements, status);


    if (U_FAILURE(status)) return;
//    if (count != 2)
    if(dateTimeElements.getSize()!=2)
    {
        status = U_INVALID_FORMAT_ERROR;
        return;
    }

    //fFirstDayOfWeek = (Calendar::EDaysOfWeek)stringToDayNumber(dateTimeElements[0], status);
    //fMinimalDaysInFirstWeek = (uint8_t)stringToDayNumber(dateTimeElements[1], status);
    fFirstDayOfWeek = (Calendar::EDaysOfWeek)stringToDayNumber(dateTimeElements.getStringEx((int32_t)0, status), status);
    fMinimalDaysInFirstWeek = (uint8_t)stringToDayNumber(dateTimeElements.getStringEx(1, status), status);
}

/**
 * Recompute the time and update the status fields isTimeSet
 * and areFieldsSet.  Callers should check isTimeSet and only
 * call this method if isTimeSet is false.
 */
void 
Calendar::updateTime(UErrorCode& status) 
{
    computeTime(status);
    if(U_FAILURE(status))
        return;
        
    // If we are lenient, we need to recompute the fields to normalize
    // the values.  Also, if we haven't set all the fields yet (i.e.,
    // in a newly-created object), we need to fill in the fields. [LIU]
    if (isLenient() || ! fAreAllFieldsSet) 
        fAreFieldsSet = FALSE;
    
    fIsTimeSet = TRUE;
}

//eof
