/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.i18n.shared.impl;

import java.util.Date;

/**
 * Implementation detail of DateTimeFormat -- not a public API and subject to
 * change.
 * 
 * DateRecord class exposes almost the same set of interface as Date class with
 * only a few exceptions. The main purpose is the record all the information
 * during parsing phase and resolve them in a later time when all information
 * can be processed together.
 */
@SuppressWarnings("deprecation")
public class DateRecord extends Date {

  /*
   * The serial version UID is only defined because this class is implicitly
   * serializable, causing warnings due to its absence. It will generally not be
   * used.
   */
  private static final long serialVersionUID = -1278816193740448162L;

  public static final int AM = 0;
  public static final int PM = 1;

  private static final int JS_START_YEAR = 1900;

  private int era;
  private int year;
  private int month;
  private int dayOfMonth;
  private int ampm;
  private int hours;
  private int minutes;
  private int seconds;
  private int milliseconds;

  private int tzOffset;
  private int dayOfWeek;
  private boolean ambiguousYear;

  /**
   * Initialize DateExt object with default value. Here we use -1 for most of
   * the field to indicate that field is not set.
   */
  public DateRecord() {
    era = -1;
    ambiguousYear = false;
    year = Integer.MIN_VALUE;
    month = -1;
    dayOfMonth = -1;
    ampm = -1;
    hours = -1;
    minutes = -1;
    seconds = -1;
    milliseconds = -1;
    dayOfWeek = -1;
    tzOffset = Integer.MIN_VALUE;
  }

  /**
   * calcDate uses all the field available so far to fill a Date object. For
   * those information that is not provided, the existing value in 'date' will
   * be kept. Ambiguous year will be resolved after the date/time values are
   * resolved.
   * 
   * If the strict option is set to true, calcDate will calculate certain
   * invalid dates by wrapping around as needed. For example, February 30 will
   * wrap to March 2.
   * 
   * @param date The Date object being filled. Its value should be set to an
   *          acceptable default before pass in to this method
   * @param strict true to be strict when parsing
   * @return true if successful, otherwise false.
   */
  public boolean calcDate(Date date, boolean strict) {
    // Year 0 is 1 BC, and so on.
    if (this.era == 0 && this.year > 0) {
      this.year = -(this.year - 1);
    }

    if (this.year > Integer.MIN_VALUE) {
      date.setYear(this.year - JS_START_YEAR);
    }

    // "setMonth" and "setDate" is a little bit tricky. Suppose content in
    // date is 11/30, switch month to 02 will lead to 03/02 since 02/30 does
    // not exist. And you certain won't like 02/12 turn out to be 03/12. So
    // here to set date to a smaller number before month, and later setMonth.
    // Real date is set after, and that might cause month switch. However,
    // that's desired.
    int orgDayOfMonth = date.getDate();
    date.setDate(1);

    if (this.month >= 0) {
      date.setMonth(this.month);
    }

    if (this.dayOfMonth >= 0) {
      date.setDate(this.dayOfMonth);
    } else if (this.month >= 0) {
      // If the month was parsed but dayOfMonth was not, then the current day of
      // the month shouldn't affect the parsed month. For example, if "Feb2006"
      // is parse on January 31, the resulting date should be in February, not
      // March. So, we limit the day of the month to the maximum day within the
      // parsed month.
      Date tmp = new Date(date.getYear(), date.getMonth(), 35);
      int daysInCurrentMonth = 35 - tmp.getDate();
      date.setDate(Math.min(daysInCurrentMonth, orgDayOfMonth));
    } else {
      date.setDate(orgDayOfMonth);
    }

    // adjust ampm
    if (this.hours < 0) {
      this.hours = date.getHours();
    }

    if (this.ampm > 0) {
      if (this.hours < 12) {
        this.hours += 12;
      }
    }
    date.setHours(this.hours);

    if (this.minutes >= 0) {
      date.setMinutes(this.minutes);
    }

    if (this.seconds >= 0) {
      date.setSeconds(this.seconds);
    }

    if (this.milliseconds >= 0) {
      date.setTime(date.getTime() / 1000 * 1000 + this.milliseconds);
    }

    // If strict, verify that the original date fields match the calculated date
    // fields. We do this before we set the timezone offset, which will skew all
    // of the dates.
    //
    // We don't need to check the day of week as it is guaranteed to be correct
    // or return false below.
    if (strict) {
      if ((this.year > Integer.MIN_VALUE)
          && ((this.year - JS_START_YEAR) != date.getYear())) {
        return false;
      }
      if ((this.month >= 0) && (this.month != date.getMonth())) {
        return false;
      }
      if ((this.dayOfMonth >= 0) && (this.dayOfMonth != date.getDate())) {
        return false;
      }
      // Times have well defined maximums
      if (this.hours >= 24) {
        return false;
      }
      if (this.minutes >= 60) {
        return false;
      }
      if (this.seconds >= 60) {
        return false;
      }
      if (this.milliseconds >= 1000) {
        return false;
      }
    }

    // Resolve ambiguous year if needed.
    if (this.ambiguousYear) { // the two-digit year == the default start year
      Date defaultCenturyStart = new Date();
      defaultCenturyStart.setYear(defaultCenturyStart.getYear() - 80);
      if (date.before(defaultCenturyStart)) {
        date.setYear(defaultCenturyStart.getYear() + 100);
      }
    }

    // Date is resolved to the nearest dayOfWeek if date is not explicitly
    // specified. There is one exception, if the nearest dayOfWeek falls
    // into a different month, the 2nd nearest dayOfWeek, which is on the
    // other direction, will be used.
    if (this.dayOfWeek >= 0) {
      if (this.dayOfMonth == -1) {
        // Adjust to the nearest day of the week.
        int adjustment = (7 + this.dayOfWeek - date.getDay()) % 7;
        if (adjustment > 3) {
          adjustment -= 7;
        }
        int orgMonth = date.getMonth();
        date.setDate(date.getDate() + adjustment);

        // If the nearest weekday fall into a different month, we will use the
        // 2nd nearest weekday, which will be on the other direction, and is
        // sure fall into the same month.
        if (date.getMonth() != orgMonth) {
          date.setDate(date.getDate() + (adjustment > 0 ? -7 : 7));
        }
      } else {
        if (date.getDay() != this.dayOfWeek) {
          return false;
        }
      }
    }

    // Adjust time zone.
    if (this.tzOffset > Integer.MIN_VALUE) {
      int offset = date.getTimezoneOffset();
      date.setTime(date.getTime() + (this.tzOffset - offset) * 60 * 1000);
      // HBJ date.setTime(date.getTime() + this.tzOffset * 60 * 1000);
    }

    return true;
  }

