/*
*******************************************************************************
* Copyright (C) 1997-2004, 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 "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/gregocal.h"
#include "gregoimp.h"
#include "buddhcal.h"
#include "japancal.h"
#include "islamcal.h"
#include "hebrwcal.h"
#include "chnsecal.h"
#include "unicode/calendar.h"
#include "cpputils.h"
#include "iculserv.h"
#include "ucln_in.h"
#include "cstring.h"
#include "locbased.h"
#include "uresimp.h"

#if !UCONFIG_NO_SERVICE
static ICULocaleService* gService = NULL;
#endif

// INTERNAL - for cleanup

U_CDECL_BEGIN
static UBool calendar_cleanup(void) {
#if !UCONFIG_NO_SERVICE
  if (gService) {
    delete gService;
    gService = NULL;
  }
#endif
  return TRUE;
}
U_CDECL_END

// ------------------------------------------
//
// Registration
//
//-------------------------------------------
//#define U_DEBUG_CALSVC 1
//

#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
#include <stdio.h>


/**
 * convert a UCalendarDateFields into a string - for debugging
 * @param f field enum
 * @return static string to the field name
 * @internal
 */
static const char* fldName(UCalendarDateFields f) {
    switch (f) {
#define FIELD_NAME_STR(x) case x: return (#x+5)
      FIELD_NAME_STR( UCAL_ERA );
      FIELD_NAME_STR( UCAL_YEAR );
      FIELD_NAME_STR( UCAL_MONTH );
      FIELD_NAME_STR( UCAL_WEEK_OF_YEAR );
      FIELD_NAME_STR( UCAL_WEEK_OF_MONTH );
      FIELD_NAME_STR( UCAL_DATE );
      FIELD_NAME_STR( UCAL_DAY_OF_YEAR );
      FIELD_NAME_STR( UCAL_DAY_OF_WEEK );
      FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH );
      FIELD_NAME_STR( UCAL_AM_PM );
      FIELD_NAME_STR( UCAL_HOUR );
      FIELD_NAME_STR( UCAL_HOUR_OF_DAY );
      FIELD_NAME_STR( UCAL_MINUTE );
      FIELD_NAME_STR( UCAL_SECOND );
      FIELD_NAME_STR( UCAL_MILLISECOND );
      FIELD_NAME_STR( UCAL_ZONE_OFFSET );
      FIELD_NAME_STR( UCAL_DST_OFFSET );
      FIELD_NAME_STR( UCAL_YEAR_WOY );
      FIELD_NAME_STR( UCAL_DOW_LOCAL );
      FIELD_NAME_STR( UCAL_EXTENDED_YEAR );
      FIELD_NAME_STR( UCAL_JULIAN_DAY );
      FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY );
#undef FIELD_NAME_STR
    default:
      return "??";
    }
}

#endif

static const char * const gBasicCalendars[] = { "@calendar=gregorian", "@calendar=japanese",
                                         "@calendar=buddhist", "@calendar=islamic-civil",
                                         "@calendar=islamic", "@calendar=hebrew", "@calendar=chinese",
                                         NULL };

U_NAMESPACE_BEGIN

static UBool isStandardSupportedID( const char *id, UErrorCode& status) { 
    if(U_FAILURE(status)) {
        return FALSE;
    }
    for(int32_t i=0;gBasicCalendars[i] != NULL;i++) {
        if(uprv_strcmp(gBasicCalendars[i],id) == 0) {
            return TRUE;
        }
    }
    return FALSE;
}

static Calendar *createStandardCalendar(char *calType, const Locale &canLoc, UErrorCode& status) {
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "BasicCalendarFactory %p: creating type for %s\n", 
            this, (const char*)curLoc.getName());
    fflush(stderr);
#endif

  if(!calType || !*calType || !uprv_strcmp(calType,"@calendar=gregorian")) {  // Gregorian (default)
    return new GregorianCalendar(canLoc, status);
  } else if(!uprv_strcmp(calType, "@calendar=japanese")) {
    return new JapaneseCalendar(canLoc, status);
  } else if(!uprv_strcmp(calType, "@calendar=buddhist")) {
    return new BuddhistCalendar(canLoc, status);
  } else if(!uprv_strcmp(calType, "@calendar=islamic-civil")) {
    return new IslamicCalendar(canLoc, status, IslamicCalendar::CIVIL);
  } else if(!uprv_strcmp(calType, "@calendar=islamic")) {
    return new IslamicCalendar(canLoc, status, IslamicCalendar::ASTRONOMICAL);
  } else if(!uprv_strcmp(calType, "@calendar=hebrew")) {
    return new HebrewCalendar(canLoc, status);
  //} else if(!uprv_strcmp(calType, "@calendar=chinese")) {
  //return new ChineseCalendar(canLoc, status);
  } else { 
    status = U_UNSUPPORTED_ERROR;
    return NULL;
  }
}

#if !UCONFIG_NO_SERVICE

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

/**
 * a Calendar Factory which creates the "basic" calendar types, that is, those 
 * shipped with ICU.
 */
class BasicCalendarFactory : public LocaleKeyFactory {
public:
  /**
   * @param calendarType static const string (caller owns storage - will be aliased) to calendar type
   */
  BasicCalendarFactory()
    : LocaleKeyFactory(LocaleKeyFactory::INVISIBLE) { }
  
  virtual ~BasicCalendarFactory() {}

protected:
  virtual UBool isSupportedID( const UnicodeString& id, UErrorCode& status) const { 
    if(U_FAILURE(status)) {
      return FALSE;
    }
    for(int32_t i=0;gBasicCalendars[i] != NULL;i++) {
      UnicodeString ourId(gBasicCalendars[i],"");
      if(ourId == id) {
        return TRUE;
      }
    }
    return FALSE;
  }

  virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const
  {
    if (U_SUCCESS(status)) {
      for(int32_t i=0;gBasicCalendars[i] != NULL;i++) {
        UnicodeString id(gBasicCalendars[i],"");
        result.put(id, (void*)this, status);
      }
    }
  }

  virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const {
#ifdef U_DEBUG_CALSVC
    if(key.getDynamicClassID() != LocaleKey::getStaticClassID()) {
      fprintf(stderr, "::create - not a LocaleKey!\n");
    }
#endif
    const LocaleKey& lkey = (LocaleKey&)key;
    Locale curLoc;  // current locale
    Locale canLoc;  // Canonical locale

    lkey.currentLocale(curLoc);
    lkey.canonicalLocale(canLoc);

    UnicodeString str;
    key.currentID(str);

    char tmp[200];
    // Extract a char* out of it..
    int32_t len = str.length();
    int32_t actLen = sizeof(tmp)-1;
    if(len > actLen) {
      len = actLen;
    }
    str.extract(0,len,tmp);
    tmp[len]=0;

#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "BasicCalendarFactory::create() - cur %s, can %s\n", (const char*)curLoc.getName(), (const char*)canLoc.getName());
#endif

    if(!isStandardSupportedID(tmp,status)) {  // Do we handle this type?
#ifdef U_DEBUG_CALSVC
      
      fprintf(stderr, "BasicCalendarFactory - not handling %s.[%s]\n", (const char*) curLoc.getName(), tmp );
#endif
      return NULL;
    }

    return createStandardCalendar(tmp, canLoc, status);
  }
};


/** 
 * A factory which looks up the DefaultCalendar resource to determine which class of calendar to use
 */

class DefaultCalendarFactory : public ICUResourceBundleFactory {
 public:
  DefaultCalendarFactory():  ICUResourceBundleFactory() { } 
 protected:
  virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const  {
    
    LocaleKey &lkey = (LocaleKey&)key;
    Locale loc;
    lkey.currentLocale(loc);
    
    UnicodeString myString;
    
    // attempt keyword lookup
    char keyword[128];

    if(!loc.getKeywordValue("calendar", keyword, sizeof(keyword)-1, status)) {
      // fetch default calendar id
      char funcEquiv[ULOC_FULLNAME_CAPACITY];
      ures_getFunctionalEquivalent(funcEquiv, sizeof(funcEquiv)-1,
                                   NULL, "calendar", "calendar",
                                   loc.getName(), 
                                   NULL, FALSE, &status);
      uloc_getKeywordValue(funcEquiv, "calendar", keyword, 
                           sizeof(keyword)-1, &status);
#ifdef U_DEBUG_CALSVC
      fprintf(stderr, "  getFunctionalEquivalent calendar=%s [%s]\n", keyword, u_errorName(status));
#endif
    }
#ifdef U_DEBUG_CALSVC
    else { fprintf(stderr, "  explicit calendar=%s\n", keyword); }
#endif


    if(U_FAILURE(status)) {
      return NULL; 
    } else {
      UnicodeString *ret = new UnicodeString();
      ret->append((UChar)0x40); // '@' is a variant character
      ret->append(UNICODE_STRING("calendar=", 9));
      (*ret) += UnicodeString(keyword,-1,US_INV);
      return ret;
    }
  }
};

// -------------------------------------
class CalendarService : public ICULocaleService {
public:
  CalendarService()
    : ICULocaleService(UNICODE_STRING_SIMPLE("Calendar"))
  {
    UErrorCode status = U_ZERO_ERROR;
    registerFactory(new DefaultCalendarFactory(), status);
  }

  virtual UObject* cloneInstance(UObject* instance) const {
    if(instance->getDynamicClassID() == UnicodeString::getStaticClassID()) {
      return ((UnicodeString*)instance)->clone(); 
    } else {
#ifdef U_DEBUG_CALSVC_F
      UErrorCode status2 = U_ZERO_ERROR;
      fprintf(stderr, "Cloning a %s calendar with tz=%ld\n", ((Calendar*)instance)->getType(), ((Calendar*)instance)->get(UCAL_ZONE_OFFSET, status2));
#endif
      return ((Calendar*)instance)->clone();
    }
  }

  virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* /*actualID*/, UErrorCode& status) const {
	LocaleKey& lkey = (LocaleKey&)key;
	//int32_t kind = lkey.kind();

	Locale loc;
	lkey.canonicalLocale(loc);

#ifdef U_DEBUG_CALSVC
        Locale loc2;
        lkey.currentLocale(loc2);
    fprintf(stderr, "CalSvc:handleDefault for currentLoc %s, canloc %s\n", (const char*)loc.getName(),  (const char*)loc2.getName());
#endif
	Calendar *nc =  new GregorianCalendar(loc, status);

#ifdef U_DEBUG_CALSVC
        UErrorCode status2 = U_ZERO_ERROR;
        fprintf(stderr, "New default calendar has tz=%d\n", ((Calendar*)nc)->get(UCAL_ZONE_OFFSET, status2));
#endif
        return nc;
  }

  virtual UBool isDefault() const {
    return countFactories() == 1;
  }
};

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

static inline UBool
isCalendarServiceUsed() {
    Mutex mutex;
    return (UBool)(gService != NULL);
}

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

static ICULocaleService* 
getCalendarService(UErrorCode &status)
{
  UBool needInit;
  {
    Mutex mutex;
    needInit = (UBool)(gService == NULL);
  }
  if (needInit) {
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Spinning up Calendar Service\n");
#endif
    ICULocaleService * newservice = new CalendarService();
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Registering classes..\n");
#endif

    // Register all basic instances. 
    newservice->registerFactory(new BasicCalendarFactory(),status);

#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Done..\n");
#endif

    if(U_FAILURE(status)) {
#ifdef U_DEBUG_CALSVC
      fprintf(stderr, "err (%s) registering classes, deleting service.....\n", u_errorName(status));
#endif
      delete newservice;
      newservice = NULL;
    }
    
    if (newservice) {
      Mutex mutex;
      if (gService == NULL) {
        gService = newservice;
        newservice = NULL;
      }
    }
    if (newservice) {
      delete newservice;
    } else {
      // we won the contention - we can register the cleanup.
      ucln_i18n_registerCleanup(UCLN_I18N_CALENDAR, calendar_cleanup);
    }
  }
  return gService;
}

