/*
 *******************************************************************************
 * Copyright (C) 2008-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.impl.jdkadapter;

import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.CharacterIterator;
import java.text.DateFormatSymbols;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;

import com.ibm.icu.impl.icuadapter.NumberFormatJDK;
import com.ibm.icu.impl.icuadapter.TimeZoneJDK;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;

/**
 * SimpleDateFormatICU is an adapter class which wraps ICU4J SimpleDateFormat and
 * implements java.text.SimpleDateFormat APIs.
 */
public class SimpleDateFormatICU extends java.text.SimpleDateFormat {

    private static final long serialVersionUID = -2060890659010258983L;

    private SimpleDateFormat fIcuSdf;

    private SimpleDateFormatICU(SimpleDateFormat icuSdf) {
        fIcuSdf = icuSdf;
    }

    public static java.text.SimpleDateFormat wrap(SimpleDateFormat icuSdf) {
        return new SimpleDateFormatICU(icuSdf);
    }

    // Methods overriding java.text.SimpleDateFormat

    @Override
    public void applyLocalizedPattern(String pattern) {
        fIcuSdf.applyLocalizedPattern(pattern);
    }

    @Override
    public void applyPattern(String pattern) {
        fIcuSdf.applyPattern(pattern);
    }

    @Override
    public Object clone() {
        SimpleDateFormatICU other = (SimpleDateFormatICU)super.clone();
        other.fIcuSdf = (SimpleDateFormat)this.fIcuSdf.clone();
        return other;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof SimpleDateFormatICU) {
            return ((SimpleDateFormatICU)obj).fIcuSdf.equals(this.fIcuSdf);
        }
        return false;
    }

    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
        return fIcuSdf.format(date, toAppendTo, pos);
    }

    @Override
    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
        AttributedCharacterIterator aci = fIcuSdf.formatToCharacterIterator(obj);

        // Create a new AttributedString
        StringBuilder sb = new StringBuilder(aci.getEndIndex() - aci.getBeginIndex());
        char c = aci.first();
        while (true) {
            sb.append(c);
            c = aci.next();
            if (c == CharacterIterator.DONE) {
                break;
            }
        }
        AttributedString resstr = new AttributedString(sb.toString());

        // Mapping attributes
        Map<AttributedCharacterIterator.Attribute,Object> attributes = null;
        int index = aci.getBeginIndex();
        int residx = 0;
        while (true) {
            if (aci.setIndex(index) == CharacterIterator.DONE) {
                break;
            }
            attributes = aci.getAttributes();
            if (attributes != null) {
                int end = aci.getRunLimit();
                Map<AttributedCharacterIterator.Attribute,Object> jdkAttributes = 
                    new HashMap<AttributedCharacterIterator.Attribute,Object>();
                for (Entry<AttributedCharacterIterator.Attribute, Object> entry
                        : attributes.entrySet()) {
                    AttributedCharacterIterator.Attribute key = entry.getKey();
                    AttributedCharacterIterator.Attribute jdkKey = mapAttribute(key);
                    Object jdkVal = entry.getValue();
                    if (jdkVal instanceof AttributedCharacterIterator.Attribute) {
                        jdkVal = mapAttribute((AttributedCharacterIterator.Attribute)jdkVal);
                    }
                    jdkAttributes.put(jdkKey, jdkVal);
                }
                int resend = residx + (end - index);
                resstr.addAttributes(jdkAttributes, residx, resend);

                index = end;
                residx = resend;
            }
        }
        return resstr.getIterator();
    }

    @Override
    public Date get2DigitYearStart() {
        return fIcuSdf.get2DigitYearStart();
    }

    @Override
    public DateFormatSymbols getDateFormatSymbols() {
        return DateFormatSymbolsICU.wrap(fIcuSdf.getDateFormatSymbols());
    }

    @Override
    public int hashCode() {
        return fIcuSdf.hashCode();
    }

    @Override
    public Date parse(String text, ParsePosition pos) {
        return fIcuSdf.parse(text, pos);
    }

    @Override
    public void set2DigitYearStart(Date startDate) {
        fIcuSdf.set2DigitYearStart(startDate);
    }

    @Override
    public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) {
        com.ibm.icu.text.DateFormatSymbols icuDfs = null;
        if (newFormatSymbols instanceof DateFormatSymbolsICU) {
            icuDfs = ((DateFormatSymbolsICU)newFormatSymbols).unwrap();
        } else if (fIcuSdf.getCalendar() instanceof com.ibm.icu.util.GregorianCalendar) {
            // Java 6 uses DateFormatSymbols exclusively for Gregorian
            // calendar.

            String[] newJDK, curICU, newICU;
            icuDfs = fIcuSdf.getDateFormatSymbols();

            // Eras
            newJDK = newFormatSymbols.getEras();
            curICU = icuDfs.getEras();
            newICU = copySymbols(newJDK, curICU, true);

            // Months
            newJDK = newFormatSymbols.getMonths();
            curICU = icuDfs.getMonths();
            newICU = copySymbols(newJDK, curICU, false);
            icuDfs.setMonths(newICU);

            // ShortMonths
            newJDK = newFormatSymbols.getShortMonths();
            curICU = icuDfs.getShortMonths();
            newICU = copySymbols(newJDK, curICU, false);
            icuDfs.setShortMonths(newICU);

            // Weekdays
            newJDK = newFormatSymbols.getWeekdays();
            curICU = icuDfs.getWeekdays();
            newICU = copySymbols(newJDK, curICU, false);
            icuDfs.setWeekdays(newICU);

            // ShortWeekdays
            newJDK = newFormatSymbols.getShortWeekdays();
            curICU = icuDfs.getShortWeekdays();
            newICU = copySymbols(newJDK, curICU, false);
            icuDfs.setShortWeekdays(newICU);

            // AmPm
            newJDK = newFormatSymbols.getAmPmStrings();
            curICU = icuDfs.getAmPmStrings();
            newICU = copySymbols(newJDK, curICU, false);
            icuDfs.setAmPmStrings(newICU);
        } else {
            // For other calendars, JDK's standard DateFormatSymbols
            // cannot be used.
            throw new UnsupportedOperationException("JDK DateFormatSymbols cannot be used for the calendar type.");
        }
        fIcuSdf.setDateFormatSymbols(icuDfs);
    }

    @Override
    public String toLocalizedPattern() {
        return fIcuSdf.toLocalizedPattern();
    }

    @Override
    public String toPattern() {
        return fIcuSdf.toLocalizedPattern();
    }

    // Methods overriding java.text.DateFormat

    @Override
    public Calendar getCalendar() {
        return CalendarICU.wrap(fIcuSdf.getCalendar());
    }

    @Override
    public NumberFormat getNumberFormat() {
        com.ibm.icu.text.NumberFormat nfmt = fIcuSdf.getNumberFormat();
        if (nfmt instanceof NumberFormatJDK) {
            return ((NumberFormatJDK)nfmt).unwrap();
        }
        if (nfmt instanceof com.ibm.icu.text.DecimalFormat) {
            return DecimalFormatICU.wrap((com.ibm.icu.text.DecimalFormat)nfmt);
        }
        return NumberFormatICU.wrap(nfmt);
    }

    @Override
    public TimeZone getTimeZone() {
        return getCalendar().getTimeZone();
    }

    @Override
    public boolean isLenient() {
        return fIcuSdf.isLenient();
    }

    private static final long SAMPLE_TIME = 962409600000L; //2000-07-01T00:00:00Z
    private static final int JAPANESE_YEAR = 12; // Japanese calendar year @ SAMPLE_TIME
    private static final int THAI_YEAR = 2543; // Thai Buddhist calendar year @ SAMPLE_TIME

    @Override
    public void setCalendar(Calendar newCalendar) {
        com.ibm.icu.util.Calendar icuCal = null;
        if (newCalendar instanceof CalendarICU) {
            icuCal = ((CalendarICU)newCalendar).unwrap();
        } else {
            // Note:    There is no easy way to implement ICU Calendar with
            //          JDK Calendar implementation.  For now, this code assumes
            //          the given calendar is either Gregorian, Buddhist or
            //          JapaneseImperial.  Once the type is detected, this code
            //          creates an instance of ICU Calendar with the same type.
            com.ibm.icu.util.TimeZone icuTz = TimeZoneJDK.wrap(newCalendar.getTimeZone());
            if (newCalendar instanceof GregorianCalendar) {
                icuCal = new com.ibm.icu.util.GregorianCalendar(icuTz);
            } else {
                newCalendar.setTimeInMillis(SAMPLE_TIME);
                int year = newCalendar.get(Calendar.YEAR);
                if (year == JAPANESE_YEAR) {
                    icuCal = new com.ibm.icu.util.JapaneseCalendar(icuTz);
                } else if (year == THAI_YEAR) {
                    icuCal = new com.ibm.icu.util.BuddhistCalendar(icuTz);
                } else {
                    // We cannot support the case
                    throw new UnsupportedOperationException("Unsupported calendar type by ICU Calendar adapter.");
                }
            }
            // Copy the original calendar settings
            icuCal.setFirstDayOfWeek(newCalendar.getFirstDayOfWeek());
            icuCal.setLenient(newCalendar.isLenient());
            icuCal.setMinimalDaysInFirstWeek(newCalendar.getMinimalDaysInFirstWeek());
        }
        fIcuSdf.setCalendar(icuCal);
    }

    @Override
    public void setLenient(boolean lenient) {
        fIcuSdf.setLenient(lenient);
    }

    @Override
    public void setNumberFormat(NumberFormat newNumberFormat) {
        if (newNumberFormat instanceof DecimalFormatICU) {
            fIcuSdf.setNumberFormat(((DecimalFormatICU)newNumberFormat).unwrap());
        } else if (newNumberFormat instanceof NumberFormatICU) {
            fIcuSdf.setNumberFormat(((NumberFormatICU)newNumberFormat).unwrap());
        } else {
            fIcuSdf.setNumberFormat(NumberFormatJDK.wrap(newNumberFormat));
        }
    }

    @Override
    public void setTimeZone(TimeZone zone) {
        fIcuSdf.setTimeZone(TimeZoneJDK.wrap(zone));
    }

    private String[] copySymbols(String[] newData, String[] curData, boolean alignEnd) {
        if (newData.length >= curData.length) {
            return newData;
        }
        int startOffset = alignEnd ? curData.length - newData.length : 0;
        System.arraycopy(newData, 0, curData, startOffset, newData.length);
        return curData;
    }

    private static AttributedCharacterIterator.Attribute mapAttribute(AttributedCharacterIterator.Attribute icuAttribute) {
        AttributedCharacterIterator.Attribute jdkAttribute = icuAttribute;

        if (icuAttribute == DateFormat.Field.AM_PM) {
            jdkAttribute = java.text.DateFormat.Field.AM_PM;
        } else if (icuAttribute == DateFormat.Field.DAY_OF_MONTH) {
            jdkAttribute = java.text.DateFormat.Field.DAY_OF_MONTH;
        } else if (icuAttribute == DateFormat.Field.DAY_OF_WEEK) {
            jdkAttribute = java.text.DateFormat.Field.DAY_OF_WEEK;
        } else if (icuAttribute == DateFormat.Field.DAY_OF_WEEK_IN_MONTH) {
            jdkAttribute = java.text.DateFormat.Field.DAY_OF_WEEK_IN_MONTH;
        } else if (icuAttribute == DateFormat.Field.DAY_OF_YEAR) {
            jdkAttribute = java.text.DateFormat.Field.DAY_OF_YEAR;
        } else if (icuAttribute == DateFormat.Field.ERA) {
            jdkAttribute = java.text.DateFormat.Field.ERA;
        } else if (icuAttribute == DateFormat.Field.HOUR_OF_DAY0) {
            jdkAttribute = java.text.DateFormat.Field.HOUR_OF_DAY0;
        } else if (icuAttribute == DateFormat.Field.HOUR_OF_DAY1) {
            jdkAttribute = java.text.DateFormat.Field.HOUR_OF_DAY1;
        } else if (icuAttribute == DateFormat.Field.HOUR0) {
            jdkAttribute = java.text.DateFormat.Field.HOUR0;
        } else if (icuAttribute == DateFormat.Field.HOUR1) {
            jdkAttribute = java.text.DateFormat.Field.HOUR1;
        } else if (icuAttribute == DateFormat.Field.MILLISECOND) {
            jdkAttribute = java.text.DateFormat.Field.MILLISECOND;
        } else if (icuAttribute == DateFormat.Field.MINUTE) {
            jdkAttribute = java.text.DateFormat.Field.MINUTE;
        } else if (icuAttribute == DateFormat.Field.MONTH) {
            jdkAttribute = java.text.DateFormat.Field.MONTH;
        } else if (icuAttribute == DateFormat.Field.SECOND) {
            jdkAttribute = java.text.DateFormat.Field.SECOND;
        } else if (icuAttribute == DateFormat.Field.TIME_ZONE) {
            jdkAttribute = java.text.DateFormat.Field.TIME_ZONE;
        } else if (icuAttribute == DateFormat.Field.WEEK_OF_MONTH) {
            jdkAttribute = java.text.DateFormat.Field.WEEK_OF_MONTH;
        } else if (icuAttribute == DateFormat.Field.WEEK_OF_YEAR) {
            jdkAttribute = java.text.DateFormat.Field.WEEK_OF_YEAR;
        } else if (icuAttribute == DateFormat.Field.YEAR) {
            jdkAttribute = java.text.DateFormat.Field.YEAR;
        }
        // There are other DateFormat.Field constants defined in
        // ICU4J DateFormat below.
        //
        //   DOW_LOCAL
        //   EXTENDED_YEAR
        //   JULIAN_DAY
        //   MILLISECONDS_IN_DAY
        //   QUARTER
        //   YEAR_WOY
        //
        // However, the corresponding pattern characters are not used by
        // the default factory method - getXXXInstance.  So these constants
        // are only used when user intentionally set a pattern including
        // these ICU4J specific pattern letters.  Even it happens,
        // ICU4J's DateFormat.Field extends java.text.Format.Field, so
        // it does not break the contract of formatToCharacterIterator.

        return jdkAttribute;
    }

}
