/*
*******************************************************************************
*   Copyright (C) 1996-2001, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*/

#include "unicode/udat.h"

#include "unicode/uloc.h"
#include "unicode/datefmt.h"
#include "unicode/timezone.h"
#include "unicode/smpdtfmt.h"
#include "unicode/fieldpos.h"
#include "cpputils.h"
#include "unicode/parsepos.h"
#include "unicode/calendar.h"
#include "unicode/numfmt.h"
#include "unicode/dtfmtsym.h"
#include "unicode/ustring.h"

U_NAMESPACE_USE

/*
U_CAPI UDateFormat*
udat_open(            UDateFormatStyle        timeStyle, 
                UDateFormatStyle        dateStyle,
                const   char*                locale,
                const   UChar                    *tzID,
		      int32_t tzIDLength,
                UErrorCode*             status)
{
  if(U_FAILURE(*status)) return 0;
  
  DateFormat *fmt;
  if(locale == 0)
    fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
                         (DateFormat::EStyle)timeStyle);
  else
    fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
                         (DateFormat::EStyle)timeStyle,
                                             Locale(locale));
  
  if(fmt == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  if(tzID != 0) {
    TimeZone *zone = 0;
    int32_t length = (tzIDLength == -1 ? u_strlen(tzID) : tzIDLength);
    zone = TimeZone::createTimeZone(UnicodeString((UChar*)tzID,
						  length, length));
    if(zone == 0) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      delete fmt;
      return 0;
    }
    fmt->adoptTimeZone(zone);
  }
  
  return (UDateFormat*)fmt;
}

U_CAPI UDateFormat*
udat_openPattern(    const   UChar           *pattern, 
            int32_t         patternLength,
            const   char         *locale,
            UErrorCode      *status)
{
  if(U_FAILURE(*status)) return 0;

  int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength);
  UDateFormat *retVal = 0;

  if(locale == 0)
    retVal = (UDateFormat*)new SimpleDateFormat(UnicodeString((UChar*)pattern,
                                  len, len),
                        *status);
  else
    retVal = (UDateFormat*)new SimpleDateFormat(UnicodeString((UChar*)pattern,
                                  len, len),
                        Locale(locale),
                        *status);

  if(retVal == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return 0;
  }
  return retVal;
}
*/
U_CAPI UDateFormat* U_EXPORT2
udat_open(UDateFormatStyle  timeStyle,
          UDateFormatStyle  dateStyle,
          const char        *locale,
	      const UChar       *tzID,
	      int32_t           tzIDLength,
          const UChar       *pattern,
          int32_t           patternLength,
          UErrorCode        *status)
{

  if(U_FAILURE(*status)) 
  {
      return 0;
  }
  if(timeStyle != UDAT_IGNORE)
  {
      DateFormat *fmt;
      if(locale == 0)
        fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
                             (DateFormat::EStyle)timeStyle);
      else
        fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
                             (DateFormat::EStyle)timeStyle,
                                                 Locale(locale));
  
      if(fmt == 0) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
      }

      if(tzID != 0) {
        TimeZone *zone = 0;
        int32_t length = (tzIDLength == -1 ? u_strlen(tzID) : tzIDLength);
        zone = TimeZone::createTimeZone(UnicodeString((UChar*)tzID,
						      length, length));
        if(zone == 0) {
          *status = U_MEMORY_ALLOCATION_ERROR;
          delete fmt;
          return 0;
        }
        fmt->adoptTimeZone(zone);
      }
  
      return (UDateFormat*)fmt;
  }
  else
  {
      int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength);
      UDateFormat *retVal = 0;

      if(locale == 0)
        retVal = (UDateFormat*)new SimpleDateFormat(UnicodeString((UChar*)pattern,
                                      len, len),
                            *status);
      else
        retVal = (UDateFormat*)new SimpleDateFormat(UnicodeString((UChar*)pattern,
                                      len, len),
                            Locale(locale),
                            *status);

      if(retVal == 0) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
      }
      return retVal;
  }
}


U_CAPI void U_EXPORT2
udat_close(UDateFormat* format)
{

  delete (DateFormat*)format;
}

