/*
 * 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.client;

import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.core.client.JsArrayString;

import java.util.Date;

/**
 * The TimeZone class implements a time zone information source for client
 * applications. The time zone object is instantiated from a TimeZoneData object,
 * which is made from a JSON string that contains all the data needed for
 * the specified time zone. Applications can instantiate a time zone statically,
 * in which case the data could be retrieved from
 * the {@link com.google.gwt.i18n.client.constants.TimeZoneConstants TimeZoneConstants}
 * class. Applications can also choose to instantiate from a string obtained
 * from a server. The time zone string contains locale specific data. If the 
 * application only uses a short representation, the English data will usually
 * satisfy the user's need. In the case that only the time zone offset is known, 
 * there is a decent fallback that only uses the time zone offset to create a
 * TimeZone object.
 */
public class TimeZone {  
  // constants to reference time zone names in the time zone names array
  private static final int STD_SHORT_NAME = 0;
  private static final int STD_LONG_NAME = 1;
  private static final int DLT_SHORT_NAME = 2;
  private static final int DLT_LONG_NAME = 3;

  /**
   * This factory method creates a time zone instance from a JSON string that
   * contains the time zone information for desired time zone. Applications can
   * get such a string from the TimeZoneConstants class, or it can request the
   * string from the server. Either way, the application obtains the original
   * string from the data provided in the TimeZoneConstant.properties file,
   * which was carefully prepared from CLDR and Olson time zone database.
   * 
   * @param tzJSON JSON string that contains time zone data.
   * @return a new time zone object. 
   */
  public static TimeZone createTimeZone(String tzJSON) {
    TimeZoneInfo tzData = TimeZoneInfo.buildTimeZoneData(tzJSON);
    
    return createTimeZone(tzData);
  }

  public static TimeZone createTimeZone(TimeZoneInfo timezoneData) {
    TimeZone tz = new TimeZone();

    tz.timezoneID = timezoneData.getID();
    tz.standardOffset = -timezoneData.getStandardOffset();
    
    JsArrayString jsTimezoneNames = timezoneData.getNames();
    
    tz.tzNames = new String[jsTimezoneNames.length()];
    
    for (int i = 0; i < jsTimezoneNames.length(); i++) {
      tz.tzNames[i] = jsTimezoneNames.get(i);
    }

    JsArrayInteger transitions = timezoneData.getTransitions();    

    if (transitions == null || transitions.length() == 0) {
      tz.transitionPoints = null;
      tz.adjustments = null;
    } else {
      int transitionNum = transitions.length() / 2;
      tz.transitionPoints = new int[transitionNum];
      tz.adjustments = new int[transitionNum];

      for (int i = 0; i < transitionNum; ++i) {
        tz.transitionPoints[i] = transitions.get(i * 2);
        tz.adjustments[i] = transitions.get(i * 2 + 1);
      }
    }
    return tz;
  }

  /**
   * This factory method provides a decent fallback to create a time zone object
   * just based on a given time zone offset.
   * 
   * @param timeZoneOffsetInMinutes time zone offset in minutes.
   * @return a new time zone object.
   */
  public static TimeZone createTimeZone(int timeZoneOffsetInMinutes) {
    TimeZone tz = new TimeZone();
    tz.standardOffset = timeZoneOffsetInMinutes;
    tz.timezoneID = composePOSIXTimeZoneID(timeZoneOffsetInMinutes);
    tz.tzNames = new String[2]; 
    tz.tzNames[0] = composeUTCString(timeZoneOffsetInMinutes);
    tz.tzNames[1] = composeUTCString(timeZoneOffsetInMinutes);
    tz.transitionPoints = null;
    tz.adjustments = null;
    return tz;
  }

  /**
   * In GMT representation, +/- has reverse sign of time zone offset.
   * when offset == 480, it should output GMT-08:00.
   */
  private static String composeGMTString(int offset) {
    char data[] = {'G', 'M', 'T', '-', '0', '0', ':', '0', '0'};
    if (offset <= 0) {
      data[3] = '+';
      offset = -offset; // suppress the '-' sign for text display.
    }
    data[4] += (offset / 60) / 10;
    data[5] += (offset / 60) % 10;
    data[7] += (offset % 60) / 10;
    data[8] += offset % 10;
    return new String(data);
  }

