/* SimpleDateFormat.java -- A class for parsing/formating simple 
   date constructs
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.text;

import gnu.java.text.AttributedFormatBuffer;
import gnu.java.text.FormatBuffer;
import gnu.java.text.FormatCharacterIterator;
import gnu.java.text.StringFormatBuffer;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * SimpleDateFormat provides convenient methods for parsing and formatting
 * dates using Gregorian calendars (see java.util.GregorianCalendar). 
 */
public class SimpleDateFormat extends DateFormat 
{
  /** 
   * This class is used by <code>SimpleDateFormat</code> as a
   * compiled representation of a format string.  The field
   * ID, size, and character used are stored for each sequence
   * of pattern characters.
   */
  private class CompiledField
  {
    /**
     * The ID of the field within the local pattern characters,
     */
    private int field;

    /**
     * The size of the character sequence.
     */
    private int size;

    /**
     * The character used.
     */
    private char character;

    /** 
     * Constructs a compiled field using the
     * the given field ID, size and character
     * values.
     *
     * @param f the field ID.
     * @param s the size of the field.
     * @param c the character used.
     */
    public CompiledField(int f, int s, char c)
    {
      field = f;
      size = s;
      character = c;
    }

    /**
     * Retrieves the ID of the field relative to
     * the local pattern characters.
     */
    public int getField()
    {
      return field;
    }

    /**
     * Retrieves the size of the character sequence.
     */
    public int getSize()
    {
      return size;
    }

    /**
     * Retrieves the character used in the sequence.
     */
    public char getCharacter()
    {
      return character;
    }

    /**
     * Returns a <code>String</code> representation
     * of the compiled field, primarily for debugging
     * purposes.
     *
     * @return a <code>String</code> representation.
     */
    public String toString()
    {
      StringBuffer builder;

      builder = new StringBuffer(getClass().getName());
      builder.append("[field=");
      builder.append(field);
      builder.append(", size=");
      builder.append(size);
      builder.append(", character=");
      builder.append(character);
      builder.append("]");

      return builder.toString();
    }
  }

  /**
   * A list of <code>CompiledField</code>s,
   * representing the compiled version of the pattern.
   *
   * @see CompiledField
   * @serial Ignored.
   */
  private transient ArrayList tokens;

  /**
   * The localised data used in formatting,
   * such as the day and month names in the local
   * language, and the localized pattern characters.
   *
   * @see DateFormatSymbols
   * @serial The localisation data.  May not be null.
   */
  private DateFormatSymbols formatData;

  /**
   * The date representing the start of the century
   * used for interpreting two digit years.  For
   * example, 24/10/2004 would cause two digit
   * years to be interpreted as representing
   * the years between 2004 and 2104.
   *
   * @see get2DigitYearStart()
   * @see set2DigitYearStart(java.util.Date)
   * @see Date
   * @serial The start date of the century for parsing two digit years.
   *         May not be null.
   */
  private Date defaultCenturyStart;

  /**
   * The year at which interpretation of two
   * digit years starts.
   *
   * @see get2DigitYearStart()
   * @see set2DigitYearStart(java.util.Date)
   * @serial Ignored.
   */
  private transient int defaultCentury;

  /**
   * The non-localized pattern string.  This
   * only ever contains the pattern characters
   * stored in standardChars.  Localized patterns
   * are translated to this form.
   *
   * @see applyPattern(String)
   * @see applyLocalizedPattern(String)
   * @see toPattern()
   * @see toLocalizedPattern()
   * @serial The non-localized pattern string.  May not be null.
   */
  private String pattern;

  /**
   * The version of serialized data used by this class.
   * Version 0 only includes the pattern and formatting
   * data.  Version 1 adds the start date for interpreting
   * two digit years.
   *
   * @serial This specifies the version of the data being serialized.
   *         Version 0 (or no version) specifies just <code>pattern</code>
   *         and <code>formatData</code>.  Version 1 adds
   *         the <code>defaultCenturyStart</code>.  This implementation
   *         always writes out version 1 data.
   */
  private int serialVersionOnStream = 1; // 0 indicates JDK1.1.3 or earlier

  /**
   * For compatability.
   */
  private static final long serialVersionUID = 4774881970558875024L;

  // This string is specified in the root of the CLDR.  We set it here
  // rather than doing a DateFormatSymbols(Locale.US).getLocalPatternChars()
  // since someone could theoretically change those values (though unlikely).
  private static final String standardChars = "GyMdkHmsSEDFwWahKzYeugAZ";