U_CAPI UDateFormat* U_EXPORT2
udat_clone(const UDateFormat *fmt,
       UErrorCode *status)
{

  if(U_FAILURE(*status)) return 0;

  Format *res = ((SimpleDateFormat*)fmt)->clone();
  
  if(res == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  return (UDateFormat*) res;
}

U_CAPI int32_t U_EXPORT2
udat_format(    const    UDateFormat*    format,
        UDate           dateToFormat,
        UChar*          result,
        int32_t         resultLength,
        UFieldPosition* position,
        UErrorCode*     status)
{

  if(U_FAILURE(*status)) return -1;

  UnicodeString res(result, 0, resultLength);
  FieldPosition fp;
  
  if(position != 0)
    fp.setField(position->field);
  
  ((DateFormat*)format)->format(dateToFormat, res, fp);
  
  if(position != 0) {
    position->beginIndex = fp.getBeginIndex();
    position->endIndex = fp.getEndIndex();
  }
  
  return res.extract(result, resultLength, *status);
}

U_CAPI UDate U_EXPORT2
udat_parse(    const    UDateFormat*        format,
        const    UChar*          text,
        int32_t         textLength,
        int32_t         *parsePos,
        UErrorCode      *status)
{

  if(U_FAILURE(*status)) return (UDate)0;

  int32_t len = (textLength == -1 ? u_strlen(text) : textLength);
  const UnicodeString src((UChar*)text, len, len);
  ParsePosition pp;
  UDate res;

  if(parsePos != 0)
    pp.setIndex(*parsePos);

  res = ((DateFormat*)format)->parse(src, pp);

  if(parsePos != 0) {
    if(pp.getErrorIndex() == -1)
      *parsePos = pp.getIndex();
    else {
      *parsePos = pp.getErrorIndex();
      *status = U_PARSE_ERROR;
    }
  }
  
  return res;
}

U_CAPI UBool U_EXPORT2
udat_isLenient(const UDateFormat* fmt)
{

  return ((DateFormat*)fmt)->isLenient();
}

U_CAPI void U_EXPORT2
udat_setLenient(    UDateFormat*    fmt,
            UBool          isLenient)
{

  ((DateFormat*)fmt)->setLenient(isLenient);
}

U_CAPI const UCalendar* U_EXPORT2
udat_getCalendar(const UDateFormat* fmt)
{

  return (const UCalendar*) ((DateFormat*)fmt)->getCalendar();
}

U_CAPI void U_EXPORT2
udat_setCalendar(            UDateFormat*    fmt,
                    const   UCalendar*      calendarToSet)
{

  ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet));
}

U_CAPI const UNumberFormat* U_EXPORT2
udat_getNumberFormat(const UDateFormat* fmt)
{

  return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
}

U_CAPI void U_EXPORT2
udat_setNumberFormat(            UDateFormat*    fmt,
                    const   UNumberFormat*  numberFormatToSet)
{

  ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet));
}

U_CAPI const char* U_EXPORT2
udat_getAvailable(int32_t index)
{
  return uloc_getAvailable(index);
}

U_CAPI int32_t U_EXPORT2
udat_countAvailable()
{

  return uloc_countAvailable();
}

U_CAPI UDate U_EXPORT2
udat_get2DigitYearStart(    const   UDateFormat     *fmt,
                UErrorCode      *status)
{

  if(U_FAILURE(*status)) return (UDate)0;
  return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status);
}

U_CAPI void U_EXPORT2
udat_set2DigitYearStart(    UDateFormat     *fmt,
                UDate           d,
                UErrorCode      *status)
{

  if(U_FAILURE(*status)) return;
  ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status);
}

U_CAPI int32_t U_EXPORT2
udat_toPattern(    const   UDateFormat     *fmt,
        UBool          localized,
        UChar           *result,
        int32_t         resultLength,
        UErrorCode      *status)
{

  if(U_FAILURE(*status)) return -1;

  UnicodeString res(result, 0, resultLength);

  if(localized)
    ((SimpleDateFormat*)fmt)->toLocalizedPattern(res, *status);
  else
    ((SimpleDateFormat*)fmt)->toPattern(res);

  return res.extract(result, resultLength, *status);
}

// TBD: should this take an UErrorCode?
U_CAPI void U_EXPORT2
udat_applyPattern(            UDateFormat     *format,
                    UBool          localized,
                    const   UChar           *pattern,
                    int32_t         patternLength)
{

  int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength);
  const UnicodeString pat((UChar*)pattern, len, len);
  UErrorCode status = U_ZERO_ERROR;

  if(localized)
    ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status);
  else
    ((SimpleDateFormat*)format)->applyPattern(pat);
}

