/*
*******************************************************************************
*                                                                             *
* COPYRIGHT:                                                                  *
*   (C) Copyright Taligent, Inc.,  1997                                       *
*   (C) Copyright International Business Machines Corporation,  1997-1998     *
*   Licensed Material - Program-Property of IBM - All Rights Reserved.        *
*   US Government Users Restricted Rights - Use, duplication, or disclosure   *
*   restricted by GSA ADP Schedule Contract with IBM Corp.                    *
*                                                                             *
*******************************************************************************
*
* 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 "resbund.h"
#include "gregocal.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)
:   fTime(0),
    fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fLenient(TRUE),
    fZone(0),
    fNextStamp(kMinimumUserStamp)
{
    clear();
    fZone = TimeZone::createDefault();
    setWeekCountData(Locale::getDefault(), success);
}

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

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

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

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

Calendar::Calendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& success)
:   fTime(0),
    fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fLenient(TRUE),
    fZone(0),
    fNextStamp(kMinimumUserStamp)
{
    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)
    {
        icu_arrayCopy(right.fFields, fFields, FIELD_COUNT);
        icu_arrayCopy(right.fIsSet, fIsSet, FIELD_COUNT);
        icu_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 (FAILURE(success)) return 0;
    // right now, createInstance will always return an instance of GregorianCalendar
    Calendar* c = new GregorianCalendar(success);
    if (FAILURE(success)) { delete c; c = 0; }
    return c;
}

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

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

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

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

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

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

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

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

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

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

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

bool_t
Calendar::operator==(const Calendar& that) const
{
    UErrorCode status = 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));
*/
}

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

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

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

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

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

bool_t
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==
bool_t 
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)icu_getUTCtime() * kMillisPerSecond; // 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(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(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 (SUCCESS(status)) ((Calendar*)this)->complete(status); // Cast away const
    return 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;
}

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

bool_t
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;
    }
}

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

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(bool_t lenient)
{
    fLenient = lenient;
}

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

bool_t
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 (FAILURE(status)) return 0;

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

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

    delete[] number;

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

    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
    //   }

    const UnicodeString *dateTimeElements;
    int32_t count;

    if (FAILURE(status)) return;
    ResourceBundle resource(Locale::getDataDirectory(), desiredLocale, status);

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

    dateTimeElements = resource.getStringArray(kDateTimeElements, count, status);
    if (FAILURE(status)) return;
    if (count != 2)
    {
        status = INVALID_FORMAT_ERROR;
        return;
    }

    fFirstDayOfWeek = (Calendar::EDaysOfWeek)stringToDayNumber(dateTimeElements[0], status);
    fMinimalDaysInFirstWeek = (uint8_t)stringToDayNumber(dateTimeElements[1], 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(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