URegistryKey Calendar::registerFactory(ICUServiceFactory* toAdopt, UErrorCode& status)
{
  return getCalendarService(status)->registerFactory(toAdopt, status);
}

UBool Calendar::unregister(URegistryKey key, UErrorCode& status) {
  return getCalendarService(status)->unregister(key, status);
}
#endif /* UCONFIG_NO_SERVICE */

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

static const int32_t kCalendarLimits[UCAL_FIELD_COUNT][4] = {
    //    Minimum  Greatest min      Least max   Greatest max
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // ERA
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // YEAR
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // MONTH
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // WEEK_OF_YEAR
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // WEEK_OF_MONTH
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // DAY_OF_MONTH
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // DAY_OF_YEAR
    {           1,            1,             7,             7  }, // DAY_OF_WEEK
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // DAY_OF_WEEK_IN_MONTH
    {           0,            0,             1,             1  }, // AM_PM
    {           0,            0,            11,            11  }, // HOUR
    {           0,            0,            23,            23  }, // HOUR_OF_DAY
    {           0,            0,            59,            59  }, // MINUTE
    {           0,            0,            59,            59  }, // SECOND
    {           0,            0,           999,           999  }, // MILLISECOND
    {-12*kOneHour, -12*kOneHour,   12*kOneHour,   15*kOneHour  }, // ZONE_OFFSET
    {           0,            0,    1*kOneHour,    1*kOneHour  }, // DST_OFFSET
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // YEAR_WOY
    {           1,            1,             7,             7  }, // DOW_LOCAL
    {/*N/A*/-1,       /*N/A*/-1,     /*N/A*/-1,       /*N/A*/-1}, // EXTENDED_YEAR
    { -0x7F000000,  -0x7F000000,    0x7F000000,    0x7F000000  }, // JULIAN_DAY
    {           0,            0, 24*kOneHour-1, 24*kOneHour-1  } // MILLISECONDS_IN_DAY
};

// 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)
:   UObject(),
    fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fAreFieldsVirtuallySet(FALSE),
    fNextStamp((int32_t)kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    clear();
    fZone = TimeZone::createDefault();
    setWeekCountData(Locale::getDefault(), NULL, success);
}

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

Calendar::Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
:   UObject(),
    fIsTimeSet(FALSE),
    fAreFieldsSet(FALSE),
    fAreAllFieldsSet(FALSE),
    fAreFieldsVirtuallySet(FALSE),
    fNextStamp((int32_t)kMinimumUserStamp),
    fTime(0),
    fLenient(TRUE),
    fZone(0)
{
    if(zone == 0) {
#if defined (U_DEBUG_CAL)
      fprintf(stderr, "%s:%d: ILLEGAL ARG because timezone cannot be 0\n",
              __FILE__, __LINE__);
#endif
      success = U_ILLEGAL_ARGUMENT_ERROR;
      return;
    }

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

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

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

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

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

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

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

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

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

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

Calendar* U_EXPORT2
Calendar::createInstance(UErrorCode& success)
{
  return createInstance(TimeZone::createDefault(), Locale::getDefault(), success);
}

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

Calendar* U_EXPORT2
Calendar::createInstance(const TimeZone& zone, UErrorCode& success)
{
  return createInstance(zone, Locale::getDefault(), success);
}

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

Calendar* U_EXPORT2
Calendar::createInstance(const Locale& aLocale, UErrorCode& success)
{
  return createInstance(TimeZone::createDefault(), aLocale, success);
}

// ------------------------------------- Adopting 

// Note: this is the bottleneck that actually calls the service routines.

Calendar* U_EXPORT2
Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
{
    Locale actualLoc;
    UObject* u;
#if !UCONFIG_NO_SERVICE
    if (isCalendarServiceUsed()) {
        u = getCalendarService(success)->get(aLocale, LocaleKey::KIND_ANY, &actualLoc, success);
    }
    else
#endif
    {
        char calLocaleType[ULOC_FULLNAME_CAPACITY] = {"@calendar="};
        int32_t calLocaleTypeLen = uprv_strlen(calLocaleType);
        int32_t keywordCapacity = aLocale.getKeywordValue("calendar", calLocaleType+calLocaleTypeLen, sizeof(calLocaleType)-calLocaleTypeLen-1, success);
        if (keywordCapacity == 0) {
            char funcEquiv[ULOC_FULLNAME_CAPACITY];

            // fetch default calendar id
            ures_getFunctionalEquivalent(funcEquiv, sizeof(funcEquiv)-1,
                                        NULL, "calendar", "calendar",
                                        aLocale.getName(), 
                                        NULL, FALSE, &success);
            keywordCapacity = uloc_getKeywordValue(funcEquiv, "calendar", calLocaleType+calLocaleTypeLen, 
                                sizeof(calLocaleType)-calLocaleTypeLen-1, &success);
            if (keywordCapacity == 0 || U_FAILURE(success)) {
                // no calendar type.  Default to nothing.
                calLocaleType[0] = 0;
            }
#ifdef U_DEBUG_CALSVC
            fprintf(stderr, "  getFunctionalEquivalent calendar=%s [%s]\n", keyword, u_errorName(status));
#endif
        }
#ifdef U_DEBUG_CALSVC
        else { fprintf(stderr, "  explicit calendar=%s\n", keyword); }
#endif
        u = createStandardCalendar(calLocaleType, aLocale, success);
    }
    Calendar* c = NULL;

  if(U_FAILURE(success) || !u) {
    delete zone;
    if(U_SUCCESS(success)) { // Propagate some kind of err
      success = U_INTERNAL_PROGRAM_ERROR;
    }
    return NULL;
  }

#if !UCONFIG_NO_SERVICE
  if(u->getDynamicClassID() == UnicodeString::getStaticClassID()) {
    // It's a unicode string telling us what type of calendar to load ("gregorian", etc)
    char tmp[200];
    const UnicodeString& str = *(UnicodeString*)u;
    // Extract a char* out of it..
    int32_t len = str.length();
    int32_t actLen = sizeof(tmp)-1;
    if(len > actLen) {
      len = actLen;
    }
    str.extract(0,len,tmp);
    tmp[len]=0;
    
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "Calendar::createInstance(%s), fetched string %s..\n", (const char*)aLocale.getName(), tmp);
#endif

    // Create a Locale over this string
    Locale l = Locale::createFromName(tmp);

#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "looking up [%s].. should be %s\n",l.getName(), tmp);
#endif

    Locale actualLoc2;
    delete u;
    u = NULL;

    // Don't overwrite actualLoc, since the actual loc from this call
    // may be something like "@calendar=gregorian" -- TODO investigate
    // further...
    c = (Calendar*)getCalendarService(success)->get(l, LocaleKey::KIND_ANY, &actualLoc2, success);

    if(U_FAILURE(success) || !c) {
      delete zone;
      if(U_SUCCESS(success)) { 
        success = U_INTERNAL_PROGRAM_ERROR; // Propagate some err
      }
      return NULL;
    }
    
    if(c->getDynamicClassID() == UnicodeString::getStaticClassID()) {
      // recursed! Second lookup returned a UnicodeString. 
      // Perhaps DefaultCalendar{} was set to another locale.
#ifdef U_DEBUG_CALSVC
      char tmp[200];
      const UnicodeString& str = *(UnicodeString*)c;
      // Extract a char* out of it..
      int32_t len = str.length();
      int32_t actLen = sizeof(tmp)-1;
      if(len > actLen) {
        len = actLen;
      }
      str.extract(0,len,tmp);
      tmp[len]=0;

      fprintf(stderr, "err - recursed, 2nd lookup was unistring %s\n", tmp);
#endif
      success = U_MISSING_RESOURCE_ERROR;  // requested a calendar type which could NOT be found.
      delete c;
      delete zone;
      return NULL;
    }
#ifdef U_DEBUG_CALSVC
    fprintf(stderr, "%p: setting week count data to locale %s, actual locale %s\n", c, (const char*)aLocale.getName(), (const char *)actualLoc.getName());
#endif
    c->setWeekCountData(aLocale, c->getType(), success);  // set the correct locale (this was an indirected calendar)
  }
  else
#endif /* UCONFIG_NO_SERVICE */
  {
    // a calendar was returned - we assume the factory did the right thing.
    c = (Calendar*)u;
  }

  // Now, reset calendar to default state:
  c->adoptTimeZone(zone); //  Set the correct time zone
  c->setTimeInMillis(getNow(), success); // let the new calendar have the current time.
  
  return c;
}

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

Calendar* U_EXPORT2
Calendar::createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode& success)
{
  Calendar* c = createInstance(aLocale, success);
  if(U_SUCCESS(success) && c) {
    c->setTimeZone(zone);
  }
  return c; 
}

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

UBool
Calendar::operator==(const Calendar& that) const
{
    UErrorCode status = U_ZERO_ERROR;
    return isEquivalentTo(that) &&
        getTimeInMillis(status) == that.getTimeInMillis(status) &&
        U_SUCCESS(status);
}

UBool 
Calendar::isEquivalentTo(const Calendar& other) const
{
    return getDynamicClassID() == other.getDynamicClassID() &&
        fLenient                == other.fLenient &&
        fFirstDayOfWeek         == other.fFirstDayOfWeek &&
        fMinimalDaysInFirstWeek == other.fMinimalDaysInFirstWeek &&
        *fZone                  == *other.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));
}

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


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

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

UDate U_EXPORT2
Calendar::getNow()
{
    return uprv_getUTCtime(); // 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);

    /* Test for buffer overflows */
    if(U_FAILURE(status)) {
        return 0.0;
    }
    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;

    if (millis > MAX_MILLIS) {
        millis = MAX_MILLIS;
    } else if (millis < MIN_MILLIS) {
        millis = MIN_MILLIS;
    }

    fTime = millis;
    fAreFieldsSet = fAreAllFieldsSet = FALSE;
    fIsTimeSet = fAreFieldsVirtuallySet = TRUE;
}

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

int32_t
Calendar::get(UCalendarDateFields 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(UCalendarDateFields field, int32_t value)
{
    if (fAreFieldsVirtuallySet) {
        UErrorCode ec = U_ZERO_ERROR;
        computeFields(ec);
    }
    fFields[field]     = value;
    fStamp[field]     = fNextStamp++;
    fIsSet[field]     = TRUE; // Remove later
    fIsTimeSet = fAreFieldsSet = fAreFieldsVirtuallySet = FALSE;
}

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

void
Calendar::set(int32_t year, int32_t month, int32_t date)
{
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
}

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

void
Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute)
{
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
    set(UCAL_HOUR_OF_DAY, hour);
    set(UCAL_MINUTE, minute);
}

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

void
Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, int32_t second)
{
    set(UCAL_YEAR, year);
    set(UCAL_MONTH, month);
    set(UCAL_DATE, date);
    set(UCAL_HOUR_OF_DAY, hour);
    set(UCAL_MINUTE, minute);
    set(UCAL_SECOND, second);
}

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

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

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

void
Calendar::clear(UCalendarDateFields field)
{
    if (fAreFieldsVirtuallySet) {
        UErrorCode ec = U_ZERO_ERROR;
        computeFields(ec);
    }
    fFields[field]         = 0;
    fStamp[field]         = kUnset;
    fIsSet[field]         = FALSE; // Remove later
    fIsTimeSet = fAreFieldsSet = fAreAllFieldsSet = fAreFieldsVirtuallySet = FALSE;
}

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

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


int32_t Calendar::newestStamp(UCalendarDateFields first, UCalendarDateFields last, int32_t bestStampSoFar) const
{
  int32_t bestStamp = bestStampSoFar;
  for (int32_t i=(int32_t)first; i<=(int32_t)last; ++i) {
    if (fStamp[i] > bestStamp) {
      bestStamp = fStamp[i];
    }
  }
  return bestStamp;
}


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

