/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.
 */

package org.apache.log4j.helpers;

import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Date;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.DateFormatSymbols;

/**
   Provides a localized {@link Date} String by prepending the date formatted
   as "dd MMM yyyy" to the time formatted according to the description in
   {@link AbsoluteTimeDateFormat}.

   @author Ceki G&uuml;lc&uuml;
   @since 0.7.5
*/
public class DateTimeDateFormat extends AbsoluteTimeDateFormat {

  String[] shortMonths;

  public
  DateTimeDateFormat() {
    this(TimeZone.getDefault(), Locale.getDefault());
  }

  public
  DateTimeDateFormat(TimeZone timeZone) {
    this(timeZone, Locale.getDefault());
  }

  public
  DateTimeDateFormat(Locale locale) {
    this(TimeZone.getDefault(),locale);
  }

  public
  DateTimeDateFormat(TimeZone timeZone, Locale locale) {
    super(timeZone, locale);
    shortMonths = new DateFormatSymbols(locale).getShortMonths();
    now = (Calendar)calendar.clone();
  }

  private static Calendar now;
  private static int      lastDate = 0;
  private static char[]   lastDateString = new char[12]; // "dd MMM yyyy "

  /**
     Appends to <code>sbuf</code> the date and time in
     "dd MMM yyyy HH:mm:ssdSSS" format, where "d" is the
     locale specific decimal separator.
     For example, "06 Nov 1994 15:49:37,459" for most
     European and East European countries, or 
     "06 Nov 1994 15:49:37.459" for most of the Americas,
     most of the Middle East and most of East Asia.

     @param sbuf the string buffer to write to
     @see AbsoluteTimeDateFormat
  */
  public
  StringBuffer format(Date date, StringBuffer sbuf,
		      FieldPosition fieldPosition) {

    now.setTime(date);

    // Created comparison date in yyyyDDD format
    int today = (1000 * now.get(Calendar.YEAR)) +
                now.get(Calendar.DAY_OF_YEAR);

    if (today == lastDate) {
      sbuf.append(lastDateString);
    }
    else {
      // We reach this point at most once per day
      // across all threads instead of each time format()
      // is called. This saves considerable CPU time.

      lastDate = today;

      int start = sbuf.length();

      int day = now.get(Calendar.DAY_OF_MONTH);
      if(day < 10)
        sbuf.append('0');
      sbuf.append(day);
      sbuf.append(' ');
      sbuf.append(shortMonths[now.get(Calendar.MONTH)]);
      sbuf.append(' ');

      int year =  now.get(Calendar.YEAR);
      sbuf.append(year);
      sbuf.append(' ');

      sbuf.getChars(start, sbuf.length(), lastDateString, 0);
    }

    // Add the time to the date string.
    return super.format(date, sbuf, fieldPosition);
  }

  /**
     This method does not do anything but return <code>null</code>.
   */
  public
  Date parse(java.lang.String s, ParsePosition pos) {
    return null;
  }
}