U_CAPI int32_t U_EXPORT2
udat_getSymbols(const   UDateFormat             *fmt,
        UDateFormatSymbolType   type,
        int32_t                 index,
        UChar                   *result,
        int32_t                 resultLength,
        UErrorCode              *status)
{

  if(U_FAILURE(*status)) return -1;

  const DateFormatSymbols *syms = 
    ((SimpleDateFormat*)fmt)->getDateFormatSymbols();
  int32_t count;
  const UnicodeString *res;

  switch(type) {
  case UDAT_ERAS:
    res = syms->getEras(count);
    if(index < count) {
      return res[index].extract(result, resultLength, *status);
    }
    break;

  case UDAT_MONTHS:
    res = syms->getMonths(count);
    if(index < count) {
      return res[index].extract(result, resultLength, *status);
    }
    break;

  case UDAT_SHORT_MONTHS:
    res = syms->getShortMonths(count);
    if(index < count) {
      return res[index].extract(result, resultLength, *status);
    }
    break;

  case UDAT_WEEKDAYS:
    res = syms->getWeekdays(count);
    if(index < count) {
      return res[index].extract(result, resultLength, *status);
    }
    break;

  case UDAT_SHORT_WEEKDAYS:
    res = syms->getShortWeekdays(count);
    if(index < count) {
      return res[index].extract(result, resultLength, *status);
    }
    break;

  case UDAT_AM_PMS:
    res = syms->getAmPmStrings(count);
    if(index < count) {
      return res[index].extract(result, resultLength, *status);
    }
    break;

  case UDAT_LOCALIZED_CHARS:
    {
      UnicodeString res1(result, 0, resultLength);
      syms->getLocalPatternChars(res1);
      return res1.extract(result, resultLength, *status);
    }
  }
  
  return 0;
}

U_CAPI int32_t U_EXPORT2
udat_countSymbols(    const    UDateFormat                *fmt,
            UDateFormatSymbolType    type)
{

  const DateFormatSymbols *syms = 
    ((SimpleDateFormat*)fmt)->getDateFormatSymbols();
  int32_t count = 0;

  switch(type) {
  case UDAT_ERAS:
    syms->getEras(count);
    break;

  case UDAT_MONTHS:
    syms->getMonths(count);
    break;

  case UDAT_SHORT_MONTHS:
    syms->getShortMonths(count);
    break;

  case UDAT_WEEKDAYS:
    syms->getWeekdays(count);
    break;

  case UDAT_SHORT_WEEKDAYS:
    syms->getShortWeekdays(count);
    break;

  case UDAT_AM_PMS:
    syms->getAmPmStrings(count);
    break;

  case UDAT_LOCALIZED_CHARS:
    count = 1;
    break;
  }
  
  return count;
}

U_CAPI void U_EXPORT2
udat_setSymbols(    UDateFormat             *format,
            UDateFormatSymbolType   type,
            int32_t                 index,
            UChar                   *value,
            int32_t                 valueLength,
            UErrorCode              *status)
{

  if(U_FAILURE(*status)) return;

  int32_t count;
  int32_t len = (valueLength == -1 ? u_strlen(value) : valueLength);
  const UnicodeString val((UChar*)value, len, len);
  const UnicodeString *res;
  DateFormatSymbols *syms = new DateFormatSymbols( 
    * ((SimpleDateFormat*)format)->getDateFormatSymbols() );
  UnicodeString *array = 0;

  if(syms == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return;
  }

  switch(type) {
  case UDAT_ERAS:
    res = syms->getEras(count);
    array = new UnicodeString[count];
    if(array == 0) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      return;
    }
    uprv_arrayCopy(res, array, count);
    if(index < count)
      array[index] = val;
    syms->setEras(array, count);
    break;

  case UDAT_MONTHS:
    res = syms->getMonths(count);
    array = new UnicodeString[count];
    if(array == 0) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      return;
    }
    uprv_arrayCopy(res, array, count);
    if(index < count)
      array[index] = val;
    syms->setMonths(array, count);
    break;

  case UDAT_SHORT_MONTHS:
    res = syms->getShortMonths(count);
    array = new UnicodeString[count];
    if(array == 0) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      return;
    }
    uprv_arrayCopy(res, array, count);
    if(index < count)
      array[index] = val;
    syms->setShortMonths(array, count);
    break;

  case UDAT_WEEKDAYS:
    res = syms->getWeekdays(count);
    array = new UnicodeString[count];
    if(array == 0) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      return;
    }
    uprv_arrayCopy(res, array, count);
    if(index < count)
      array[index] = val;
    syms->setWeekdays(array, count);
    break;

  case UDAT_SHORT_WEEKDAYS:
    res = syms->getShortWeekdays(count);
    array = new UnicodeString[count];
    if(array == 0) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      return;
    }
    uprv_arrayCopy(res, array, count);
    if(index < count)
      array[index] = val;
    syms->setShortWeekdays(array, count);
    break;

  case UDAT_AM_PMS:
    res = syms->getAmPmStrings(count);
    array = new UnicodeString[count];
    if(array == 0) {
      *status = U_MEMORY_ALLOCATION_ERROR;
      return;
    }
    uprv_arrayCopy(res, array, count);
    if(index < count)
      array[index] = val;
    syms->setAmPmStrings(array, count);
    break;

  case UDAT_LOCALIZED_CHARS:
    syms->setLocalPatternChars(val);
    break;
  }
  
  ((SimpleDateFormat*)format)->adoptDateFormatSymbols(syms);
  delete [] array;
}