void
Calendar::complete(UErrorCode& status)
{
    if (!fIsTimeSet) {
        updateTime(status);
        /* Test for buffer overflows */
        if(U_FAILURE(status)) {
            return;
        }
    }
    if (!fAreFieldsSet) {
        computeFields(status); // fills in unset fields
        /* Test for buffer overflows */
        if(U_FAILURE(status)) {
            return;
        }
        fAreFieldsSet         = TRUE;
        fAreAllFieldsSet     = TRUE;
    }
}

    //-------------------------------------------------------------------------
    // Protected utility methods for use by subclasses.  These are very handy
    // for implementing add, roll, and computeFields.
    //-------------------------------------------------------------------------

    /**
     * Adjust the specified field so that it is within
     * the allowable range for the date to which this calendar is set.
     * For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH}
     * field for a calendar set to April 31 would cause it to be set
     * to April 30.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This utility method is intended for use by subclasses that need to implement
     * their own overrides of {@link #roll roll} and {@link #add add}.
     * <p>
     * <b>Note:</b>
     * <code>pinField</code> is implemented in terms of
     * {@link #getActualMinimum getActualMinimum}
     * and {@link #getActualMaximum getActualMaximum}.  If either of those methods uses
     * a slow, iterative algorithm for a particular field, it would be
     * unwise to attempt to call <code>pinField</code> for that field.  If you
     * really do need to do so, you should override this method to do
     * something more efficient for that field.
     * <p>
     * @param field The calendar field whose value should be pinned.
     *
     * @see #getActualMinimum
     * @see #getActualMaximum
     * @stable ICU 2.0
     */
void Calendar::pinField(UCalendarDateFields field, UErrorCode& status) {
  int32_t max = getActualMaximum(field, status);
  int32_t min = getActualMinimum(field, status);
  
  if (fFields[field] > max) {
    set(field, max);
  } else if (fFields[field] < min) {
    set(field, min);
  }
}


void Calendar::computeFields(UErrorCode &ec)
{
  if (U_FAILURE(ec)) {
    return;
  }
  // Compute local wall millis
  double localMillis = internalGetTime();
  int32_t rawOffset, dstOffset;
  getTimeZone().getOffset(localMillis, FALSE, rawOffset, dstOffset, ec);
  localMillis += rawOffset; 
  
  // Mark fields as set.  Do this before calling handleComputeFields().
  uint32_t mask =   //fInternalSetMask;
    (1 << ERA) |
    (1 << UCAL_YEAR) |
    (1 << UCAL_MONTH) |
    (1 << UCAL_DAY_OF_MONTH) | // = UCAL_DATE
    (1 << UCAL_DAY_OF_YEAR) |
    (1 << UCAL_EXTENDED_YEAR);  

  for (int32_t i=0; i<UCAL_FIELD_COUNT; ++i) {
    if ((mask & 1) == 0) {
      fStamp[i] = kInternallySet;
      fIsSet[i] = TRUE; // Remove later
    } else {
      fStamp[i] = kUnset;
      fIsSet[i] = FALSE; // Remove later
    }
    mask >>= 1;
  }
  
  // We used to check for and correct extreme millis values (near
  // Long.MIN_VALUE or Long.MAX_VALUE) here.  Such values would cause
  // overflows from positive to negative (or vice versa) and had to
  // be manually tweaked.  We no longer need to do this because we
  // have limited the range of supported dates to those that have a
  // Julian day that fits into an int.  This allows us to implement a
  // JULIAN_DAY field and also removes some inelegant code. - Liu
  // 11/6/00
  
  int32_t days =  (int32_t)Math::floorDivide(localMillis, (double)kOneDay);

  internalSet(UCAL_JULIAN_DAY,days + kEpochStartAsJulianDay);

#if defined (U_DEBUG_CAL)
  //fprintf(stderr, "%s:%d- Hmm! Jules @ %d, as per %.0lf millis\n",
  //__FILE__, __LINE__, fFields[UCAL_JULIAN_DAY], localMillis);
#endif  

  // In some cases we will have to call this method again below to
  // adjust for DST pushing us into the next Julian day.
  computeGregorianAndDOWFields(fFields[UCAL_JULIAN_DAY], ec);
  
  int32_t millisInDay =  (int32_t) (localMillis - (days * kOneDay));
  if (millisInDay < 0) millisInDay += (int32_t)kOneDay;
    
  // Adjust our millisInDay for DST.  dstOffset will be zero if DST
  // is not in effect at this time of year, or if our zone does not
  // use DST.
  millisInDay += dstOffset;
  
  // If DST has pushed us into the next day, we must call
  // computeGregorianAndDOWFields() again.  This happens in DST between
  // 12:00 am and 1:00 am every day.  The first call to
  // computeGregorianAndDOWFields() will give the wrong day, since the
  // Standard time is in the previous day.
  if (millisInDay >= (int32_t)kOneDay) {
    millisInDay -= (int32_t)kOneDay; // ASSUME dstOffset < 24:00
    
    // We don't worry about overflow of JULIAN_DAY because the
    // allowable range of JULIAN_DAY has slop at the ends (that is,
    // the max is less that 0x7FFFFFFF and the min is greater than
    // -0x80000000).
    computeGregorianAndDOWFields(++fFields[UCAL_JULIAN_DAY], ec);
  }
  
  // Call framework method to have subclass compute its fields.
  // These must include, at a minimum, MONTH, DAY_OF_MONTH,
  // EXTENDED_YEAR, YEAR, DAY_OF_YEAR.  This method will call internalSet(),
  // which will update stamp[].
  handleComputeFields(fFields[UCAL_JULIAN_DAY], ec);
  
  // Compute week-related fields, based on the subclass-computed
  // fields computed by handleComputeFields().
  computeWeekFields(ec);
  
  // Compute time-related fields.  These are indepent of the date and
  // of the subclass algorithm.  They depend only on the local zone
  // wall milliseconds in day.
  fFields[UCAL_MILLISECONDS_IN_DAY] = millisInDay;
  fFields[UCAL_MILLISECOND] = millisInDay % 1000;
  millisInDay /= 1000;
  fFields[UCAL_SECOND] = millisInDay % 60;
  millisInDay /= 60;
  fFields[UCAL_MINUTE] = millisInDay % 60;
  millisInDay /= 60;
  fFields[UCAL_HOUR_OF_DAY] = millisInDay;
  fFields[UCAL_AM_PM] = millisInDay / 12; // Assume AM == 0
  fFields[UCAL_HOUR] = millisInDay % 12;
  fFields[UCAL_ZONE_OFFSET] = rawOffset;
  fFields[UCAL_DST_OFFSET] = dstOffset;
}

uint8_t Calendar::julianDayToDayOfWeek(double julian)
{
  // If julian is negative, then julian%7 will be negative, so we adjust
  // accordingly.  We add 1 because Julian day 0 is Monday.
  int8_t dayOfWeek = (int8_t) uprv_fmod(julian + 1, 7);

  uint8_t result = (uint8_t)(dayOfWeek + ((dayOfWeek < 0) ? (7+UCAL_SUNDAY ) : UCAL_SUNDAY));
  return result;
}

/**
 * Compute the Gregorian calendar year, month, and day of month from
 * the given Julian day.  These values are not stored in fields, but in
 * member variables gregorianXxx.  Also compute the DAY_OF_WEEK and
 * DOW_LOCAL fields.
 */
void Calendar::computeGregorianAndDOWFields(int32_t julianDay, UErrorCode &ec)
{
  computeGregorianFields(julianDay, ec);
  
  // Compute day of week: JD 0 = Monday
  int32_t dow = julianDayToDayOfWeek(julianDay);
  internalSet(UCAL_DAY_OF_WEEK,dow);

  // Calculate 1-based localized day of week
  int32_t dowLocal = dow - getFirstDayOfWeek() + 1;
  if (dowLocal < 1) {
    dowLocal += 7;
  }
  internalSet(UCAL_DOW_LOCAL,dowLocal);
  fFields[UCAL_DOW_LOCAL] = dowLocal;
}

/**
 * Compute the Gregorian calendar year, month, and day of month from the
 * Julian day.  These values are not stored in fields, but in member
 * variables gregorianXxx.  They are used for time zone computations and by
 * subclasses that are Gregorian derivatives.  Subclasses may call this
 * method to perform a Gregorian calendar millis->fields computation.
 * To perform a Gregorian calendar fields->millis computation, call
 * computeGregorianMonthStart().
 * @see #computeGregorianMonthStart
 */
void Calendar::computeGregorianFields(int32_t julianDay, UErrorCode & /* ec */) {
  int32_t gregorianDayOfWeekUnused;
  Grego::dayToFields(julianDay - kEpochStartAsJulianDay, fGregorianYear, fGregorianMonth, fGregorianDayOfMonth, gregorianDayOfWeekUnused, fGregorianDayOfYear);
}

/**
 * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH,
 * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR,
 * DAY_OF_WEEK, and DAY_OF_YEAR.  The latter fields are computed by the
 * subclass based on the calendar system.
 *
 * <p>The YEAR_WOY field is computed simplistically.  It is equal to YEAR
 * most of the time, but at the year boundary it may be adjusted to YEAR-1
 * or YEAR+1 to reflect the overlap of a week into an adjacent year.  In
 * this case, a simple increment or decrement is performed on YEAR, even
 * though this may yield an invalid YEAR value.  For instance, if the YEAR
 * is part of a calendar system with an N-year cycle field CYCLE, then
 * incrementing the YEAR may involve incrementing CYCLE and setting YEAR
 * back to 0 or 1.  This is not handled by this code, and in fact cannot be
 * simply handled without having subclasses define an entire parallel set of
 * fields for fields larger than or equal to a year.  This additional
 * complexity is not warranted, since the intention of the YEAR_WOY field is
 * to support ISO 8601 notation, so it will typically be used with a
 * proleptic Gregorian calendar, which has no field larger than a year.
 */
void Calendar::computeWeekFields(UErrorCode &ec) {
  if(U_FAILURE(ec)) { 
    return;
  }
  int32_t eyear = fFields[UCAL_EXTENDED_YEAR];
  int32_t year = fFields[UCAL_YEAR];
  int32_t dayOfWeek = fFields[UCAL_DAY_OF_WEEK];
  int32_t dayOfYear = fFields[UCAL_DAY_OF_YEAR];
  
  // WEEK_OF_YEAR start
  // Compute the week of the year.  For the Gregorian calendar, valid week
  // numbers run from 1 to 52 or 53, depending on the year, the first day
  // of the week, and the minimal days in the first week.  For other
  // calendars, the valid range may be different -- it depends on the year
  // length.  Days at the start of the year may fall into the last week of
  // the previous year; days at the end of the year may fall into the
  // first week of the next year.  ASSUME that the year length is less than
  // 7000 days.
  int32_t yearOfWeekOfYear = year;
  int32_t relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
  int32_t relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6
  int32_t woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
  if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
    ++woy;
  }
  
  // Adjust for weeks at the year end that overlap into the previous or
  // next calendar year.
  if (woy == 0) {
    // We are the last week of the previous year.
    // Check to see if we are in the last week; if so, we need
    // to handle the case in which we are the first week of the
    // next year.
    
    int32_t prevDoy = dayOfYear + handleGetYearLength(eyear - 1);
    woy = weekNumber(prevDoy, dayOfWeek);
    yearOfWeekOfYear--;
  } else {
    int32_t lastDoy = handleGetYearLength(eyear);
    // Fast check: For it to be week 1 of the next year, the DOY
    // must be on or after L-5, where L is yearLength(), then it
    // cannot possibly be week 1 of the next year:
    //          L-5                  L
    // doy: 359 360 361 362 363 364 365 001
    // dow:      1   2   3   4   5   6   7
    if (dayOfYear >= (lastDoy - 5)) {
      int32_t lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
      if (lastRelDow < 0) {
        lastRelDow += 7;
      }
      if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) &&
          ((dayOfYear + 7 - relDow) > lastDoy)) {
        woy = 1;
        yearOfWeekOfYear++;
      }
    }
  }
  fFields[UCAL_WEEK_OF_YEAR] = woy;
  fFields[UCAL_YEAR_WOY] = yearOfWeekOfYear;
  // WEEK_OF_YEAR end
  
  int32_t dayOfMonth = fFields[UCAL_DAY_OF_MONTH];
  fFields[UCAL_WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek);
  fFields[UCAL_DAY_OF_WEEK_IN_MONTH] = (dayOfMonth-1) / 7 + 1;
