/*******************************************************************************
 * Copyright (c) 2005, 2010 Andrea Bittau, University College London, 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:
 *     Andrea Bittau - initial API and implementation from the PsychoPath XPath 2.0
 *     Mukul Gandhi - bug 273760 - wrong namespace for functions and data types
 *     David Carver - bug 282223 - implementation of xs:duration data type.
 *                                 correction of casting to time. 
 *     David Carver - bug 280547 - fix dates for comparison 
 *     Jesper Steen Moller - bug 262765 - fix type tests
 *     Mukul Gandhi - bug 280798 - PsychoPath support for JDK 1.4
 *******************************************************************************/

package org.eclipse.wst.xml.xpath2.processor.internal.types;

import org.eclipse.wst.xml.xpath2.processor.DynamicContext;
import org.eclipse.wst.xml.xpath2.processor.DynamicError;
import org.eclipse.wst.xml.xpath2.processor.ResultSequence;
import org.eclipse.wst.xml.xpath2.processor.ResultSequenceFactory;
import org.eclipse.wst.xml.xpath2.processor.internal.function.CmpEq;
import org.eclipse.wst.xml.xpath2.processor.internal.function.CmpGt;
import org.eclipse.wst.xml.xpath2.processor.internal.function.CmpLt;
import org.eclipse.wst.xml.xpath2.processor.internal.function.MathMinus;
import org.eclipse.wst.xml.xpath2.processor.internal.function.MathPlus;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;

/**
 * A representation of the Time datatype
 */
public class XSTime extends CalendarType implements CmpEq, CmpLt, CmpGt,

MathMinus, MathPlus,