  /** 
   * POSIX time zone ID as fallback. 
   */
  private static String composePOSIXTimeZoneID(int offset) {
    if (offset == 0) {
      return "Etc/GMT";
    }
    String str;
    if (offset < 0) {
      offset = -offset;
      str = "Etc/GMT-";
    } else {
      str = "Etc/GMT+";
    }
    return str + offsetDisplay(offset);
  }

  private static String composeUTCString(int offset) {
    if (offset == 0) {
      return "UTC";
    }
    String str;
    if (offset < 0) {
      offset = -offset;
      str = "UTC+";
    } else {
      str = "UTC-";
    }
    return str + offsetDisplay(offset);
  }
  
  private static String offsetDisplay(int offset) {
    int hour = offset / 60;
    int mins = offset % 60;
    if (mins == 0) {
      return Integer.toString(hour);
    }
    return Integer.toString(hour) + ":" + Integer.toString(mins);
  }

  private String timezoneID;
  private int standardOffset;
  private String[] tzNames;
  private int[] transitionPoints;
  private int[]  adjustments;

  private TimeZone() {
  }

  /**
   * Return the daylight savings time adjustment, in minutes, for the given
   * date. If daylight savings time is in effect on the given date, the number
   * will be positive, otherwise 0.
   * 
   * @param date the date to check.
   * @return offset amount.
   */
  public int getDaylightAdjustment(Date date) {
    if (transitionPoints == null) {
      return 0;
    }
    long timeInHours = date.getTime() / 1000 / 3600;
    int index = 0;
    while (index < transitionPoints.length && 
        timeInHours >= transitionPoints[index]) {
      ++index;
    }
    return (index == 0) ? 0 : adjustments[index - 1];
  }

  /**
   * Return the GMT representation of this time zone object.
   * 
   * @param date The date from which the time information should be extracted
   * @return A GMT representation of the time given by the date.
   */
  public String getGMTString(Date date) {
    return composeGMTString(getOffset(date));
  }

  /**
   * Return time zone id for this time zone. For time zone objects that have
   * been instantiated from a time zone offset, the POSIX time zone id will be
   * returned.
   * 
   * @return time zone id.
   */
  public String getID() {
    return timezoneID;
  }

  /**
   * Returns the long version of the time zone name for the given date; the
   * result of this method will be different if daylight savings time is in
   * effect.
   * 
   * @param date The date for which the long time zone name is returned
   * @return long time zone name.
   */
  public String getLongName(Date date) {
    return tzNames[isDaylightTime(date) ? DLT_LONG_NAME : STD_LONG_NAME]; 
  }

  /**
   * Returns the RFC representation of the time zone name for the given date.
   * To be consistent with JDK/Javascript API, west of Greenwich will be
   * positive.
   * 
   *  @param date The date for which time to retrieve time zone offset.
   *  @return time zone offset in minutes. 
   */
  public int getOffset(Date date) {
    return standardOffset - getDaylightAdjustment(date);
  }

  /**
   * To get RFC representation of certain time zone name for given date.
   * @param date The date for which time to retrieve RFC time zone string.
   * @return RFC time zone string.
   */
  public String getRFCTimeZoneString(Date date) {
    int offset = -getOffset(date);
    char data[] = {'+', '0', '0', '0', '0'};
    if (offset < 0) {
      data[0] = '-';
      offset = -offset; // suppress the '-' sign for text display.
    }
    data[1] += (offset / 60) / 10;
    data[2] += (offset / 60) % 10;
    data[3] += (offset % 60) / 10;
    data[4] += offset % 10;
    return new String(data);
  }

  /**
   * Returns the short time zone name for a given date.
   * 
   * @param date The date for which time to retrieve short time zone.
   * @return short time zone name.
   */
  public String getShortName(Date date) {
    return tzNames[isDaylightTime(date) ? DLT_SHORT_NAME : STD_SHORT_NAME]; 
  }

  /**
   * Returns the standard time zone offset in minutes.
   * 
   * @return the standard time zone offset, in minutes
   */
  public int getStandardOffset() {
    return standardOffset;
  }

  /**
   * Check whether the given date and time falls within a daylight savings time
   * period
   * 
   * @param date and time to check.
   * @return true if daylight savings time is in effect.
   */
  public boolean isDaylightTime(Date date) {
    return getDaylightAdjustment(date) > 0;
  }
}