#if defined (U_DEBUG_CAL)
  if(fFields[UCAL_DAY_OF_WEEK_IN_MONTH]==0) fprintf(stderr, "%s:%d: DOWIM %d on %g\n", 
                  __FILE__, __LINE__,fFields[UCAL_DAY_OF_WEEK_IN_MONTH], fTime);
#endif
}


int32_t Calendar::weekNumber(int32_t desiredDay, int32_t dayOfPeriod, int32_t dayOfWeek)
{
  // Determine the day of the week of the first day of the period
  // in question (either a year or a month).  Zero represents the
  // first day of the week on this calendar.
  int32_t periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
  if (periodStartDayOfWeek < 0) periodStartDayOfWeek += 7;
  
  // Compute the week number.  Initially, ignore the first week, which
  // may be fractional (or may not be).  We add periodStartDayOfWeek in
  // order to fill out the first week, if it is fractional.
  int32_t weekNo = (desiredDay + periodStartDayOfWeek - 1)/7;
  
  // If the first week is long enough, then count it.  If
  // the minimal days in the first week is one, or if the period start
  // is zero, we always increment weekNo.
  if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) ++weekNo;
  
  return weekNo;
}

void Calendar::handleComputeFields(int32_t /* julianDay */, UErrorCode &/* status */)
{
  internalSet(UCAL_MONTH, getGregorianMonth());
  internalSet(UCAL_DAY_OF_MONTH, getGregorianDayOfMonth());
  internalSet(UCAL_DAY_OF_YEAR, getGregorianDayOfYear());
  int32_t eyear = getGregorianYear();
  internalSet(UCAL_EXTENDED_YEAR, eyear);
  int32_t era = GregorianCalendar::AD;
  if (eyear < 1) {
    era = GregorianCalendar::BC;
    eyear = 1 - eyear;
  }
  internalSet(UCAL_ERA, era);
  internalSet(UCAL_YEAR, eyear);
}
// -------------------------------------


void Calendar::roll(EDateFields field, int32_t amount, UErrorCode& status) 
{
  roll((UCalendarDateFields)field, amount, status);
}

void Calendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& status)
{
  if (amount == 0) {
    return; // Nothing to do
  }

  complete(status);

  if(U_FAILURE(status)) {
    return;
  }
  switch (field) {
  case UCAL_DAY_OF_MONTH:
  case UCAL_AM_PM:
  case UCAL_MINUTE:
  case UCAL_SECOND:
  case UCAL_MILLISECOND:
  case UCAL_MILLISECONDS_IN_DAY:
  case UCAL_ERA:
    // These are the standard roll instructions.  These work for all
    // simple cases, that is, cases in which the limits are fixed, such
    // as the hour, the day of the month, and the era.
    {
      int32_t min = getActualMinimum(field,status);
      int32_t max = getActualMaximum(field,status);
      int32_t gap = max - min + 1;

      int32_t value = internalGet(field) + amount;
      value = (value - min) % gap;
      if (value < 0) {
        value += gap;
      }
      value += min;

      set(field, value);
      return;
    }

  case UCAL_HOUR:
  case UCAL_HOUR_OF_DAY:
    // Rolling the hour is difficult on the ONSET and CEASE days of
    // daylight savings.  For example, if the change occurs at
    // 2 AM, we have the following progression:
    // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst
    // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std
    // To get around this problem we don't use fields; we manipulate
    // the time in millis directly.
    {
      // Assume min == 0 in calculations below
      double start = getTimeInMillis(status);
      int32_t oldHour = internalGet(field);
      int32_t max = getMaximum(field);
      int32_t newHour = (oldHour + amount) % (max + 1);
      if (newHour < 0) {
        newHour += max + 1;
      }
      setTimeInMillis(start + kOneHour * (newHour - oldHour),status);
      return;
    }

  case UCAL_MONTH:
    // Rolling the month involves both pinning the final value
    // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the
    // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
    // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
    {
      int32_t max = getActualMaximum(UCAL_MONTH, status);
      int32_t mon = (internalGet(UCAL_MONTH) + amount) % (max+1);

      if (mon < 0) {
        mon += (max + 1);
      }
      set(UCAL_MONTH, mon);

      // Keep the day of month in range.  We don't want to spill over
      // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->
      // mar3.
      pinField(UCAL_DAY_OF_MONTH,status);
      return;
    }

  case UCAL_YEAR:
  case UCAL_YEAR_WOY:
  case UCAL_EXTENDED_YEAR:
    // Rolling the year can involve pinning the DAY_OF_MONTH.
    set(field, internalGet(field) + amount);
    pinField(UCAL_MONTH,status);
    pinField(UCAL_DAY_OF_MONTH,status);
    return;

  case UCAL_WEEK_OF_MONTH:
    {
      // This is tricky, because during the roll we may have to shift
      // to a different day of the week.  For example:

      //    s  m  t  w  r  f  s
      //          1  2  3  4  5
      //    6  7  8  9 10 11 12

      // When rolling from the 6th or 7th back one week, we go to the
      // 1st (assuming that the first partial week counts).  The same
      // thing happens at the end of the month.

      // The other tricky thing is that we have to figure out whether
      // the first partial week actually counts or not, based on the
      // minimal first days in the week.  And we have to use the
      // correct first day of the week to delineate the week
      // boundaries.

      // Here's our algorithm.  First, we find the real boundaries of
      // the month.  Then we discard the first partial week if it
      // doesn't count in this locale.  Then we fill in the ends with
      // phantom days, so that the first partial week and the last
      // partial week are full weeks.  We then have a nice square
      // block of weeks.  We do the usual rolling within this block,
      // as is done elsewhere in this method.  If we wind up on one of
      // the phantom days that we added, we recognize this and pin to
      // the first or the last day of the month.  Easy, eh?

      // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
      // in this locale.  We have dow in 0..6.
      int32_t dow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek();
      if (dow < 0) dow += 7;

      // Find the day of the week (normalized for locale) for the first
      // of the month.
      int32_t fdm = (dow - internalGet(UCAL_DAY_OF_MONTH) + 1) % 7;
      if (fdm < 0) fdm += 7;

      // Get the first day of the first full week of the month,
      // including phantom days, if any.  Figure out if the first week
      // counts or not; if it counts, then fill in phantom days.  If
      // not, advance to the first real full week (skip the partial week).
      int32_t start;
      if ((7 - fdm) < getMinimalDaysInFirstWeek())
        start = 8 - fdm; // Skip the first partial week
      else
        start = 1 - fdm; // This may be zero or negative

      // Get the day of the week (normalized for locale) for the last
      // day of the month.
      int32_t monthLen = getActualMaximum(UCAL_DAY_OF_MONTH, status);
      int32_t ldm = (monthLen - internalGet(UCAL_DAY_OF_MONTH) + dow) % 7;
      // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.

      // Get the limit day for the blocked-off rectangular month; that
      // is, the day which is one past the last day of the month,
      // after the month has already been filled in with phantom days
      // to fill out the last week.  This day has a normalized DOW of 0.
      int32_t limit = monthLen + 7 - ldm;

      // Now roll between start and (limit - 1).
      int32_t gap = limit - start;
      int32_t day_of_month = (internalGet(UCAL_DAY_OF_MONTH) + amount*7 -
                          start) % gap;
      if (day_of_month < 0) day_of_month += gap;
      day_of_month += start;

      // Finally, pin to the real start and end of the month.
      if (day_of_month < 1) day_of_month = 1;
      if (day_of_month > monthLen) day_of_month = monthLen;

      // Set the DAY_OF_MONTH.  We rely on the fact that this field
      // takes precedence over everything else (since all other fields
      // are also set at this point).  If this fact changes (if the
      // disambiguation algorithm changes) then we will have to unset
      // the appropriate fields here so that DAY_OF_MONTH is attended
      // to.
      set(UCAL_DAY_OF_MONTH, day_of_month);
      return;
    }
  case UCAL_WEEK_OF_YEAR:
    {
      // This follows the outline of WEEK_OF_MONTH, except it applies
      // to the whole year.  Please see the comment for WEEK_OF_MONTH
      // for general notes.

      // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
      // in this locale.  We have dow in 0..6.
      int32_t dow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek();
      if (dow < 0) dow += 7;

      // Find the day of the week (normalized for locale) for the first
      // of the year.
      int32_t fdy = (dow - internalGet(UCAL_DAY_OF_YEAR) + 1) % 7;
      if (fdy < 0) fdy += 7;

      // Get the first day of the first full week of the year,
      // including phantom days, if any.  Figure out if the first week
      // counts or not; if it counts, then fill in phantom days.  If
      // not, advance to the first real full week (skip the partial week).
      int32_t start;
      if ((7 - fdy) < getMinimalDaysInFirstWeek())
        start = 8 - fdy; // Skip the first partial week
      else
        start = 1 - fdy; // This may be zero or negative

      // Get the day of the week (normalized for locale) for the last
      // day of the year.
      int32_t yearLen = getActualMaximum(UCAL_DAY_OF_YEAR,status);
      int32_t ldy = (yearLen - internalGet(UCAL_DAY_OF_YEAR) + dow) % 7;
      // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here.

      // Get the limit day for the blocked-off rectangular year; that
      // is, the day which is one past the last day of the year,
      // after the year has already been filled in with phantom days
      // to fill out the last week.  This day has a normalized DOW of 0.
      int32_t limit = yearLen + 7 - ldy;

      // Now roll between start and (limit - 1).
      int32_t gap = limit - start;
      int32_t day_of_year = (internalGet(UCAL_DAY_OF_YEAR) + amount*7 -
                         start) % gap;
      if (day_of_year < 0) day_of_year += gap;
      day_of_year += start;

      // Finally, pin to the real start and end of the month.
      if (day_of_year < 1) day_of_year = 1;
      if (day_of_year > yearLen) day_of_year = yearLen;

      // Make sure that the year and day of year are attended to by
      // clearing other fields which would normally take precedence.
      // If the disambiguation algorithm is changed, this section will
      // have to be updated as well.
      set(UCAL_DAY_OF_YEAR, day_of_year);
      clear(UCAL_MONTH);
      return;
    }
  case UCAL_DAY_OF_YEAR:
    {
      // Roll the day of year using millis.  Compute the millis for
      // the start of the year, and get the length of the year.
      double delta = amount * kOneDay; // Scale up from days to millis
      double min2 = internalGet(UCAL_DAY_OF_YEAR)-1;
      min2 *= kOneDay;
      min2 = internalGetTime() - min2;

      //      double min2 = internalGetTime() - (internalGet(UCAL_DAY_OF_YEAR) - 1.0) * kOneDay;
      double newtime;

      double yearLength = getActualMaximum(UCAL_DAY_OF_YEAR,status);
      double oneYear = yearLength;
      oneYear *= kOneDay;
      newtime = uprv_fmod((internalGetTime() + delta - min2), oneYear);
      if (newtime < 0) newtime += oneYear;
      setTimeInMillis(newtime + min2, status);
      return;
    }
  case UCAL_DAY_OF_WEEK:
  case UCAL_DOW_LOCAL:
    {
      // Roll the day of week using millis.  Compute the millis for
      // the start of the week, using the first day of week setting.
      // Restrict the millis to [start, start+7days).
      double delta = amount * kOneDay; // Scale up from days to millis
      // Compute the number of days before the current day in this
      // week.  This will be a value 0..6.
      int32_t leadDays = internalGet(field);
      leadDays -= (field == UCAL_DAY_OF_WEEK) ? getFirstDayOfWeek() : 1;
      if (leadDays < 0) leadDays += 7;
      double min2 = internalGetTime() - leadDays * kOneDay;
      double newtime = uprv_fmod((internalGetTime() + delta - min2), kOneWeek);
      if (newtime < 0) newtime += kOneWeek;
      setTimeInMillis(newtime + min2, status);
      return;
    }
  case UCAL_DAY_OF_WEEK_IN_MONTH:
    {
      // Roll the day of week in the month using millis.  Determine
      // the first day of the week in the month, and then the last,
      // and then roll within that range.
      double delta = amount * kOneWeek; // Scale up from weeks to millis
      // Find the number of same days of the week before this one
      // in this month.
      int32_t preWeeks = (internalGet(UCAL_DAY_OF_MONTH) - 1) / 7;
      // Find the number of same days of the week after this one
      // in this month.
      int32_t postWeeks = (getActualMaximum(UCAL_DAY_OF_MONTH,status) -
                       internalGet(UCAL_DAY_OF_MONTH)) / 7;
      // From these compute the min and gap millis for rolling.
      double min2 = internalGetTime() - preWeeks * kOneWeek;
      double gap2 = kOneWeek * (preWeeks + postWeeks + 1); // Must add 1!
      // Roll within this range
      double newtime = uprv_fmod((internalGetTime() + delta - min2), gap2);
      if (newtime < 0) newtime += gap2;
      setTimeInMillis(newtime + min2, status);
      return;
    }
  case UCAL_JULIAN_DAY:
    set(field, internalGet(field) + amount);
    return;
  default:
    // Other fields cannot be rolled by this method
#if defined (U_DEBUG_CAL)
          fprintf(stderr, "%s:%d: ILLEGAL ARG because of roll on non-rollable field %s\n", 
                  __FILE__, __LINE__,fldName(field));
#endif
    status = U_ILLEGAL_ARGUMENT_ERROR;
  }
}

