/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package java.util;

public abstract class Calendar {

	protected long time;
	protected int[] fields;
	protected boolean[] isSet;
	
	boolean timeSet, fieldsSet;
	TimeZone zone;
	
	public static final int YEAR = 1;
	public static final int MONTH = 2;
	public static final int DATE = 5;
	public static final int DAY_OF_MONTH = 5;
	public static final int DAY_OF_WEEK = 7;
	public static final int AM_PM = 9;
	public static final int HOUR = 10;
	public static final int HOUR_OF_DAY = 11;
	public static final int MINUTE = 12;
	public static final int SECOND = 13;
	public static final int MILLISECOND = 14;

	public static final int SUNDAY = 1;
	public static final int MONDAY = 2;
	public static final int TUESDAY = 3;
	public static final int WEDNESDAY = 4;
	public static final int THRUSDAY = 5;
	public static final int FRIDAY = 6;
	public static final int SATURDAY = 7;

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

	public static final int JANUARY = 0;
	public static final int FEBRUARY = 1;
	public static final int MARCH = 2;
	public static final int APRIL = 3;
	public static final int MAY = 4;
	public static final int JUNE = 5;
	public static final int JULY = 6;
	public static final int AUGUST = 7;
	public static final int SEPTEMBER = 8;
	public static final int OCTOBER = 9;
	public static final int NOVEMBER = 10;
	public static final int DECEMBER = 11;
	
protected Calendar() {
	time = System.currentTimeMillis();
	timeSet = true;
}

public boolean after(Object when) {
	if (!(when instanceof Calendar)) return false;
	return getTimeInMillis() > ((Calendar)when).getTimeInMillis();
}

public boolean before(Object when) {
	if (!(when instanceof Calendar)) return false;
	return getTimeInMillis() < ((Calendar)when).getTimeInMillis();
}

protected abstract void computeFields();

protected abstract void computeTime();

public boolean equals(Object other) {
	if (other == this) return true;
	if (!(other instanceof Calendar)) return false;
	return getTimeInMillis() == ((Calendar)other).getTimeInMillis();
}

public final int get(int field) {
	if (!isSet[field]) {
		computeFields();
		fieldsSet = true;
	}
	return fields[field];
}

public static Calendar getInstance() {
	return getInstance(TimeZone.getDefault());
}

public static Calendar getInstance(TimeZone zone) {
	Calendar calendar = new GregorianCalendar();
	calendar.setTimeZone(zone);
	return calendar;
}

public final Date getTime() {
	return new Date(getTimeInMillis());
}

protected long getTimeInMillis() {
	if (!timeSet) computeTime();
	return time;
}

protected TimeZone getTimeZone() {
	return zone;
}

public final void set(int field, int value) {
	if (timeSet && !fieldsSet) {
		computeFields();
		fieldsSet = true;
	}
	fields[field] = value;
	isSet[field] = true;
	timeSet = false;
}

public final void setTime(Date date) {
	setTimeInMillis(date.getTime());
}

protected void setTimeInMillis(long millis) {
	time = millis;
	timeSet = true;
	fieldsSet = false;
	for (int i = 0; i < isSet.length; i++) {
		isSet[i] = false;
	}
}

public void setTimeZone(TimeZone zone) {
	//TODO 
//	if (!timeSet) computeTime();
//	timeSet = true;
//	this.zone = zone;
//	if (zone != null) time += zone.getRawOffset();
//	fieldsSet = false;
//	for (int i = 0; i < isSet.length; i++) {
//		isSet[i] = false;
//	}
}
}