  /**
   * Reads the serialized version of this object.
   * If the serialized data is only version 0,
   * then the date for the start of the century
   * for interpreting two digit years is computed.
   * The pattern is parsed and compiled following the process
   * of reading in the serialized data.
   *
   * @param stream the object stream to read the data from.
   * @throws IOException if an I/O error occurs.
   * @throws ClassNotFoundException if the class of the serialized data
   *         could not be found.
   * @throws InvalidObjectException if the pattern is invalid.
   */ 
  private void readObject(ObjectInputStream stream)
    throws IOException, ClassNotFoundException
  {
    stream.defaultReadObject();
    if (serialVersionOnStream < 1)
      {
        computeCenturyStart ();
	serialVersionOnStream = 1;
      }
    else
      // Ensure that defaultCentury gets set.
      set2DigitYearStart(defaultCenturyStart);

    // Set up items normally taken care of by the constructor.
    tokens = new ArrayList();
    try
      {
	compileFormat(pattern);
      }
    catch (IllegalArgumentException e)
      {
	throw new InvalidObjectException("The stream pattern was invalid.");
      }
  }

  /**
   * Compiles the supplied non-localized pattern into a form
   * from which formatting and parsing can be performed.
   * This also detects errors in the pattern, which will
   * be raised on later use of the compiled data.
   *
   * @param pattern the non-localized pattern to compile.
   * @throws IllegalArgumentException if the pattern is invalid.
   */
  private void compileFormat(String pattern) 
  {
    // Any alphabetical characters are treated as pattern characters
    // unless enclosed in single quotes.

    char thisChar;
    int pos;
    int field;
    CompiledField current = null;

    for (int i=0; i<pattern.length(); i++) {
      thisChar = pattern.charAt(i);
      field = standardChars.indexOf(thisChar);
      if (field == -1) {
	current = null;
	if ((thisChar >= 'A' && thisChar <= 'Z')
	    || (thisChar >= 'a' && thisChar <= 'z')) {
 	  // Not a valid letter
	  throw new IllegalArgumentException("Invalid letter " + thisChar +
					     "encountered at character " + i
					     + ".");
	} else if (thisChar == '\'') {
	  // Quoted text section; skip to next single quote
	  pos = pattern.indexOf('\'',i+1);
	  if (pos == -1) {
	    throw new IllegalArgumentException("Quotes starting at character "
					       + i + " not closed.");
	  }
	  if ((pos+1 < pattern.length()) && (pattern.charAt(pos+1) == '\'')) {
	    tokens.add(pattern.substring(i+1,pos+1));
	  } else {
	    tokens.add(pattern.substring(i+1,pos));
	  }
	  i = pos;
	} else {
	  // A special character
	  tokens.add(new Character(thisChar));
	}
      } else {
	// A valid field
	if ((current != null) && (field == current.field)) {
	  current.size++;
	} else {
	  current = new CompiledField(field,1,thisChar);
	  tokens.add(current);
	}
      }
    }
  }

  /**
   * Returns a string representation of this
   * class.
   *
   * @return a string representation of the <code>SimpleDateFormat</code>
   *         instance.
   */
  public String toString() 
  {
    StringBuffer output = new StringBuffer(getClass().getName());
    output.append("[tokens=");
    output.append(tokens);
    output.append(", formatData=");
    output.append(formatData);
    output.append(", defaultCenturyStart=");
    output.append(defaultCenturyStart);
    output.append(", defaultCentury=");
    output.append(defaultCentury);
    output.append(", pattern=");
    output.append(pattern);
    output.append(", serialVersionOnStream=");
    output.append(serialVersionOnStream);
    output.append(", standardChars=");
    output.append(standardChars);
    output.append("]");
    return output.toString();
  }

  /**
   * Constructs a SimpleDateFormat using the default pattern for
   * the default locale.
   */
  public SimpleDateFormat() 
  {
    /*
     * There does not appear to be a standard API for determining 
     * what the default pattern for a locale is, so use package-scope
     * variables in DateFormatSymbols to encapsulate this.
     */
    super();
    Locale locale = Locale.getDefault();
    calendar = new GregorianCalendar(locale);
    computeCenturyStart();
    tokens = new ArrayList();
    formatData = new DateFormatSymbols(locale);
    pattern = (formatData.dateFormats[DEFAULT] + ' '
	       + formatData.timeFormats[DEFAULT]);
    compileFormat(pattern);
    numberFormat = NumberFormat.getInstance(locale);
    numberFormat.setGroupingUsed (false);
    numberFormat.setParseIntegerOnly (true);
    numberFormat.setMaximumFractionDigits (0);
  }
  