void Calendar::add(EDateFields field, int32_t amount, UErrorCode& status)
{
  Calendar::add((UCalendarDateFields)field, amount, status);
}

// -------------------------------------
void Calendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status)
{
  if (amount == 0) {
    return;   // Do nothing!
  }

  // We handle most fields in the same way.  The algorithm is to add
  // a computed amount of millis to the current millis.  The only
  // wrinkle is with DST -- for some fields, like the DAY_OF_MONTH,
  // we don't want the HOUR to shift due to changes in DST.  If the
  // result of the add operation is to move from DST to Standard, or
  // vice versa, we need to adjust by an hour forward or back,
  // respectively.  For such fields we set keepHourInvariant to TRUE.

  // We only adjust the DST for fields larger than an hour.  For
  // fields smaller than an hour, we cannot adjust for DST without
  // causing problems.  for instance, if you add one hour to April 5,
  // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an
  // illegal value), but then the adjustment sees the change and
  // compensates by subtracting an hour.  As a result the time
  // doesn't advance at all.

  // For some fields larger than a day, such as a UCAL_MONTH, we pin the
  // UCAL_DAY_OF_MONTH.  This allows <March 31>.add(UCAL_MONTH, 1) to be
  // <April 30>, rather than <April 31> => <May 1>.

  double delta = amount; // delta in ms
  UBool keepHourInvariant = TRUE;

  switch (field) {
  case UCAL_ERA:
    set(field, get(field, status) + amount);
    pinField(UCAL_ERA, status);
    return;

  case UCAL_YEAR:
  case UCAL_EXTENDED_YEAR:
  case UCAL_YEAR_WOY:
  case UCAL_MONTH:
    set(field, get(field, status) + amount);
    pinField(UCAL_DAY_OF_MONTH, status);
    return;

  case UCAL_WEEK_OF_YEAR:
  case UCAL_WEEK_OF_MONTH:
  case UCAL_DAY_OF_WEEK_IN_MONTH:
    delta *= kOneWeek;
    break;

  case UCAL_AM_PM:
    delta *= 12 * kOneHour;
    break;

  case UCAL_DAY_OF_MONTH:
  case UCAL_DAY_OF_YEAR:
  case UCAL_DAY_OF_WEEK:
  case UCAL_DOW_LOCAL:
  case UCAL_JULIAN_DAY:
    delta *= kOneDay;
    break;

  case UCAL_HOUR_OF_DAY:
  case UCAL_HOUR:
    delta *= kOneHour;
    keepHourInvariant = FALSE;
    break;

  case UCAL_MINUTE:
    delta *= kOneMinute;
    keepHourInvariant = FALSE;
    break;

  case UCAL_SECOND:
    delta *= kOneSecond;
    keepHourInvariant = FALSE;
    break;

  case UCAL_MILLISECOND:
  case UCAL_MILLISECONDS_IN_DAY:
    keepHourInvariant = FALSE;
    break;

  default:
#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s not addable",
            __FILE__, __LINE__, fldName(field));
#endif
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return;
  //  throw new IllegalArgumentException("Calendar.add(" + fieldName(field) +
  //                                     ") not supported");
  }

  // In order to keep the hour invariant (for fields where this is
  // appropriate), record the DST_OFFSET before and after the add()
  // operation.  If it has changed, then adjust the millis to
  // compensate.
  int32_t dst = 0;
  int32_t hour = 0;
  if (keepHourInvariant) {
    dst = get(UCAL_DST_OFFSET, status);
    hour = internalGet(UCAL_HOUR_OF_DAY);
  }

  setTimeInMillis(getTimeInMillis(status) + delta, status);

  if (keepHourInvariant) {
    dst -= get(UCAL_DST_OFFSET, status);
    if (dst != 0) {
      // We have done an hour-invariant adjustment but the
      // DST offset has altered.  We adjust millis to keep
      // the hour constant.  In cases such as midnight after
      // a DST change which occurs at midnight, there is the
      // danger of adjusting into a different day.  To avoid
      // this we make the adjustment only if it actually
      // maintains the hour.
      double t = internalGetTime();
      setTimeInMillis(t + dst, status);
      if (get(UCAL_HOUR_OF_DAY, status) != hour) {
        setTimeInMillis(t, status);
      }
    }
  } 
}

// -------------------------------------
int32_t Calendar::fieldDifference(UDate when, EDateFields field, UErrorCode& status) {
  return fieldDifference(when, (UCalendarDateFields) field, status);
}

int32_t Calendar::fieldDifference(UDate targetMs, UCalendarDateFields field, UErrorCode& ec) {
    if (U_FAILURE(ec)) return 0;
    int32_t min = 0;
    double startMs = getTimeInMillis(ec);
    // Always add from the start millis.  This accomodates
    // operations like adding years from February 29, 2000 up to
    // February 29, 2004.  If 1, 1, 1, 1 is added to the year
    // field, the DOM gets pinned to 28 and stays there, giving an
    // incorrect DOM difference of 1.  We have to add 1, reset, 2,
    // reset, 3, reset, 4.
    if (startMs < targetMs) {
        int32_t max = 1;
        // Find a value that is too large
        while (U_SUCCESS(ec)) {
            setTimeInMillis(startMs, ec);
            add(field, max, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return max;
            } else if (ms > targetMs) {
                break;
            } else {
                max <<= 1;
                if (max < 0) {
                    // Field difference too large to fit into int32_t
#if defined (U_DEBUG_CAL)
                  fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s's max too large for int32_t\n",
                          __FILE__, __LINE__, fldName(field));
#endif
                    ec = U_ILLEGAL_ARGUMENT_ERROR;
                }
            }
        }
        // Do a binary search
        while ((max - min) > 1 && U_SUCCESS(ec)) {
            int32_t t = (min + max) / 2;
            setTimeInMillis(startMs, ec);
            add(field, t, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return t;
            } else if (ms > targetMs) {
                max = t;
            } else {
                min = t;
            }
        }
    } else if (startMs > targetMs) {
        int32_t max = -1;
        // Find a value that is too small
        while (U_SUCCESS(ec)) {
            setTimeInMillis(startMs, ec);
            add(field, max, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return max;
            } else if (ms < targetMs) {
                break;
            } else {
                max <<= 1;
                if (max == 0) {
                    // Field difference too large to fit into int32_t
#if defined (U_DEBUG_CAL)
                  fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s's max too large for int32_t\n",
                          __FILE__, __LINE__, fldName(field));
#endif
                    ec = U_ILLEGAL_ARGUMENT_ERROR;
                }
            }
        }
        // Do a binary search
        while ((min - max) > 1 && U_SUCCESS(ec)) {
            int32_t t = (min + max) / 2;
            setTimeInMillis(startMs, ec);
            add(field, t, ec);
            double ms = getTimeInMillis(ec);
            if (ms == targetMs) {
                return t;
            } else if (ms < targetMs) {
                max = t;
            } else {
                min = t;
            }
        }
    }
    // Set calendar to end point
    setTimeInMillis(startMs, ec);
    add(field, min, ec);
    
    /* Test for buffer overflows */
    if(U_FAILURE(ec)) {
        return 0;
    }
    return min;
}

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

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(UCalendarDaysOfWeek value)
{
  if (fFirstDayOfWeek != value &&
        value >= UCAL_SUNDAY && value <= UCAL_SATURDAY) {
        fFirstDayOfWeek = value;
        fAreFieldsSet = FALSE;
    }
}

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

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

UCalendarDaysOfWeek
Calendar::getFirstDayOfWeek(UErrorCode & /*status*/) const
{
    return fFirstDayOfWeek;
}
// -------------------------------------

void
Calendar::setMinimalDaysInFirstWeek(uint8_t value)
{
    // Values less than 1 have the same effect as 1; values greater
    // than 7 have the same effect as 7. However, we normalize values
    // so operator== and so forth work.
    if (value < 1) {
        value = 1;
    } else if (value > 7) {
        value = 7;
    }
    if (fMinimalDaysInFirstWeek != value) {
        fMinimalDaysInFirstWeek = value;
        fAreFieldsSet = FALSE;
    }
}

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

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

// ------------------------------------- limits

int32_t 
Calendar::getMinimum(EDateFields field) const {
    return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MINIMUM);
}

int32_t
Calendar::getMinimum(UCalendarDateFields field) const
{
    return getLimit(field,UCAL_LIMIT_MINIMUM);
}

// -------------------------------------
int32_t
Calendar::getMaximum(EDateFields field) const
{
    return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MAXIMUM);
}

int32_t
Calendar::getMaximum(UCalendarDateFields field) const
{
    return getLimit(field,UCAL_LIMIT_MAXIMUM);
}

// -------------------------------------
int32_t
Calendar::getGreatestMinimum(EDateFields field) const
{
    return getLimit((UCalendarDateFields)field,UCAL_LIMIT_GREATEST_MINIMUM);
}

int32_t
Calendar::getGreatestMinimum(UCalendarDateFields field) const
{
    return getLimit(field,UCAL_LIMIT_GREATEST_MINIMUM);
}

// -------------------------------------
int32_t
Calendar::getLeastMaximum(EDateFields field) const
{
    return getLimit((UCalendarDateFields) field,UCAL_LIMIT_LEAST_MAXIMUM);
}

int32_t
Calendar::getLeastMaximum(UCalendarDateFields field) const
{
    return getLimit( field,UCAL_LIMIT_LEAST_MAXIMUM);
}

// -------------------------------------
int32_t 
Calendar::getActualMinimum(EDateFields field, UErrorCode& status) const
{
    return getActualMinimum((UCalendarDateFields) field, status);
}

