/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package ganttChart;

import java.util.Date;
import java.util.TimeZone;

import ilog.views.gantt.IlvActivity;
import ilog.views.gantt.IlvDuration;
import ilog.views.gantt.property.IlvActivityFormattedDurationProperty;
import ilog.views.gantt.property.IlvStringProperty;
import ilog.views.gantt.text.IlvDurationFormat;

/**
 * <code>CalendarDurationProperty</code> is an adapter that allows the calendar
 * duration of an {@link IlvActivity} to be accessed via the generic
 * {@link IlvStringProperty} interface.
 */
public class CalendarDurationProperty extends IlvActivityFormattedDurationProperty {

  // =========================================
  // Instance Construction and Initialization
  // =========================================

  /**
   * Creates an <code>CalendarDurationProperty</code> with the specified
   * duration format.
   *
   * @param durationFormat
   *          The duration format.
   */
  public CalendarDurationProperty(IlvDurationFormat durationFormat) {
    super(durationFormat);
  }

  /**
   * Creates an <code>CalendarDurationProperty</code> with a default duration
   * format of {@link IlvDurationFormat#LARGEST_UNIT_MEDIUM}.
   */
  public CalendarDurationProperty() {
  }

  // =========================================
  // Accessing
  // =========================================

  /**
   * Returns the specified {@link IlvActivity}'s calendar duration.
   *
   * @param activity
   *          The activity.
   */
  Override
  protected Object getValueImpl(Object activity) {
    IlvActivity a = (IlvActivity) activity;
    IlvDuration duration = a.getTimeInterval().getDuration();
    // We need to know if the start and end dates are crossing the Daylight
    // Saving time, to adjust the duration in milliseconds.
    int delta = getDeltaDST(a.getStartTime(), a.getEndTime());
    if (delta != 0) {
      duration = duration.add(new IlvDuration(delta));
    }
    return duration;
  }

  /**
   * Sets the specified {@link IlvActivity}'s duration.
   *
   * @param activity
   *          The activity.
   * @param duration
   *          The activity's new duration.
   */
  Override
  protected void setValueImpl(Object activity, Object duration) {
    IlvActivity a = (IlvActivity) activity;
    IlvDuration d = (IlvDuration) duration;
    // We need to know if the start and end dates are crossing the Daylight
    // Saving time, to adjust the duration in milliseconds.
    Date start = a.getStartTime();
    Date end = d.add(start);
    int delta = getDeltaDST(start, end);
    if (delta != 0) {
      // Adjust the end date
      d = d.subtract(new IlvDuration(delta));
      end = d.add(start);
    }
    a.setEndTime(end);
  }

  // Return the number of milliseconds to add or remove when 2 dates are
  // crossing the Daylight Saving time.
  private int getDeltaDST(Date start, Date end) {
    TimeZone timeZone = TimeZone.getDefault();
    boolean isStartDST = timeZone.inDaylightTime(start);
    boolean isEndDST = timeZone.inDaylightTime(end);
    if (isStartDST != isEndDST) {
      int DSTSavings = timeZone.getDSTSavings();
      return isStartDST ? -DSTSavings : DSTSavings;
    } else {
      return 0;
    }
  }

}