  /**
   * Creates a date formatter using the specified non-localized pattern,
   * with the default DateFormatSymbols for the default locale.
   *
   * @param pattern the pattern to use.
   * @throws NullPointerException if the pattern is null.
   * @throws IllegalArgumentException if the pattern is invalid.
   */
  public SimpleDateFormat(String pattern) 
  {
    this(pattern, Locale.getDefault());
  }

  /**
   * Creates a date formatter using the specified non-localized pattern,
   * with the default DateFormatSymbols for the given locale.
   *
   * @param pattern the non-localized pattern to use.
   * @param locale the locale to use for the formatting symbols.
   * @throws NullPointerException if the pattern is null.
   * @throws IllegalArgumentException if the pattern is invalid.
   */
  public SimpleDateFormat(String pattern, Locale locale) 
  {
    super();
    calendar = new GregorianCalendar(locale);
    computeCenturyStart();
    tokens = new ArrayList();
    formatData = new DateFormatSymbols(locale);
    compileFormat(pattern);
    this.pattern = pattern;
    numberFormat = NumberFormat.getInstance(locale);
    numberFormat.setGroupingUsed (false);
    numberFormat.setParseIntegerOnly (true);
    numberFormat.setMaximumFractionDigits (0);
  }

  /**
   * Creates a date formatter using the specified non-localized
   * pattern. The specified DateFormatSymbols will be used when
   * formatting.
   *
   * @param pattern the non-localized pattern to use.
   * @param formatData the formatting symbols to use.
   * @throws NullPointerException if the pattern or formatData is null.
   * @throws IllegalArgumentException if the pattern is invalid.
   */
  public SimpleDateFormat(String pattern, DateFormatSymbols formatData)
  {
    super();
    calendar = new GregorianCalendar();
    computeCenturyStart ();
    tokens = new ArrayList();
    if (formatData == null)
      throw new NullPointerException("formatData");
    this.formatData = formatData;
    compileFormat(pattern);
    this.pattern = pattern;
    numberFormat = NumberFormat.getInstance();
    numberFormat.setGroupingUsed (false);
    numberFormat.setParseIntegerOnly (true);
    numberFormat.setMaximumFractionDigits (0);
  }

  /**
   * This method returns a string with the formatting pattern being used
   * by this object.  This string is unlocalized.
   *
   * @return The format string.
   */
  public String toPattern()
  {
    return pattern;
  }

  /**
   * This method returns a string with the formatting pattern being used
   * by this object.  This string is localized.
   *
   * @return The format string.
   */
  public String toLocalizedPattern()
  {
    String localChars = formatData.getLocalPatternChars();
    return translateLocalizedPattern(pattern, standardChars, localChars);
  }

  /**
   * This method sets the formatting pattern that should be used by this
   * object.  This string is not localized.
   *
   * @param pattern The new format pattern.
   * @throws NullPointerException if the pattern is null.
   * @throws IllegalArgumentException if the pattern is invalid.
   */
  public void applyPattern(String pattern)
  {
    tokens = new ArrayList();
    compileFormat(pattern);
    this.pattern = pattern;
  }

  /**
   * This method sets the formatting pattern that should be used by this
   * object.  This string is localized.
   *
   * @param pattern The new format pattern.
   * @throws NullPointerException if the pattern is null.
   * @throws IllegalArgumentException if the pattern is invalid.
   */
  public void applyLocalizedPattern(String pattern)
  {
    String localChars = formatData.getLocalPatternChars();
    pattern = translateLocalizedPattern(pattern, localChars, standardChars);
    applyPattern(pattern);
  }

  /**
   * Translates either from or to a localized variant of the pattern
   * string.  For example, in the German locale, 't' (for 'tag') is
   * used instead of 'd' (for 'date').  This method translates
   * a localized pattern (such as 'ttt') to a non-localized pattern
   * (such as 'ddd'), or vice versa.  Non-localized patterns use
   * a standard set of characters, which match those of the U.S. English
   * locale.
   *
   * @param pattern the pattern to translate.
   * @param oldChars the old set of characters (used in the pattern).
   * @param newChars the new set of characters (which will be used in the
   *                 pattern).
   * @return a version of the pattern using the characters in
   *         <code>newChars</code>.
   */
  private String translateLocalizedPattern(String pattern,
					   String oldChars, String newChars)
  {
    int len = pattern.length();
    StringBuffer buf = new StringBuffer(len);
    boolean quoted = false;
    for (int i = 0;  i < len;  i++)
      {
	char ch = pattern.charAt(i);
	if (ch == '\'')
	  quoted = ! quoted;
	if (! quoted)
	  {
	    int j = oldChars.indexOf(ch);
	    if (j >= 0)
	      ch = newChars.charAt(j);
	  }
	buf.append(ch);
      }
    return buf.toString();
  }