int32_t Calendar::getLimit(UCalendarDateFields field, ELimitType limitType) const {
    switch (field) {
    case UCAL_DAY_OF_WEEK:
    case UCAL_AM_PM:
    case UCAL_HOUR:
    case UCAL_HOUR_OF_DAY:
    case UCAL_MINUTE:
    case UCAL_SECOND:
    case UCAL_MILLISECOND:
    case UCAL_ZONE_OFFSET:
    case UCAL_DST_OFFSET:
    case UCAL_DOW_LOCAL:
    case UCAL_JULIAN_DAY:
    case UCAL_MILLISECONDS_IN_DAY:
        return kCalendarLimits[field][limitType];
    default:
        return handleGetLimit(field, limitType);
    }
}


int32_t
Calendar::getActualMinimum(UCalendarDateFields 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;

    /* Test for buffer overflows */
    if(U_FAILURE(status)) {
        return 0;
    }
    return result;
}

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



/**
 * Ensure that each field is within its valid range by calling {@link
 * #validateField(int)} on each field that has been set.  This method
 * should only be called if this calendar is not lenient.
 * @see #isLenient
 * @see #validateField(int)
 * @draft ICU 2.8
 */
void Calendar::validateFields(UErrorCode &status) {
  for (int32_t field = 0; U_SUCCESS(status) && (field < UCAL_FIELD_COUNT); field++) {
    if (isSet((UCalendarDateFields)field)) {
      validateField((UCalendarDateFields)field, status);
    }
  }
}

/**
 * Validate a single field of this calendar.  Subclasses should
 * override this method to validate any calendar-specific fields.
 * Generic fields can be handled by
 * <code>Calendar.validateField()</code>.
 * @see #validateField(int, int, int)
 * @draft ICU 2.8
 */
void Calendar::validateField(UCalendarDateFields field, UErrorCode &status) {
  int32_t y;
  switch (field) {
  case UCAL_DAY_OF_MONTH:
    y = handleGetExtendedYear();
    validateField(field, 1, handleGetMonthLength(y, internalGet(UCAL_MONTH)), status);
    break;
  case UCAL_DAY_OF_YEAR:
    y = handleGetExtendedYear();
    validateField(field, 1, handleGetYearLength(y), status);
    break;
  case UCAL_DAY_OF_WEEK_IN_MONTH:
    if (internalGet(field) == 0) {
#if defined (U_DEBUG_CAL)
          fprintf(stderr, "%s:%d: ILLEGAL ARG because DOW in month cannot be 0\n", 
                  __FILE__, __LINE__);
#endif
      status = U_ILLEGAL_ARGUMENT_ERROR; // "DAY_OF_WEEK_IN_MONTH cannot be zero"
      return;
    }
    validateField(field, getMinimum(field), getMaximum(field), status);
    break;
  default:
    validateField(field, getMinimum(field), getMaximum(field), status);
    break;
  }
}

/**
 * Validate a single field of this calendar given its minimum and
 * maximum allowed value.  If the field is out of range, throw a
 * descriptive <code>IllegalArgumentException</code>.  Subclasses may
 * use this method in their implementation of {@link
 * #validateField(int)}.
 * @draft ICU 2.8
 */
void Calendar::validateField(UCalendarDateFields field, int32_t min, int32_t max, UErrorCode& status)
{
  int32_t value = fFields[field];
  if (value < min || value > max) {
#if defined (U_DEBUG_CAL)
          fprintf(stderr, "%s:%d: ILLEGAL ARG because of field %s out of range %d..%d  at %d\n", 
                  __FILE__, __LINE__,fldName(field),min,max,value);
#endif
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return;
  }
}

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

const UFieldResolutionTable* Calendar::getFieldResolutionTable() const {
  return kDatePrecedence;
}


UCalendarDateFields Calendar::newerField(UCalendarDateFields defaultField, UCalendarDateFields alternateField) const
{
  if (fStamp[alternateField] > fStamp[defaultField]) {
    return alternateField;
  }
  return defaultField;
}

UCalendarDateFields Calendar::resolveFields(const UFieldResolutionTable* precedenceTable) {
  int32_t bestField = UCAL_FIELD_COUNT;
  for (int32_t g=0; precedenceTable[g][0][0] != -1 && (bestField == UCAL_FIELD_COUNT); ++g) {
    int32_t bestStamp = kUnset;
    for (int32_t l=0; precedenceTable[g][l][0] != -1; ++l) {
      int32_t lineStamp = kUnset;
      // Skip over first entry if it is negative
      for (int32_t i=((precedenceTable[g][l][0]>=kResolveRemap)?1:0); precedenceTable[g][l][i]!=-1; ++i) {
        int32_t s = fStamp[precedenceTable[g][l][i]];
        // If any field is unset then don't use this line
        if (s == kUnset) {
          goto linesInGroup;
        } else if(s > lineStamp) {
          lineStamp = s;
        }
      }
      // Record new maximum stamp & field no.
      if (lineStamp > bestStamp) {
        bestStamp = lineStamp;
        bestField = precedenceTable[g][l][0]; // First field refers to entire line
      }
    linesInGroup:
      ;
    }
  }
  return (UCalendarDateFields)( (bestField>=kResolveRemap)?(bestField&(kResolveRemap-1)):bestField  );
}

