/* HTTPDateFormat.java --
   Copyright (C) 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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 gnu.java.net.protocol.http;

import java.text.DateFormat;
import java.text.DecimalFormat;
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.TimeZone;

/**
 * HTTP date formatter and parser.
 * Formats dates according to RFC 822 (updated by RFC 1123).
 * Parses dates according to the above, <i>or</i> RFC 1036, <i>or</i> the
 * ANSI C <code>asctime()</code> format.
 *
 * @author Chris Burdess (dog@gnu.org)
 */
public class HTTPDateFormat
  extends DateFormat
{

  static final String[] DAYS_OF_WEEK = {
    null, "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  };

  static final String[] MONTHS = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  };

  public HTTPDateFormat()
  {
    calendar = new GregorianCalendar(TimeZone.getTimeZone ("GMT"));
    numberFormat = new DecimalFormat();
  }

  /**
   * Appends the textual value for the specified field to the given string
   * buffer. This method should be avoided, use <code>format(Date)</code>
   * instead.
   * @param date the Date object
   * @param buf the buffer to append to
   * @param field the current field position
   * @return the modified buffer
   */
  public StringBuffer format(Date date, StringBuffer buf,
                             FieldPosition field)
  {
    calendar.clear();
    calendar.setTime(date);
    buf.setLength(0);

    // Day of week
    buf.append(DAYS_OF_WEEK[calendar.get(Calendar.DAY_OF_WEEK)]);
    buf.append(',');
    buf.append(' ');

    // Day of month
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    buf.append(Character.forDigit(day / 10, 10));
    buf.append(Character.forDigit(day % 10, 10));
    buf.append(' ');

    // Month
    buf.append(MONTHS[calendar.get(Calendar.MONTH)]);
    buf.append(' ');

    // Year
    int year = calendar.get(Calendar.YEAR);
    if (year < 1000)
      {
        buf.append('0');
        if (year < 100)
          {
            buf.append('0');
            if (year < 10)
              {
                buf.append('0');
              }
          }
      }
    buf.append(Integer.toString(year));
    buf.append(' ');

    // Hour
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    buf.append(Character.forDigit(hour / 10, 10));
    buf.append(Character.forDigit(hour % 10, 10));
    buf.append(':');

    // Minute
    int minute = calendar.get(Calendar.MINUTE);
    buf.append(Character.forDigit(minute / 10, 10));
    buf.append(Character.forDigit(minute % 10, 10));
    buf.append(':');

    // Second
    int second = calendar.get(Calendar.SECOND);
    buf.append(Character.forDigit(second / 10, 10));
    buf.append(Character.forDigit(second % 10, 10));
    buf.append(' ');

    // Timezone
    // Get time offset in minutes
    int zoneOffset =(calendar.get(Calendar.ZONE_OFFSET) +
                     calendar.get(Calendar.DST_OFFSET)) / 60000;
    
    // Apply + or - appropriately
    if (zoneOffset < 0)
      {
        zoneOffset = -zoneOffset;
        buf.append('-');
      }
    else
      {
        buf.append('+');
      }
    
    // Set the 2 2-char fields as specified above
    int tzhours = zoneOffset / 60;
    buf.append(Character.forDigit(tzhours / 10, 10));
    buf.append(Character.forDigit(tzhours % 10, 10));
    int tzminutes = zoneOffset % 60;
    buf.append(Character.forDigit(tzminutes / 10, 10));
    buf.append(Character.forDigit(tzminutes % 10, 10));

    field.setBeginIndex(0);
    field.setEndIndex(buf.length());
    return buf;
  }

  /**
   * Parses the given date in the current TimeZone.
   * @param text the formatted date to be parsed
   * @param pos the current parse position
   */
  public Date parse(String text, ParsePosition pos)
  {
    int date, month, year, hour, minute, second;
    String monthText;
    int start = 0, end = -1;
    int len = text.length();
    calendar.clear();
    pos.setIndex(start);
    try
      {
        // Advance to date
        if (Character.isLetter(text.charAt(start)))
          {
            start = skipNonWhitespace(text, start);
          }
        // Determine mode
        switch(start)
          {
          case 3:
            // asctime
            start = skipWhitespace(text, start);
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            monthText = text.substring(start, end);
            month = -1;
            for (int i = 0; i < 12; i++)
              {
                if (MONTHS[i].equals(monthText))
                  {
                    month = i;
                    break;
                  }
              }
            if (month == -1)
              {
                pos.setErrorIndex(end);
                return null;
              }
            // Advance to date
            start = skipWhitespace(text, end + 1);
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            date = Integer.parseInt(text.substring(start, end));
            // Advance to hour
            start = skipWhitespace(text, end + 1);
            pos.setIndex(start);
            end = skipTo(text, start + 1, ':');
            hour = Integer.parseInt(text.substring(start, end));
            // Advance to minute
            start = end + 1;
            pos.setIndex(start);
            end = skipTo(text, start + 1, ':');
            minute = Integer.parseInt(text.substring(start, end));
            // Advance to second
            start = end + 1;
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            second = Integer.parseInt(text.substring(start, end));
            // Advance to year
            start = skipWhitespace(text, end + 1);
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            year = Integer.parseInt(text.substring(start, end));
            break;
          case 0:
          case 4:
            // rfc822
            start = skipWhitespace(text, start);
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            date = Integer.parseInt(text.substring(start, end));
            // Advance to month
            start = skipWhitespace(text, end + 1);
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            monthText = text.substring(start, end);
            month = -1;
            for (int i = 0; i < 12; i++)
              {
                if (MONTHS[i].equals(monthText))
                  {
                    month = i;
                    break;
                  }
              }
            if (month == -1)
              {
                pos.setErrorIndex(end);
                return null;
              }
            // Advance to year
            start = skipWhitespace(text, end + 1);
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            year = Integer.parseInt(text.substring(start, end));
            // Advance to hour
            start = skipWhitespace(text, end + 1);
            pos.setIndex(start);
            end = skipTo(text, start + 1, ':');
            hour = Integer.parseInt(text.substring(start, end));
            // Advance to minute
            start = end + 1;
            pos.setIndex(start);
            end = skipTo(text, start + 1, ':');
            minute = Integer.parseInt(text.substring(start, end));
            // Advance to second
            start = end + 1;
            pos.setIndex(start);
            end = start + 1;
            while (end < len && !Character.isWhitespace(text.charAt(end)))
              {
                end++;
              }
            second = Integer.parseInt(text.substring(start, end));
            break;
          default:
            // rfc850(obsolete)
            start = skipWhitespace(text, start);
            pos.setIndex(start);
            end = skipTo(text, start + 1, '-');
            date = Integer.parseInt(text.substring(start, end));
            // Advance to month
            start = end + 1;
            pos.setIndex(start);
            end = skipTo(text, start + 1, '-');
            monthText = text.substring(start, end);
            month = -1;
            for (int i = 0; i < 12; i++)
              {
                if (MONTHS[i].equals(monthText))
                  {
                    month = i;
                    break;
                  }
              }
            if (month == -1)
              {
                pos.setErrorIndex(end);
                return null;
              }
            // Advance to year
            start = end + 1;
            pos.setIndex(start);
            end = skipNonWhitespace(text, start + 1);
            year = 1900 + Integer.parseInt(text.substring(start, end));
            // Advance to hour
            start = skipWhitespace(text, end + 1);
            pos.setIndex(start);
            end = skipTo(text, start + 1, ':');
            hour = Integer.parseInt(text.substring(start, end));
            // Advance to minute
            start = end + 1;
            pos.setIndex(start);
            end = skipTo(text, start + 1, ':');
            minute = Integer.parseInt(text.substring(start, end));
            // Advance to second
            start = end + 1;
            pos.setIndex(start);
            end = start + 1;
            while (end < len && !Character.isWhitespace(text.charAt(end)))
              {
                end++;
              }
            second = Integer.parseInt(text.substring(start, end));
          }
        
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, date);
        calendar.set(Calendar.HOUR, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        
        if (end != len)
          {
            // Timezone
            start = skipWhitespace(text, end + 1);
            end = start + 1;
            while (end < len && !Character.isWhitespace(text.charAt(end)))
              {
                end++;
              }
            char pm = text.charAt(start);
            if (Character.isLetter(pm))
              {
                TimeZone tz =
                  TimeZone.getTimeZone(text.substring(start, end));
                calendar.set(Calendar.ZONE_OFFSET, tz.getRawOffset());
              }
            else
              {
                int zoneOffset = 0;
                zoneOffset += 600 * Character.digit(text.charAt(++start), 10);
                zoneOffset += 60 * Character.digit(text.charAt(++start), 10);
                zoneOffset += 10 * Character.digit(text.charAt(++start), 10);
                zoneOffset += Character.digit(text.charAt(++start), 10);
                zoneOffset *= 60000; // minutes -> ms
                if ('-' == pm)
                  {
                    zoneOffset = -zoneOffset;
                  }
                calendar.set(Calendar.ZONE_OFFSET, zoneOffset);
              }
          }
        pos.setIndex(end);
        
        return calendar.getTime();
      }
    catch (NumberFormatException e)
      {
        pos.setErrorIndex(Math.max(start, end));
      }
    catch (StringIndexOutOfBoundsException e)
      {
        pos.setErrorIndex(Math.max(start, end));
      }
    return null;
  }

  private int skipWhitespace(String text, int pos)
  {
    while(Character.isWhitespace(text.charAt(pos)))
      {
        pos++;
      }
    return pos;    
  }

  private int skipNonWhitespace(String text, int pos)
  {
    while(!Character.isWhitespace(text.charAt(pos)))
      {
        pos++;
      }
    return pos;    
  }

  private int skipTo(String text, int pos, char c)
  {
    while(text.charAt(pos) != c)
      {
        pos++;
      }
    return pos;    
  }

  /**
   * Don't allow setting the calendar.
   */
  public void setCalendar(Calendar newCalendar)
  {
    throw new UnsupportedOperationException();
  }

  /**
   * Don't allow setting the NumberFormat.
   */
  public void setNumberFormat(NumberFormat newNumberFormat)
  {
    throw new UnsupportedOperationException();
  }

}