  /** 
   * Returns the start of the century used for two digit years.
   *
   * @return A <code>Date</code> representing the start of the century
   * for two digit years.
   */
  public Date get2DigitYearStart()
  {
    return defaultCenturyStart;
  }

  /**
   * Sets the start of the century used for two digit years.
   *
   * @param date A <code>Date</code> representing the start of the century for
   * two digit years.
   */
  public void set2DigitYearStart(Date date)
  {
    defaultCenturyStart = date;
    calendar.clear();
    calendar.setTime(date);
    int year = calendar.get(Calendar.YEAR);
    defaultCentury = year - (year % 100);
  }

  /**
   * This method returns a copy of the format symbol information used
   * for parsing and formatting dates.
   *
   * @return a copy of the date format symbols.
   */
  public DateFormatSymbols getDateFormatSymbols()
  {
    return (DateFormatSymbols) formatData.clone();
  }

  /**
   * This method sets the format symbols information used for parsing
   * and formatting dates.
   *
   * @param formatData The date format symbols.
   * @throws NullPointerException if <code>formatData</code> is null.
   */
   public void setDateFormatSymbols(DateFormatSymbols formatData)
   {
     if (formatData == null)
       {
	 throw new
	   NullPointerException("The supplied format data was null.");
       }
     this.formatData = formatData;
   }

  /**
   * This methods tests whether the specified object is equal to this
   * object.  This will be true if and only if the specified object:
   * <p>
   * <ul>
   * <li>Is not <code>null</code>.</li>
   * <li>Is an instance of <code>SimpleDateFormat</code>.</li>
   * <li>Is equal to this object at the superclass (i.e., <code>DateFormat</code>)
   *     level.</li>
   * <li>Has the same formatting pattern.</li>
   * <li>Is using the same formatting symbols.</li>
   * <li>Is using the same century for two digit years.</li>
   * </ul>
   *
   * @param obj The object to compare for equality against.
   *
   * @return <code>true</code> if the specified object is equal to this object,
   * <code>false</code> otherwise.
   */
  public boolean equals(Object o)
  {
    if (!super.equals(o))
      return false;

    if (!(o instanceof SimpleDateFormat))
      return false;

    SimpleDateFormat sdf = (SimpleDateFormat)o;

    if (defaultCentury != sdf.defaultCentury)
      return false;

    if (!toPattern().equals(sdf.toPattern()))
      return false;

    if (!getDateFormatSymbols().equals(sdf.getDateFormatSymbols()))
      return false;

    return true;
  }

  /**
   * This method returns a hash value for this object.
   *
   * @return A hash value for this object.
   */
  public int hashCode()
  {
    return super.hashCode() ^ toPattern().hashCode() ^ defaultCentury ^
      getDateFormatSymbols().hashCode();
  }