const UFieldResolutionTable Calendar::kDatePrecedence[] =
  { 
    {
      { UCAL_DAY_OF_MONTH, kResolveSTOP },
      { UCAL_WEEK_OF_YEAR, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { UCAL_WEEK_OF_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { UCAL_WEEK_OF_YEAR, UCAL_DOW_LOCAL, kResolveSTOP },
      { UCAL_WEEK_OF_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
      { UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
      { UCAL_DAY_OF_YEAR, kResolveSTOP },
      { kResolveRemap | UCAL_DAY_OF_MONTH, UCAL_YEAR, kResolveSTOP },  // if YEAR is set over YEAR_WOY use DAY_OF_MONTH
      { kResolveRemap | UCAL_WEEK_OF_YEAR, UCAL_YEAR_WOY, kResolveSTOP },  // if YEAR_WOY is set,  calc based on WEEK_OF_YEAR
      { kResolveSTOP }
    },
    {
      { UCAL_WEEK_OF_YEAR, kResolveSTOP },
      { UCAL_WEEK_OF_MONTH, kResolveSTOP },
      { UCAL_DAY_OF_WEEK_IN_MONTH, kResolveSTOP },
      { kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
      { kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
      { kResolveSTOP }
    }, 
    {{kResolveSTOP}}
  };


const UFieldResolutionTable Calendar::kDOWPrecedence[] = 
{
  {
    { UCAL_DAY_OF_WEEK,kResolveSTOP, kResolveSTOP },
    { UCAL_DOW_LOCAL,kResolveSTOP, kResolveSTOP },
    {kResolveSTOP}
  },
  {{kResolveSTOP}}
};

// precedence for calculating a year
const UFieldResolutionTable Calendar::kYearPrecedence[] = 
{
  {
    { UCAL_YEAR, kResolveSTOP },
    { UCAL_EXTENDED_YEAR, kResolveSTOP },
    { UCAL_YEAR_WOY, UCAL_WEEK_OF_YEAR, kResolveSTOP },  // YEAR_WOY is useless without WEEK_OF_YEAR
    { kResolveSTOP }
  },
  {{kResolveSTOP}}
};


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


void Calendar::computeTime(UErrorCode& status) {
  if (!isLenient()) {
    validateFields(status);
  }

  // Compute the Julian day
  int32_t julianDay = computeJulianDay();

  double millis = Grego::julianDayToMillis(julianDay);

#if defined (U_DEBUG_CAL)
  //  int32_t julianInsanityCheck =  (int32_t)Math::floorDivide(millis, kOneDay);
  //  julianInsanityCheck += kEpochStartAsJulianDay;
  //  if(1 || julianInsanityCheck != julianDay) {
  //    fprintf(stderr, "%s:%d- D'oh- computed jules %d, to mills (%s)%.lf, recomputed %d\n",
  //            __FILE__, __LINE__, julianDay, millis<0.0?"NEG":"", millis, julianInsanityCheck);
  //  }
#endif

  int32_t millisInDay;

  // We only use MILLISECONDS_IN_DAY if it has been set by the user.
  // This makes it possible for the caller to set the calendar to a
  // time and call clear(MONTH) to reset the MONTH to January.  This
  // is legacy behavior.  Without this, clear(MONTH) has no effect,
  // since the internally set JULIAN_DAY is used.
  if (fStamp[UCAL_MILLISECONDS_IN_DAY] >= ((int32_t)kMinimumUserStamp) &&
      newestStamp(UCAL_AM_PM, UCAL_MILLISECOND, kUnset) <= fStamp[UCAL_MILLISECONDS_IN_DAY]) {
    millisInDay = internalGet(UCAL_MILLISECONDS_IN_DAY);
  } else {
    millisInDay = computeMillisInDay();
  }
  
  // Compute the time zone offset and DST offset.  There are two potential
  // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time
  // for discussion purposes here.
  // 1. The transition into DST.  Here, a designated time of 2:00 am - 2:59 am
  //    can be in standard or in DST depending.  However, 2:00 am is an invalid
  //    representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).
  //    We assume standard time.
  // 2. The transition out of DST.  Here, a designated time of 1:00 am - 1:59 am
  //    can be in standard or DST.  Both are valid representations (the rep
  //    jumps from 1:59:59 DST to 1:00:00 Std).
  //    Again, we assume standard time.
  // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
  // or DST_OFFSET fields; then we use those fields.
  if (fStamp[UCAL_ZONE_OFFSET] >= ((int32_t)kMinimumUserStamp) ||
      fStamp[UCAL_DST_OFFSET] >= ((int32_t)kMinimumUserStamp)) {
    millisInDay -= internalGet(UCAL_ZONE_OFFSET) + internalGet(UCAL_DST_OFFSET);
  } else {
    millisInDay -= computeZoneOffset(millis, millisInDay,status);
  }
  
  internalSetTime(millis + millisInDay);
}

/**
 * Compute the milliseconds in the day from the fields.  This is a
 * value from 0 to 23:59:59.999 inclusive, unless fields are out of
 * range, in which case it can be an arbitrary value.  This value
 * reflects local zone wall time.
 * @stable ICU 2.0
 */
int32_t Calendar::computeMillisInDay() {
  // Do the time portion of the conversion.
  
  int32_t millisInDay = 0;
  
  // Find the best set of fields specifying the time of day.  There
  // are only two possibilities here; the HOUR_OF_DAY or the
  // AM_PM and the HOUR.
  int32_t hourOfDayStamp = fStamp[UCAL_HOUR_OF_DAY];
  int32_t hourStamp = (fStamp[UCAL_HOUR] > fStamp[UCAL_AM_PM])?fStamp[UCAL_HOUR]:fStamp[UCAL_AM_PM];
  int32_t bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;
  
  // Hours
  if (bestStamp != kUnset) {
    if (bestStamp == hourOfDayStamp) {
      // Don't normalize here; let overflow bump into the next period.
      // This is consistent with how we handle other fields.
      millisInDay += internalGet(UCAL_HOUR_OF_DAY);
    } else {
      // Don't normalize here; let overflow bump into the next period.
      // This is consistent with how we handle other fields.
      millisInDay += internalGet(UCAL_HOUR);
      millisInDay += 12 * internalGet(UCAL_AM_PM); // Default works for unset AM_PM
    }
  }
  
  // We use the fact that unset == 0; we start with millisInDay
  // == HOUR_OF_DAY.
  millisInDay *= 60;
  millisInDay += internalGet(UCAL_MINUTE); // now have minutes
  millisInDay *= 60;
  millisInDay += internalGet(UCAL_SECOND); // now have seconds
  millisInDay *= 1000;
  millisInDay += internalGet(MILLISECOND); // now have millis
  
  return millisInDay;
}

/**
 * This method can assume EXTENDED_YEAR has been set.
 * @param millis milliseconds of the date fields
 * @param millisInDay milliseconds of the time fields; may be out
 * or range.
 * @stable ICU 2.0
 */
int32_t Calendar::computeZoneOffset(double millis, int32_t millisInDay, UErrorCode &ec) {
  int32_t rawOffset, dstOffset;
  getTimeZone().getOffset(millis+millisInDay, TRUE, rawOffset, dstOffset, ec);
  return rawOffset + dstOffset;
  // Note: Because we pass in wall millisInDay, rather than
  // standard millisInDay, we interpret "1:00 am" on the day
  // of cessation of DST as "1:00 am Std" (assuming the time
  // of cessation is 2:00 am).
}

int32_t Calendar::computeJulianDay() 
{
  // We want to see if any of the date fields is newer than the
  // JULIAN_DAY.  If not, then we use JULIAN_DAY.  If so, then we do
  // the normal resolution.  We only use JULIAN_DAY if it has been
  // set by the user.  This makes it possible for the caller to set
  // the calendar to a time and call clear(MONTH) to reset the MONTH
  // to January.  This is legacy behavior.  Without this,
  // clear(MONTH) has no effect, since the internally set JULIAN_DAY
  // is used.
  if (fStamp[UCAL_JULIAN_DAY] >= (int32_t)kMinimumUserStamp) {
    int32_t bestStamp = newestStamp(UCAL_ERA, UCAL_DAY_OF_WEEK_IN_MONTH, kUnset);
    bestStamp = newestStamp(UCAL_YEAR_WOY, UCAL_EXTENDED_YEAR, bestStamp);
    if (bestStamp <= fStamp[UCAL_JULIAN_DAY]) {
      return internalGet(UCAL_JULIAN_DAY);
    }
  }

  UCalendarDateFields bestField = resolveFields(getFieldResolutionTable());
  if (bestField == UCAL_FIELD_COUNT) {
    bestField = UCAL_DAY_OF_MONTH;
  }

  return handleComputeJulianDay(bestField);
}

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

int32_t Calendar::handleComputeJulianDay(UCalendarDateFields bestField)  {
  UBool useMonth = (bestField == UCAL_DAY_OF_MONTH ||
                    bestField == UCAL_WEEK_OF_MONTH ||
                    bestField == UCAL_DAY_OF_WEEK_IN_MONTH);
  int32_t year;

  if (bestField == UCAL_WEEK_OF_YEAR) {
    year = internalGet(UCAL_YEAR_WOY, handleGetExtendedYear());
    internalSet(UCAL_EXTENDED_YEAR, year);
  } else {
    year = handleGetExtendedYear();
    internalSet(UCAL_EXTENDED_YEAR, year);
  }

#if defined (U_DEBUG_CAL) 
  fprintf(stderr, "%s:%d - bf= %s - y=%d\n", __FILE__, __LINE__, fldName(bestField), year);
#endif 

  // Get the Julian day of the day BEFORE the start of this year.
  // If useMonth is true, get the day before the start of the month.
  
  // give calendar subclass a chance to have a default 'first' month
  int8_t month;

  if(isSet(UCAL_MONTH)) {
    month = (int8_t)internalGet(UCAL_MONTH);
  } else {
    month = (int8_t)getDefaultMonthInYear();
  }

  int32_t julianDay = handleComputeMonthStart(year, useMonth ? month : 0, useMonth);

  if (bestField == UCAL_DAY_OF_MONTH) {

    // give calendar subclass a chance to have a default 'first' dom
    int32_t dayOfMonth;
    if(isSet(UCAL_DAY_OF_MONTH)) {
      dayOfMonth = internalGet(UCAL_DAY_OF_MONTH,1);
    } else {
      dayOfMonth = getDefaultDayInMonth(month);
    }
    return julianDay + dayOfMonth;
  }
  
  if (bestField == UCAL_DAY_OF_YEAR) {
    return julianDay + internalGet(UCAL_DAY_OF_YEAR);
  }
  
  int32_t firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw
  
  // At this point julianDay is the 0-based day BEFORE the first day of
  // January 1, year 1 of the given calendar.  If julianDay == 0, it
  // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
  // or Gregorian). (or it is before the month we are in, if useMonth is True)
  
  // At this point we need to process the WEEK_OF_MONTH or
  // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH.
  // First, perform initial shared computations.  These locate the
  // first week of the period.
  
  // Get the 0-based localized DOW of day one of the month or year.
  // Valid range 0..6.
  int32_t first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek;
  if (first < 0) {
    first += 7;
  }

  int32_t dowLocal = getLocalDOW();
  
  // Find the first target DOW (dowLocal) in the month or year.
  // Actually, it may be just before the first of the month or year.
  // It will be an integer from -5..7.
  int32_t date = 1 - first + dowLocal;
  
  if (bestField == UCAL_DAY_OF_WEEK_IN_MONTH) {
    // Adjust the target DOW to be in the month or year.
    if (date < 1) {
      date += 7;
    }
    
    // The only trickiness occurs if the day-of-week-in-month is
    // negative.
    int32_t dim = internalGet(UCAL_DAY_OF_WEEK_IN_MONTH, 1);
    if (dim >= 0) {
      date += 7*(dim - 1);
      
    } else {
      // Move date to the last of this day-of-week in this month,
      // then back up as needed.  If dim==-1, we don't back up at
      // all.  If dim==-2, we back up once, etc.  Don't back up
      // past the first of the given day-of-week in this month.
      // Note that we handle -2, -3, etc. correctly, even though
      // values < -1 are technically disallowed.
      int32_t m = internalGet(UCAL_MONTH, UCAL_JANUARY);
      int32_t monthLength = handleGetMonthLength(year, m);
      date += ((monthLength - date) / 7 + dim + 1) * 7;
    }
  } else {
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - bf= %s\n", __FILE__, __LINE__, fldName(bestField));
#endif 

    if(bestField == UCAL_WEEK_OF_YEAR) {  // ------------------------------------- WOY -------------
      if(!isSet(UCAL_YEAR_WOY) ||  // YWOY not set at all or
         ( (resolveFields(kYearPrecedence) != UCAL_YEAR_WOY) // YWOY doesn't have precedence
           && (fStamp[UCAL_YEAR_WOY]!=kInternallySet) ) ) { // (excluding where all fields are internally set - then YWOY is used)
        // need to be sure to stay in 'real' year.
        int32_t woy = internalGet(bestField);

        int32_t nextJulianDay = handleComputeMonthStart(year+1, 0, FALSE); // jd of day before jan 1
        int32_t nextFirst = julianDayToDayOfWeek(nextJulianDay + 1) - firstDayOfWeek; 
        
        if (nextFirst < 0) { // 0..6 ldow of Jan 1
          nextFirst += 7;
        }

        if(woy==1) {  // FIRST WEEK ---------------------------------
#if defined (U_DEBUG_CAL) 
          fprintf(stderr, "%s:%d - woy=%d, yp=%d, nj(%d)=%d, nf=%d", __FILE__, __LINE__, 
                  internalGet(bestField), resolveFields(kYearPrecedence), year+1, 
                  nextJulianDay, nextFirst);
          
          fprintf(stderr, " next: %d DFW,  min=%d   \n", (7-nextFirst), getMinimalDaysInFirstWeek() );
#endif 
          
          // nextFirst is now the localized DOW of Jan 1  of y-woy+1
          if((nextFirst > 0) &&   // Jan 1 starts on FDOW
             (7-nextFirst) >= getMinimalDaysInFirstWeek()) { // or enough days in the week
            // Jan 1 of (yearWoy+1) is in yearWoy+1 - recalculate JD to next year
#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "%s:%d - was going to move JD from %d to %d [d%d]\n", __FILE__, __LINE__, 
                    julianDay, nextJulianDay, (nextJulianDay-julianDay));
#endif 
            julianDay = nextJulianDay;
            
            // recalculate 'first' [0-based local dow of jan 1]
            first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek;
            if (first < 0) {
              first += 7;
            }
            // recalculate date.
            date = 1 - first + dowLocal;
          }
        } else if(woy>=getLeastMaximum(bestField)) {          
          // could be in the last week- find out if this JD would overstep
          int32_t testDate = date;
          if ((7 - first) < getMinimalDaysInFirstWeek()) {
            testDate += 7;
          }
          
          // Now adjust for the week number.
          testDate += 7 * (woy - 1);
          
#if defined (U_DEBUG_CAL) 
          fprintf(stderr, "%s:%d - y=%d, y-1=%d doy%d, njd%d (C.F. %d)\n",
                  __FILE__, __LINE__, year, year-1, testDate, julianDay+testDate, nextJulianDay);
#endif
          if(julianDay+testDate > nextJulianDay) { // is it past Dec 31?  (nextJulianDay is day BEFORE year+1's  Jan 1)
            // Fire up the calculating engines.. retry YWOY = (year-1)
            julianDay = handleComputeMonthStart(year-1, 0, FALSE); // jd before Jan 1 of previous year
            first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; // 0 based local dow   of first week
            
            if(first < 0) { // 0..6
              first += 7;
            }
            date = 1 - first + dowLocal;

#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "%s:%d - date now %d, jd%d, ywoy%d\n",
                    __FILE__, __LINE__, date, julianDay, year-1);
#endif

            
          } /* correction needed */
        } /* leastmaximum */
      } /* resolvefields(year) != year_woy */
    } /* bestfield != week_of_year */
    
    // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR)
    // Adjust for minimal days in first week
    if ((7 - first) < getMinimalDaysInFirstWeek()) {
      date += 7;
    }
    
    // Now adjust for the week number.
    date += 7 * (internalGet(bestField) - 1);
  }
  
  return julianDay + date;
}

int32_t
Calendar::getDefaultMonthInYear() 
{
    return 0;
}

int32_t
Calendar::getDefaultDayInMonth(int32_t /*month*/) 
{
    return 1;
}


int32_t Calendar::getLocalDOW()
{
  // Get zero-based localized DOW, valid range 0..6.  This is the DOW
  // we are looking for.
  int32_t dowLocal = 0;
  switch (resolveFields(kDOWPrecedence)) {
  case DAY_OF_WEEK:
    dowLocal = internalGet(UCAL_DAY_OF_WEEK) - fFirstDayOfWeek;
    break;
  case DOW_LOCAL:
    dowLocal = internalGet(UCAL_DOW_LOCAL) - 1;
    break;
  default:
    break;
  }
  dowLocal = dowLocal % 7;
  if (dowLocal < 0) {
    dowLocal += 7;
  }
  return dowLocal;
}

int32_t Calendar::handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy)
{
  // We have UCAL_YEAR_WOY and UCAL_WEEK_OF_YEAR - from those, determine 
  // what year we fall in, so that other code can set it properly.
  // (code borrowed from computeWeekFields and handleComputeJulianDay)
  //return yearWoy;

   // First, we need a reliable DOW.
   UCalendarDateFields bestField = resolveFields(kDatePrecedence); // !! Note: if subclasses have a different table, they should override handleGetExtendedYearFromWeekFields 

   // Now, a local DOW
   int32_t dowLocal = getLocalDOW(); // 0..6
   int32_t firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw
   int32_t jan1Start = handleComputeMonthStart(yearWoy, 0, FALSE);
   int32_t nextJan1Start = handleComputeMonthStart(yearWoy+1, 0, FALSE); // next year's Jan1 start
   
   // At this point julianDay is the 0-based day BEFORE the first day of
   // January 1, year 1 of the given calendar.  If julianDay == 0, it
   // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
   // or Gregorian). (or it is before the month we are in, if useMonth is True)
   
   // At this point we need to process the WEEK_OF_MONTH or
   // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH.
   // First, perform initial shared computations.  These locate the
   // first week of the period.
   
   // Get the 0-based localized DOW of day one of the month or year.
   // Valid range 0..6.
   int32_t first = julianDayToDayOfWeek(jan1Start + 1) - firstDayOfWeek;
   if (first < 0) {
     first += 7;
   }
   int32_t nextFirst = julianDayToDayOfWeek(nextJan1Start + 1) - firstDayOfWeek;
   if (nextFirst < 0) {
     nextFirst += 7;
   }

   int32_t minDays = getMinimalDaysInFirstWeek();
   UBool jan1InPrevYear = FALSE;  // January 1st in the year of WOY is the 1st week?  (i.e. first week is < minimal )
   UBool nextJan1InPrevYear = FALSE; // January 1st of Year of WOY + 1 is in the first week? 

   if((7 - first) < minDays) { 
     jan1InPrevYear = TRUE;
   }

   if((7 - nextFirst) < minDays) {
     nextJan1InPrevYear = TRUE;
   }
   
   switch(bestField) {
   case UCAL_WEEK_OF_YEAR:
     if(woy == 1) {
       if(jan1InPrevYear == TRUE) {
         // the first week of January is in the previous year
         // therefore WOY1 is always solidly within yearWoy
         return yearWoy;
       } else {
         // First WOY is split between two years
         if( dowLocal < first) { // we are prior to Jan 1
           return yearWoy-1; // previous year
         } else {
           return yearWoy; // in this year
         }
       }
     } else if(woy >= getLeastMaximum(bestField)) {  
       // we _might_ be in the last week.. 
       int32_t jd =  // Calculate JD of our target day:
         jan1Start +  // JD of Jan 1
         (7-first) + //  days in the first week (Jan 1.. )
         (woy-1)*7 + // add the weeks of the year
         dowLocal;   // the local dow (0..6) of last week
       if(jan1InPrevYear==FALSE) {
         jd -= 7; // woy already includes Jan 1's week.
       }
       
       if( (jd+1) >= nextJan1Start ) {
         // we are in week 52 or 53 etc. - actual year is yearWoy+1
         return yearWoy+1;
       } else {
         // still in yearWoy;
         return yearWoy;
       }
     } else {
       // we're not possibly in the last week -must be ywoy
       return yearWoy;
     }
     break;

    case UCAL_DATE:
     if((internalGet(UCAL_MONTH)==0) &&
        (woy >= getLeastMaximum(UCAL_WEEK_OF_YEAR))) {
       return yearWoy+1; // month 0, late woy = in the next year
     } else if(woy==1) {
       //if(nextJan1InPrevYear) {
       if(internalGet(UCAL_MONTH)==0) {
         return yearWoy;
       } else {
         return yearWoy-1;
       }
       //}
     }

     //(internalGet(UCAL_DATE) <= (7-first)) /* && in minDow  */ ) {
     //within 1st week and in this month.. 
     //return yearWoy+1;
     return yearWoy;
     break;

   default: // assume the year is appropriate
     return yearWoy;
     break;
   }

#if defined (U_DEBUG_CAL) 
   fprintf(stderr, "%s:%d - forgot a return on field %s\n", __FILE__, __LINE__, fldName(bestField));
#endif 

   return yearWoy;
}

int32_t Calendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const
{
    return handleComputeMonthStart(extendedYear, month+1, TRUE) -
        handleComputeMonthStart(extendedYear, month, TRUE);
}

int32_t Calendar::handleGetYearLength(int32_t eyear) const  {
    return handleComputeMonthStart(eyear+1, 0, FALSE) -
            handleComputeMonthStart(eyear, 0, FALSE);
}

int32_t
Calendar::getActualMaximum(UCalendarDateFields field, UErrorCode& status) const
{
    int32_t result;
    switch (field) {
    case UCAL_DATE:
        {
            if(U_FAILURE(status)) return 0;
            Calendar *cal = clone();
            if(!cal) { status = U_MEMORY_ALLOCATION_ERROR; return 0; }
            cal->prepareGetActual(field,FALSE,status);
            result = handleGetMonthLength(cal->get(UCAL_EXTENDED_YEAR, status), cal->get(UCAL_MONTH, status));
            delete cal;
        }
        break;

    case UCAL_DAY_OF_YEAR:
        {
            if(U_FAILURE(status)) return 0;
            Calendar *cal = clone();
            if(!cal) { status = U_MEMORY_ALLOCATION_ERROR; return 0; }
            cal->prepareGetActual(field,FALSE,status);
            result = handleGetYearLength(cal->get(UCAL_EXTENDED_YEAR, status));
            delete cal;
        }
        break;

    case DAY_OF_WEEK:
    case AM_PM:
    case HOUR:
    case HOUR_OF_DAY:
    case MINUTE:
    case SECOND:
    case MILLISECOND:
    case ZONE_OFFSET:
    case DST_OFFSET:
    case DOW_LOCAL:
    case UCAL_JULIAN_DAY:
    case UCAL_MILLISECONDS_IN_DAY:
        // These fields all have fixed minima/maxima
        result = getMaximum(field);
        break;

    default:
        // For all other fields, do it the hard way....
        result = getActualHelper(field, getLeastMaximum(field), getMaximum(field),status);
        break;
    }
    return result;
}


/**
* Prepare this calendar for computing the actual minimum or maximum.
* This method modifies this calendar's fields; it is called on a
* temporary calendar.
*
* <p>Rationale: The semantics of getActualXxx() is to return the
* maximum or minimum value that the given field can take, taking into
* account other relevant fields.  In general these other fields are
* larger fields.  For example, when computing the actual maximum
* DATE, the current value of DATE itself is ignored,
* as is the value of any field smaller.
*
* <p>The time fields all have fixed minima and maxima, so we don't
* need to worry about them.  This also lets us set the
* MILLISECONDS_IN_DAY to zero to erase any effects the time fields
* might have when computing date fields.
*
* <p>DAY_OF_WEEK is adjusted specially for the WEEK_OF_MONTH and
* WEEK_OF_YEAR fields to ensure that they are computed correctly.
* @internal
*/
void Calendar::prepareGetActual(UCalendarDateFields field, UBool isMinimum, UErrorCode &status)
 {
    set(UCAL_MILLISECONDS_IN_DAY, 0);

    switch (field) {
    case UCAL_YEAR:
    case UCAL_YEAR_WOY:
    case UCAL_EXTENDED_YEAR:
        set(UCAL_DAY_OF_YEAR, getGreatestMinimum(UCAL_DAY_OF_YEAR));
        break;

    case UCAL_MONTH:
        set(UCAL_DATE, getGreatestMinimum(UCAL_DATE));
        break;

    case UCAL_DAY_OF_WEEK_IN_MONTH:
        // For dowim, the maximum occurs for the DOW of the first of the
        // month.
        set(UCAL_DATE, 1);
        set(UCAL_DAY_OF_WEEK, get(UCAL_DAY_OF_WEEK, status)); // Make this user set
        break;

    case UCAL_WEEK_OF_MONTH:
    case UCAL_WEEK_OF_YEAR:
        // If we're counting weeks, set the day of the week to either the
        // first or last localized DOW.  We know the last week of a month
        // or year will contain the first day of the week, and that the
        // first week will contain the last DOW.
        {
            int32_t dow = fFirstDayOfWeek;
            if (isMinimum) {
                dow = (dow + 6) % 7; // set to last DOW
                if (dow < UCAL_SUNDAY) {
                    dow += 7;
                }
            }
#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "prepareGetActualHelper(WOM/WOY) - dow=%d\n", dow);
#endif
            set(UCAL_DAY_OF_WEEK, dow);
        }
        break;
    default:
	;
    }

    // Do this last to give it the newest time stamp
    set(field, getGreatestMinimum(field));
}

int32_t Calendar::getActualHelper(UCalendarDateFields field, int32_t startValue, int32_t endValue, UErrorCode &status) const
{
#if defined (U_DEBUG_CAL) 
  fprintf(stderr, "getActualHelper(%d,%d .. %d, %s)\n", field, startValue, endValue, u_errorName(status));
#endif
    if (startValue == endValue) {
        // if we know that the maximum value is always the same, just return it
        return startValue;
    }

    int32_t delta = (endValue > startValue) ? 1 : -1;

    // clone the calendar so we don't mess with the real one, and set it to
    // accept anything for the field values
    if(U_FAILURE(status)) return startValue;
    Calendar *work = clone();
    if(!work) { status = U_MEMORY_ALLOCATION_ERROR; return startValue; }
    work->setLenient(TRUE);
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status));
#endif 
   work->prepareGetActual(field, delta < 0, status);
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status));
#endif

    // now try each value from the start to the end 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 = startValue;
    do {
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status));
#endif
        work->set(field, startValue);