Cloneable {

	private static final String XS_TIME = "xs:time";
	private Calendar _calendar;
	private boolean _timezoned;
	private XSDuration _tz;

	/**
	 * Initialises to the supplied time and timezone
	 * 
	 * @param cal
	 *            Calendar representation of the time to be stored
	 * @param tz
	 *            The timezone (possibly null) associated with this time
	 */
	public XSTime(Calendar cal, XSDuration tz) {
		_calendar = cal;

		_tz = tz;
		if (tz == null)
			_timezoned = false;
		else
			_timezoned = true;
	}

	/**
	 * Initialises to the current time
	 */
	public XSTime() {
		this(new GregorianCalendar(TimeZone.getTimeZone("GMT")), null);
	}

	/**
	 * Creates a new copy of the time (and timezone) stored
	 * 
	 * @return New XSTime representing the copy of the time and timezone
	 * @throws CloneNotSupportedException
	 */
	public Object clone() throws CloneNotSupportedException {
		Calendar c = (Calendar) calendar().clone();
		XSDuration t = tz();

		if (t != null)
			t = (XSDuration) t.clone();

		return new XSTime(c, t);
	}

	/**
	 * Retrieves the datatype's name
	 * 
	 * @return "time" which is the datatype's name
	 */
	public String type_name() {
		return "time";
	}

	/**
	 * Creates a new XSTime representing the String represented supplied time
	 * 
	 * @param str
	 *            String represented time and timezone to be stored
	 * @return New XSTime representing the supplied time
	 */
	public static CalendarType parse_time(String str) {

		String startdate = "1983-11-29T";
		
		XSDateTime dt = XSDateTime.parseDateTime(startdate + str);
		if (dt == null)
			return null;

		return new XSTime(dt.calendar(), dt.tz());
	}

	/**
	 * Creates a new ResultSequence consisting of the extractable time from the
	 * supplied ResultSequence
	 * 
	 * @param arg
	 *            The ResultSequence from which to extract the time
	 * @return New ResultSequence consisting of the supplied time
	 * @throws DynamicError
	 */
	public ResultSequence constructor(ResultSequence arg) throws DynamicError {
		ResultSequence rs = ResultSequenceFactory.create_new();

		if (arg.empty())
			return rs;

		AnyAtomicType aat = (AnyAtomicType) arg.first();
		if (!isCastable(aat)) {
			throw DynamicError.invalidType();
		}

		
		CalendarType t = castTime(aat);

		if (t == null)
			throw DynamicError.cant_cast(null);

		rs.add(t);

		return rs;
	} 

	private boolean isCastable(AnyAtomicType aat) {
		if (aat instanceof XSString || aat instanceof XSUntypedAtomic) {
			return true;
		}
		
		if (aat instanceof XSDateTime) {
			return true;
		}
		
		if (aat instanceof XSTime) {
			return true;
		}
		return false;
	}
	
	private CalendarType castTime(AnyAtomicType aat) {
		if (aat instanceof XSTime) {
			XSTime time = (XSTime) aat;
			return new XSTime(time.calendar(), time.tz());
		}
		if (aat instanceof XSDateTime) {
			XSDateTime dateTime = (XSDateTime) aat;
			return new XSTime(dateTime.calendar(), dateTime.tz());
		}
		
		return parse_time(aat.string_value());
	}
	/**
	 * Retrieves the hour stored as an integer
	 * 
	 * @return The hour stored
	 */
	public int hour() {
		return _calendar.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * Retrieves the minute stored as an integer
	 * 
	 * @return The minute stored
	 */
	public int minute() {
		return _calendar.get(Calendar.MINUTE);
	}

	/**
	 * Retrieves the seconds stored as an integer
	 * 
	 * @return The second stored
	 */
	public double second() {
		double s = _calendar.get(Calendar.SECOND);

		double ms = _calendar.get(Calendar.MILLISECOND);

		ms /= 1000;

		s += ms;
		return s;
	}

	/**
	 * Check for whether the time stored has a timezone associated with it
	 * 
	 * @return True if the time has a timezone associated. False otherwise
	 */
	public boolean timezoned() {
		return _timezoned;
	}

	/**
	 * Retrieves a String representation of the time stored
	 * 
	 * @return String representation of the time stored
	 */
	public String string_value() {
		String ret = "";
		
		Calendar adjustFortimezone = calendar();
		ret += XSDateTime.pad_int(adjustFortimezone.get(Calendar.HOUR_OF_DAY), 2);
		
		ret += ":";
		ret += XSDateTime.pad_int(adjustFortimezone.get(Calendar.MINUTE), 2);
		

		ret += ":";
		int isecond = (int) second();
		double sec = second();

		if ((sec - (isecond)) == 0.0)
			ret += XSDateTime.pad_int(isecond, 2);
		else {
			if (sec < 10.0)
				ret += "0" + sec;
			else
				ret += sec;
		}

		if (timezoned()) {
			int hrs = _tz.hours();
			int min = _tz.minutes();
			double secs = _tz.seconds();
			if (hrs == 0 && min == 0 && secs == 0) {
			  ret += "Z";
			}
			else {
			  String tZoneStr = "";
			  if (_tz.negative()) {
				tZoneStr += "-";  
			  }
			  else {
				tZoneStr += "+"; 
			  }
			  tZoneStr += XSDateTime.pad_int(hrs, 2);  
			  tZoneStr += ":";
			  tZoneStr += XSDateTime.pad_int(min, 2);
			  
			  ret += tZoneStr;
			}
		}

		return ret;
	}

	/**
	 * Retrieves the datatype's full pathname
	 * 
	 * @return "xs:time" which is the datatype's full pathname
	 */
	public String string_type() {
		return XS_TIME;
	}

	/**
	 * Retrieves a Calendar representation of time stored
	 * 
	 * @return Calendar representation of the time stored
	 */
	public Calendar calendar() {
		return _calendar;
	}

	/**
	 * Retrieves the timezone associated with the time stored as a duration of
	 * time
	 * 
	 * @return The duration of time between the time stored and the actual time
	 *         after the timezone is taken into account
	 */
	public XSDuration tz() {
		return _tz;
	}

	/**
	 * Retrieves the time in milliseconds since the epoch
	 * 
	 * @return time stored in milliseconds since the epoch
	 */
	public double value() {
		return calendar().getTimeInMillis() / 1000.0;
	}

	/**
	 * Equality comparison between this and the supplied XSTime representation
	 * 
	 * @param arg
	 *            The XSTime to compare with
	 * @return True if both XSTime's represent the same time. False otherwise
	 * @throws DynamicError
	 */
	public boolean eq(AnyType arg, DynamicContext context) throws DynamicError {
		XSTime val = (XSTime) NumericType.get_single_type(arg, XSTime.class);
		Calendar thiscal = normalizeCalendar(calendar(), tz());
		Calendar thatcal = normalizeCalendar(val.calendar(), val.tz());

		return thiscal.equals(thatcal);
	}

	/**
	 * Comparison between this and the supplied XSTime representation
	 * 
	 * @param arg
	 *            The XSTime to compare with
	 * @return True if the supplied time represnts a point in time after that
	 *         represented by the time stored. False otherwise
	 */
	public boolean lt(AnyType arg, DynamicContext context) throws DynamicError {
		XSTime val = (XSTime) NumericType.get_single_type(arg, XSTime.class);
		Calendar thiscal = normalizeCalendar(calendar(), tz());
		Calendar thatcal = normalizeCalendar(val.calendar(), val.tz());
		return thiscal.before(thatcal);
	}
	
	/**
	 * Comparison between this and the supplied XSTime representation
	 * 
	 * @param arg
	 *            The XSTime to compare with
	 * @return True if the supplied time represnts a point in time before that
	 *         represented by the time stored. False otherwise
	 * @throws DynamicError
	 */
	public boolean gt(AnyType arg, DynamicContext context) throws DynamicError {
		XSTime val = (XSTime) NumericType.get_single_type(arg, XSTime.class);
		Calendar thiscal = normalizeCalendar(calendar(), tz());
		Calendar thatcal = normalizeCalendar(val.calendar(), val.tz());

		return thiscal.after(thatcal);
	}

	/**
	 * Mathematical subtraction between this time stored and the supplied
	 * representation. This supplied representation must be of either type
	 * XSTime (in which case the result is the duration of time between these
	 * two times) or a XSDayTimeDuration (in which case the result is the time
	 * when this duration is subtracted from the time stored).
	 * 
	 * @param arg
	 *            The representation to subtract (either XSTim or
	 *            XDTDayTimeDuration)
	 * @return A ResultSequence representing the result of the subtraction
	 */
	public ResultSequence minus(ResultSequence arg) throws DynamicError {
		if (arg.size() != 1)
			DynamicError.throw_type_error();

		AnyType at = arg.first();
		
		if (!(at instanceof XSTime) && !(at instanceof XSDayTimeDuration)) {
			throw DynamicError.throw_type_error();
		}

		if (at instanceof XSTime) {
			return minusXSTimeDuration(at);
		}
		
		if (at instanceof XSDayTimeDuration) {
			return minusXSDayTimeDuration(at);
		}
		return null; // unreach
	}

	private ResultSequence minusXSDayTimeDuration(AnyType at) {
		XSDuration val = (XSDuration) at;

		XSTime res = null;
		try {
			res = (XSTime) clone();
		} catch (CloneNotSupportedException err) {
			return null;
		}

		try {
			XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar((GregorianCalendar)calendar());
			Duration dtduration = DatatypeFactory.newInstance().newDuration(val.string_value());
			xmlCal.add(dtduration.negate());
			res = new XSTime(xmlCal.toGregorianCalendar(), res.tz());
		} catch (DatatypeConfigurationException ex) {
			
		}

		return ResultSequenceFactory.create_new(res);
	}

	private ResultSequence minusXSTimeDuration(AnyType at) {
		XSTime val = (XSTime) at;
		Duration dtduration = null;
		try {
			Calendar thisCal = normalizeCalendar(calendar(), tz());
			Calendar thatCal = normalizeCalendar(val.calendar(), val.tz());
			long duration = thisCal.getTimeInMillis() - thatCal.getTimeInMillis();
			dtduration = DatatypeFactory.newInstance().newDuration(duration);
			return ResultSequenceFactory.create_new(XSDayTimeDuration.parseDTDuration(dtduration.toString()));
		} catch (DatatypeConfigurationException ex) {
			return null;
		}
	}

	/**
	 * Mathematical addition between this time stored and the supplied time
	 * duration.
	 * 
	 * @param arg
	 *            A XDTDayTimeDuration representation of the duration of time to
	 *            add
	 * @return A XSTime representing the result of this addition.
	 * @throws DynamicError
	 */
	public ResultSequence plus(ResultSequence arg) throws DynamicError {
		XSDuration val = (XSDuration) NumericType
				.get_single_type(arg, XSDayTimeDuration.class);

		try {
			double ms = val.time_value() * 1000.0;

			XSTime res = (XSTime) clone();

			res.calendar().add(Calendar.MILLISECOND, (int) ms);

			return ResultSequenceFactory.create_new(res);
		} catch (CloneNotSupportedException err) {
			assert false;
			return null;
		}
	}
}