  /**
   * Formats the date input according to the format string in use,
   * appending to the specified StringBuffer.  The input StringBuffer
   * is returned as output for convenience.
   */
  private void formatWithAttribute(Date date, FormatBuffer buffer, FieldPosition pos)
  {
    String temp;
    AttributedCharacterIterator.Attribute attribute;
    calendar.setTime(date);

    // go through vector, filling in fields where applicable, else toString
    Iterator iter = tokens.iterator();
    while (iter.hasNext())
      {
	Object o = iter.next();
	if (o instanceof CompiledField)
	  {
	    CompiledField cf = (CompiledField) o;
	    int beginIndex = buffer.length();
	    
	    switch (cf.getField())
	      {
	      case ERA_FIELD:
		buffer.append (formatData.eras[calendar.get (Calendar.ERA)], DateFormat.Field.ERA);
		break;
	      case YEAR_FIELD:
		// If we have two digits, then we truncate.  Otherwise, we
		// use the size of the pattern, and zero pad.
		buffer.setDefaultAttribute (DateFormat.Field.YEAR);
		if (cf.getSize() == 2)
		  {
		    temp = String.valueOf (calendar.get (Calendar.YEAR));
		    buffer.append (temp.substring (temp.length() - 2));
		  }
		else
		  withLeadingZeros (calendar.get (Calendar.YEAR), cf.getSize(), buffer);
		break;
	      case MONTH_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.MONTH);
		if (cf.getSize() < 3)
		  withLeadingZeros (calendar.get (Calendar.MONTH) + 1, cf.getSize(), buffer);
		else if (cf.getSize() < 4)
		  buffer.append (formatData.shortMonths[calendar.get (Calendar.MONTH)]);
		else
		  buffer.append (formatData.months[calendar.get (Calendar.MONTH)]);
		break;
	      case DATE_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_MONTH);
		withLeadingZeros (calendar.get (Calendar.DATE), cf.getSize(), buffer);
		break;
	      case HOUR_OF_DAY1_FIELD: // 1-24
		buffer.setDefaultAttribute(DateFormat.Field.HOUR_OF_DAY1);
		withLeadingZeros ( ((calendar.get (Calendar.HOUR_OF_DAY) + 23) % 24) + 1, 
				   cf.getSize(), buffer);
		break;
	      case HOUR_OF_DAY0_FIELD: // 0-23
		buffer.setDefaultAttribute (DateFormat.Field.HOUR_OF_DAY0);
		withLeadingZeros (calendar.get (Calendar.HOUR_OF_DAY), cf.getSize(), buffer);
		break;
	      case MINUTE_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.MINUTE);
		withLeadingZeros (calendar.get (Calendar.MINUTE),
				  cf.getSize(), buffer);
		break;
	      case SECOND_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.SECOND);
		withLeadingZeros(calendar.get (Calendar.SECOND), 
				 cf.getSize(), buffer);
		break;
	      case MILLISECOND_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.MILLISECOND);
		withLeadingZeros (calendar.get (Calendar.MILLISECOND), cf.getSize(), buffer);
		break;
	      case DAY_OF_WEEK_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_WEEK);
		if (cf.getSize() < 4)
		  buffer.append (formatData.shortWeekdays[calendar.get (Calendar.DAY_OF_WEEK)]);
		else
		  buffer.append (formatData.weekdays[calendar.get (Calendar.DAY_OF_WEEK)]);
		break;
	      case DAY_OF_YEAR_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_YEAR);
		withLeadingZeros (calendar.get (Calendar.DAY_OF_YEAR), cf.getSize(), buffer);
		break;
	      case DAY_OF_WEEK_IN_MONTH_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_WEEK_IN_MONTH);
		withLeadingZeros (calendar.get (Calendar.DAY_OF_WEEK_IN_MONTH), 
				 cf.getSize(), buffer);
		break;
	      case WEEK_OF_YEAR_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.WEEK_OF_YEAR);
		withLeadingZeros (calendar.get (Calendar.WEEK_OF_YEAR),
				  cf.getSize(), buffer);
		break;
	      case WEEK_OF_MONTH_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.WEEK_OF_MONTH);
		withLeadingZeros (calendar.get (Calendar.WEEK_OF_MONTH),
				  cf.getSize(), buffer);
		break;
	      case AM_PM_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.AM_PM);
		buffer.append (formatData.ampms[calendar.get (Calendar.AM_PM)]);
		break;
	      case HOUR1_FIELD: // 1-12
		buffer.setDefaultAttribute (DateFormat.Field.HOUR1);
		withLeadingZeros (((calendar.get (Calendar.HOUR) + 11) % 12) + 1,
				  cf.getSize(), buffer);
		break;
	      case HOUR0_FIELD: // 0-11
		buffer.setDefaultAttribute (DateFormat.Field.HOUR0);
		withLeadingZeros (calendar.get (Calendar.HOUR), cf.getSize(), buffer);
		break;
	      case TIMEZONE_FIELD:
		buffer.setDefaultAttribute (DateFormat.Field.TIME_ZONE);
		TimeZone zone = calendar.getTimeZone();
		boolean isDST = calendar.get (Calendar.DST_OFFSET) != 0;
		// FIXME: XXX: This should be a localized time zone.
		String zoneID = zone.getDisplayName
		  (isDST, cf.getSize() > 3 ? TimeZone.LONG : TimeZone.SHORT);
		buffer.append (zoneID);
		break;
	      case RFC822_TIMEZONE_FIELD:
		buffer.setDefaultAttribute(DateFormat.Field.RFC822_TIME_ZONE);
		int pureMinutes = (calendar.get(Calendar.ZONE_OFFSET) +
				   calendar.get(Calendar.DST_OFFSET)) / (1000 * 60);
		String sign = (pureMinutes < 0) ? "-" : "+";	  
		int hours = pureMinutes / 60;
		int minutes = pureMinutes % 60;
		buffer.append(sign);
		withLeadingZeros(hours, 2, buffer);
		withLeadingZeros(minutes, 2, buffer);
		break;
	      default:
		throw new IllegalArgumentException ("Illegal pattern character " +
						    cf.getCharacter());
	      }
	    if (pos != null && (buffer.getDefaultAttribute() == pos.getFieldAttribute()
				|| cf.getField() == pos.getField()))
	      {
		pos.setBeginIndex(beginIndex);
		pos.setEndIndex(buffer.length());
	      }
	  } 
      else
	{  
	  buffer.append(o.toString(), null);
	}
      }
  }
  
  public StringBuffer format(Date date, StringBuffer buffer, FieldPosition pos)
  {
    formatWithAttribute(date, new StringFormatBuffer (buffer), pos);

    return buffer;
  }

  public AttributedCharacterIterator formatToCharacterIterator(Object date)
    throws IllegalArgumentException
  {
    if (date == null)
      throw new NullPointerException("null argument");
    if (!(date instanceof Date))
      throw new IllegalArgumentException("argument should be an instance of java.util.Date");

    AttributedFormatBuffer buf = new AttributedFormatBuffer();
    formatWithAttribute((Date)date, buf,
			null);
    buf.sync();
        
    return new FormatCharacterIterator(buf.getBuffer().toString(),
				       buf.getRanges(),
				       buf.getAttributes());
  }

  private void withLeadingZeros(int value, int length, FormatBuffer buffer) 
  {
    String valStr = String.valueOf(value);
    for (length -= valStr.length(); length > 0; length--)
      buffer.append('0');
    buffer.append(valStr);
  }

  private boolean expect(String source, ParsePosition pos, char ch)
  {
    int x = pos.getIndex();
    boolean r = x < source.length() && source.charAt(x) == ch;
    if (r)
      pos.setIndex(x + 1);
    else
      pos.setErrorIndex(x);
    return r;
  }

  /**
   * This method parses the specified string into a date.
   * 
   * @param dateStr The date string to parse.
   * @param pos The input and output parse position
   *
   * @return The parsed date, or <code>null</code> if the string cannot be
   * parsed.
   */
  public Date parse (String dateStr, ParsePosition pos)
  {
    int fmt_index = 0;
    int fmt_max = pattern.length();

    calendar.clear();
    boolean saw_timezone = false;
    int quote_start = -1;
    boolean is2DigitYear = false;
    try
      {
	for (; fmt_index < fmt_max; ++fmt_index)
	  {
	    char ch = pattern.charAt(fmt_index);
	    if (ch == '\'')
	      {
		int index = pos.getIndex();
		if (fmt_index < fmt_max - 1
		    && pattern.charAt(fmt_index + 1) == '\'')
		  {
		    if (! expect (dateStr, pos, ch))
		      return null;
		    ++fmt_index;
		  }
		else
		  quote_start = quote_start < 0 ? fmt_index : -1;
		continue;
	      }
	    
	    if (quote_start != -1
		|| ((ch < 'a' || ch > 'z')
		    && (ch < 'A' || ch > 'Z')))
	      {
		if (! expect (dateStr, pos, ch))
		  return null;
		continue;
	      }
	    
	    // We've arrived at a potential pattern character in the
	    // pattern.
	    int fmt_count = 1;
	    while (++fmt_index < fmt_max && pattern.charAt(fmt_index) == ch)
	      {
		++fmt_count;
	      }
	    
	    // We might need to limit the number of digits to parse in
	    // some cases.  We look to the next pattern character to
	    // decide.
	    boolean limit_digits = false;
	    if (fmt_index < fmt_max
		&& standardChars.indexOf(pattern.charAt(fmt_index)) >= 0)
	      limit_digits = true;
	    --fmt_index;
	    
	    // We can handle most fields automatically: most either are
	    // numeric or are looked up in a string vector.  In some cases
	    // we need an offset.  When numeric, `offset' is added to the
	    // resulting value.  When doing a string lookup, offset is the
	    // initial index into the string array.
	    int calendar_field;
	    boolean is_numeric = true;
	    int offset = 0;
	    boolean maybe2DigitYear = false;
	    boolean oneBasedHour = false;
	    boolean oneBasedHourOfDay = false;
	    Integer simpleOffset;
	    String[] set1 = null;
	    String[] set2 = null;
	    switch (ch)
	      {
	      case 'd':
		calendar_field = Calendar.DATE;
		break;
	      case 'D':
		calendar_field = Calendar.DAY_OF_YEAR;
		break;
	      case 'F':
		calendar_field = Calendar.DAY_OF_WEEK_IN_MONTH;
		break;
	      case 'E':
		is_numeric = false;
		offset = 1;
		calendar_field = Calendar.DAY_OF_WEEK;
		set1 = formatData.getWeekdays();
		set2 = formatData.getShortWeekdays();
		break;
	      case 'w':
		calendar_field = Calendar.WEEK_OF_YEAR;
		break;
	      case 'W':
		calendar_field = Calendar.WEEK_OF_MONTH;
		break;
	      case 'M':
		calendar_field = Calendar.MONTH;
		if (fmt_count <= 2)
		  offset = -1;
		else
		  {
		    is_numeric = false;
		    set1 = formatData.getMonths();
		    set2 = formatData.getShortMonths();
		  }
		break;
	      case 'y':
		calendar_field = Calendar.YEAR;
		if (fmt_count <= 2)
		  maybe2DigitYear = true;
		break;
	      case 'K':
		calendar_field = Calendar.HOUR;
		break;
	      case 'h':
		calendar_field = Calendar.HOUR;
		oneBasedHour = true;
		break;
	      case 'H':
		calendar_field = Calendar.HOUR_OF_DAY;
		break;
	      case 'k':
		calendar_field = Calendar.HOUR_OF_DAY;
		oneBasedHourOfDay = true;
		break;
	      case 'm':
		calendar_field = Calendar.MINUTE;
		break;
	      case 's':
		calendar_field = Calendar.SECOND;
		break;
	      case 'S':
		calendar_field = Calendar.MILLISECOND;
		break;
	      case 'a':
		is_numeric = false;
		calendar_field = Calendar.AM_PM;
		set1 = formatData.getAmPmStrings();
		break;
	      case 'z':
	      case 'Z':
		// We need a special case for the timezone, because it
		// uses a different data structure than the other cases.
		is_numeric = false;
		calendar_field = Calendar.ZONE_OFFSET;
		String[][] zoneStrings = formatData.getZoneStrings();
		int zoneCount = zoneStrings.length;
		int index = pos.getIndex();
		boolean found_zone = false;
		simpleOffset = computeOffset(dateStr.substring(index));
		if (simpleOffset != null)
		  {
		    found_zone = true;
		    saw_timezone = true;
		    calendar.set(Calendar.DST_OFFSET, 0);
		    offset = simpleOffset.intValue();
		  }
		else
		  {
		    for (int j = 0;  j < zoneCount;  j++)
		      {
			String[] strings = zoneStrings[j];
			int k;
			for (k = 0; k < strings.length; ++k)
			  {
			    if (dateStr.startsWith(strings[k], index))
			      break;
			  }
			if (k != strings.length)
			  {
			    found_zone = true;
			    saw_timezone = true;
			    TimeZone tz = TimeZone.getTimeZone (strings[0]);
			    // Check if it's a DST zone or ordinary 
			    if(k == 3 || k == 4)
			      calendar.set (Calendar.DST_OFFSET, tz.getDSTSavings());
			    else
			      calendar.set (Calendar.DST_OFFSET, 0);
                            offset = tz.getRawOffset ();
			    pos.setIndex(index + strings[k].length());
			    break;
			  }
		      }
		  }
		if (! found_zone)
		  {
			pos.setErrorIndex(pos.getIndex());
			return null;
		  }
		break;
	      default:
		pos.setErrorIndex(pos.getIndex());
		return null;
	      }
      
	    // Compute the value we should assign to the field.
	    int value;
	    int index = -1;
	    if (is_numeric)
	      {
		numberFormat.setMinimumIntegerDigits(fmt_count);
		if (limit_digits)
		  numberFormat.setMaximumIntegerDigits(fmt_count);
		if (maybe2DigitYear)
		  index = pos.getIndex();
		Number n = numberFormat.parse(dateStr, pos);
		if (pos == null || ! (n instanceof Long))
		  return null;
		value = n.intValue() + offset;
	      }
	    else if (set1 != null)
	      {
		index = pos.getIndex();
		int i;
		boolean found = false;
		for (i = offset; i < set1.length; ++i)
		  {
		    if (set1[i] != null)
		      if (dateStr.toUpperCase().startsWith(set1[i].toUpperCase(),
							   index))
			{
			  found = true;
			  pos.setIndex(index + set1[i].length());
			  break;
			}
		  }
		if (!found && set2 != null)
		  {
		    for (i = offset; i < set2.length; ++i)
		      {
			if (set2[i] != null)
			  if (dateStr.toUpperCase().startsWith(set2[i].toUpperCase(),
							       index))
			    {
			      found = true;
			      pos.setIndex(index + set2[i].length());
			      break;
			    }
		      }
		  }
		if (!found)
		  {
		    pos.setErrorIndex(index);
		    return null;
		  }
		value = i;
	      }
	    else
	      value = offset;
	  
	    if (maybe2DigitYear)
	      {
		// Parse into default century if the numeric year string has 
		// exactly 2 digits.
		int digit_count = pos.getIndex() - index;
		if (digit_count == 2)
		  {
		    is2DigitYear = true;
		    value += defaultCentury;
		  }
	      }
	    
	    // Calendar uses 0-based hours. 
	    // I.e. 00:00 AM is midnight, not 12 AM or 24:00
	    if (oneBasedHour && value == 12)
	      value = 0;

	    if (oneBasedHourOfDay && value == 24)
	      value = 0;
	    
	    // Assign the value and move on.
	    calendar.set(calendar_field, value);
	  }
    
	if (is2DigitYear)
	  {
	    // Apply the 80-20 heuristic to dermine the full year based on 
	    // defaultCenturyStart. 
	    int year = calendar.get(Calendar.YEAR);
	    if (calendar.getTime().compareTo(defaultCenturyStart) < 0)
	      calendar.set(Calendar.YEAR, year + 100);      
	  }
	if (! saw_timezone)
	  {
	    // Use the real rules to determine whether or not this
	    // particular time is in daylight savings.
	    calendar.clear (Calendar.DST_OFFSET);
	    calendar.clear (Calendar.ZONE_OFFSET);
	  }
        return calendar.getTime();
      }
    catch (IllegalArgumentException x)
      {
        pos.setErrorIndex(pos.getIndex());
	return null;
      }
      }

  /**
   * <p>
   * Computes the time zone offset in milliseconds
   * relative to GMT, based on the supplied
   * <code>String</code> representation.
   * </p>
   * <p>
   * The supplied <code>String</code> must be a three
   * or four digit signed number, with an optional 'GMT'
   * prefix.  The first one or two digits represents the hours,
   * while the last two represent the minutes.  The
   * two sets of digits can optionally be separated by
   * ':'.  The mandatory sign prefix (either '+' or '-')
   * indicates the direction of the offset from GMT.
   * </p>
   * <p>
   * For example, 'GMT+0200' specifies 2 hours after
   * GMT, while '-05:00' specifies 5 hours prior to
   * GMT.  The special case of 'GMT' alone can be used
   * to represent the offset, 0.
   * </p>
   * <p>
   * If the <code>String</code> can not be parsed,
   * the result will be null.  The resulting offset
   * is wrapped in an <code>Integer</code> object, in
   * order to allow such failure to be represented.
   * </p>
   *
   * @param zoneString a string in the form 
   *        (GMT)? sign hours : minutes
   *        where sign = '+' or '-', hours
   *        is a one or two digits representing
   *        a number between 0 and 23, and
   *        minutes is two digits representing
   *        a number between 0 and 59.
   * @return the parsed offset, or null if parsing
   *         failed.
   */
  private Integer computeOffset(String zoneString)
  {
    Pattern pattern =
      Pattern.compile("(GMT)?([+-])([012])?([0-9]):?([0-9]{2})");
    Matcher matcher = pattern.matcher(zoneString);
    if (matcher.matches())
      {
	int sign = matcher.group(2).equals("+") ? 1 : -1;
	int hour = (Integer.parseInt(matcher.group(3)) * 10)
	  + Integer.parseInt(matcher.group(4));
	int minutes = Integer.parseInt(matcher.group(5));

	if (hour > 23)
	  return null;

	int offset = sign * ((hour * 60) + minutes) * 60000;
	return new Integer(offset);
      }
    else if (zoneString.startsWith("GMT"))
      {
	return new Integer(0);
      }
    return null;
  }

  // Compute the start of the current century as defined by
  // get2DigitYearStart.
  private void computeCenturyStart()
  {
    int year = calendar.get(Calendar.YEAR);
    calendar.set(Calendar.YEAR, year - 80);
    set2DigitYearStart(calendar.getTime());
  }

  /**
   * Returns a copy of this instance of
   * <code>SimpleDateFormat</code>.  The copy contains
   * clones of the formatting symbols and the 2-digit
   * year century start date.
   */
  public Object clone()
  {
    SimpleDateFormat clone = (SimpleDateFormat) super.clone();
    clone.setDateFormatSymbols((DateFormatSymbols) formatData.clone());
    clone.set2DigitYearStart((Date) defaultCenturyStart.clone());
    return clone;
  }

}
