package jxl.write.biff;

import common.Logger;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import jxl.Cell;
import jxl.CellType;
import jxl.DateCell;
import jxl.biff.DoubleHelper;
import jxl.biff.Type;
import jxl.format.CellFormat;
import jxl.write.DateFormats;
import jxl.write.WritableCellFormat;

public abstract class DateRecord extends CellValue {
  private static Logger logger = Logger.getLogger(DateRecord.class);
  
  private double value;
  
  private Date date;
  
  private boolean time;
  
  private static final int utcOffsetDays = 25569;
  
  private static final long msInADay = 86400000L;
  
  static final WritableCellFormat defaultDateFormat = new WritableCellFormat(DateFormats.DEFAULT);
  
  private static final int nonLeapDay = 61;
  
  protected static final class GMTDate {}
  
  protected DateRecord(int c, int r, Date d) {
    this(c, r, d, (CellFormat)defaultDateFormat, true);
  }
  
  protected DateRecord(int c, int r, Date d, GMTDate a) {
    this(c, r, d, (CellFormat)defaultDateFormat, false);
  }
  
  protected DateRecord(int c, int r, Date d, CellFormat st) {
    super(Type.NUMBER, c, r, st);
    this.date = d;
    calculateValue(true);
  }
  
  protected DateRecord(int c, int r, Date d, CellFormat st, GMTDate a) {
    super(Type.NUMBER, c, r, st);
    this.date = d;
    calculateValue(false);
  }
  
  protected DateRecord(int c, int r, Date d, CellFormat st, boolean tim) {
    super(Type.NUMBER, c, r, st);
    this.date = d;
    this.time = tim;
    calculateValue(false);
  }
  
  protected DateRecord(DateCell dc) {
    super(Type.NUMBER, (Cell)dc);
    this.date = dc.getDate();
    this.time = dc.isTime();
    calculateValue(false);
  }
  
  protected DateRecord(int c, int r, DateRecord dr) {
    super(Type.NUMBER, c, r, dr);
    this.value = dr.value;
    this.time = dr.time;
    this.date = dr.date;
  }
  
  private void calculateValue(boolean adjust) {
    long zoneOffset = 0L;
    long dstOffset = 0L;
    if (adjust) {
      Calendar cal = Calendar.getInstance();
      cal.setTime(this.date);
      zoneOffset = cal.get(15);
      dstOffset = cal.get(16);
    } 
    long utcValue = this.date.getTime() + zoneOffset + dstOffset;
    double utcDays = utcValue / 8.64E7D;
    this.value = utcDays + 25569.0D;
    if (!this.time && this.value < 61.0D)
      this.value--; 
    if (this.time)
      this.value -= (int)this.value; 
  }
  
  public CellType getType() {
    return CellType.DATE;
  }
  
  public byte[] getData() {
    byte[] celldata = super.getData();
    byte[] data = new byte[celldata.length + 8];
    System.arraycopy(celldata, 0, data, 0, celldata.length);
    DoubleHelper.getIEEEBytes(this.value, data, celldata.length);
    return data;
  }
  
  public String getContents() {
    return this.date.toString();
  }
  
  protected void setDate(Date d) {
    this.date = d;
    calculateValue(true);
  }
  
  protected void setDate(Date d, GMTDate a) {
    this.date = d;
    calculateValue(false);
  }
  
  public Date getDate() {
    return this.date;
  }
  
  public boolean isTime() {
    return this.time;
  }
  
  public DateFormat getDateFormat() {
    return null;
  }
}