#if defined (U_DEBUG_CAL) 
        fprintf(stderr, "%s:%d - getActualHelper - %s (set to %d)\n", __FILE__, __LINE__, u_errorName(status), startValue);
#endif
        if (work->get(field, status) != startValue) {
#if defined (U_DEBUG_CAL) 
          fprintf(stderr, "getActualHelper(fld %d) - got  %d (not %d), BREAK - %s\n", field, work->get(field,status), startValue, u_errorName(status));
#endif
            break;
        } else {
            result = startValue;
            startValue += delta;
#if defined (U_DEBUG_CAL) 
            fprintf(stderr, "getActualHelper(%d)  result=%d (start), start += %d to %d\n", field, result, delta, startValue);
#endif
        }
    } while (result != endValue && U_SUCCESS(status));
    delete work;
#if defined (U_DEBUG_CAL) 
    fprintf(stderr, "getActualHelper(%d) = %d\n", field, result);
#endif
    return result;
}




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

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


    if (U_FAILURE(status)) return;

    fFirstDayOfWeek = UCAL_SUNDAY;
    fMinimalDaysInFirstWeek = 1;

    CalendarData calData(desiredLocale, type, status);
    // If the resource data doesn't seem to be present at all, then use last-resort
    // hard-coded data.
    UResourceBundle *dateTimeElements = calData.getByKey(kDateTimeElements, status);

    if (U_FAILURE(status))
    {
#if defined (U_DEBUG_CALDATA)
      fprintf(stderr, " Failure loading dateTimeElements = %s\n", u_errorName(status));
#endif
        status = U_USING_FALLBACK_WARNING;
        return;
    }

    U_LOCALE_BASED(locBased, *this);
    locBased.setLocaleIDs(ures_getLocaleByType(dateTimeElements, ULOC_VALID_LOCALE, &status),
                          ures_getLocaleByType(dateTimeElements, ULOC_ACTUAL_LOCALE, &status));
    if (U_SUCCESS(status)) {
#if defined (U_DEBUG_CAL)
      fprintf(stderr, " Valid=%s, Actual=%s\n", validLocale, actualLocale);
#endif
        int32_t arrLen;
        const int32_t *dateTimeElementsArr = ures_getIntVector(dateTimeElements, &arrLen, &status);

        if(U_SUCCESS(status) && arrLen == 2
            && 1 <= dateTimeElementsArr[0] && dateTimeElementsArr[0] <= 7
            && 1 <= dateTimeElementsArr[1] && dateTimeElementsArr[1] <= 7)
        {
            fFirstDayOfWeek = (UCalendarDaysOfWeek)dateTimeElementsArr[0];
            fMinimalDaysInFirstWeek = (uint8_t)dateTimeElementsArr[1];
        }
        else {
            status = U_INVALID_FORMAT_ERROR;
        }
    }
    
    // do NOT close dateTimeElements
}

/**
 * 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;
    fAreFieldsVirtuallySet = FALSE;
}

Locale 
Calendar::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
    U_LOCALE_BASED(locBased, *this);
    return locBased.getLocale(type, status);
}

const char *
Calendar::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
    U_LOCALE_BASED(locBased, *this);
    return locBased.getLocaleID(type, status);
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */


//eof