  /**
   * Set ambiguous year field. This flag indicates that a 2 digit years's
   * century need to be determined by its date/time value. This can only be
   * resolved after its date/time is known.
   * 
   * @param ambiguousYear true if it is ambiguous year.
   */
  public void setAmbiguousYear(boolean ambiguousYear) {
    this.ambiguousYear = ambiguousYear;
  }

  /**
   * Set morning/afternoon field.
   * 
   * @param ampm ampm value.
   */
  public void setAmpm(int ampm) {
    this.ampm = ampm;
  }

  /**
   * Set dayOfMonth field.
   * 
   * @param day dayOfMonth value
   */
  public void setDayOfMonth(int day) {
    this.dayOfMonth = day;
  }

  /**
   * Set dayOfWeek field.
   * 
   * @param dayOfWeek day of the week.
   */
  public void setDayOfWeek(int dayOfWeek) {
    this.dayOfWeek = dayOfWeek;
  }

  /**
   * Set Era field.
   * 
   * @param era era value being set.
   */
  public void setEra(int era) {
    this.era = era;
  }

  /**
   * Set hour field.
   * 
   * @param hours hour value.
   */
  @Override
  public void setHours(int hours) {
    this.hours = hours;
  }

  /**
   * Set milliseconds field.
   * 
   * @param milliseconds milliseconds value.
   */
  public void setMilliseconds(int milliseconds) {
    this.milliseconds = milliseconds;
  }

  /**
   * Set minute field.
   * 
   * @param minutes minute value.
   */
  @Override
  public void setMinutes(int minutes) {
    this.minutes = minutes;
  }

  /**
   * Set month field.
   * 
   * @param month month value.
   */
  @Override
  public void setMonth(int month) {
    this.month = month;
  }

  /**
   * Set seconds field.
   * 
   * @param seconds second value.
   */
  @Override
  public void setSeconds(int seconds) {
    this.seconds = seconds;
  }

  /**
   * Set timezone offset, in minutes.
   * 
   * @param tzOffset timezone offset.
   */
  public void setTzOffset(int tzOffset) {
    this.tzOffset = tzOffset;
  }

  /**
   * Set year field.
   * 
   * @param value year value.
   */
  @Override
  public void setYear(int value) {
    this.year = value;
  }
}
