/*
 * Copyright 2002-2004 The Apache Software Foundation.
 *
 * 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 org.apache.axis2.databinding.types;

import java.io.Serializable;
import java.util.Calendar;

/**
 * Implementation of the XML Schema type duration. Duration supports a minimum
 * fractional second precision of milliseconds.
 *
 * @see <a href="http://www.w3.org/TR/xmlschema-2/#duration">XML Schema 3.2.6</a>
 */
public class Duration implements Serializable {

	private static final long serialVersionUID = -3736760992541369098L;
	
	boolean isNegative;
    int years;
    int months;
    int days;
    int hours;
    int minutes;
    double seconds;

    /**
     * Default no-arg constructor
     */
    public Duration() {
    }

    /**
     * @param negative
     * @param aYears
     * @param aMonths
     * @param aDays
     * @param aHours
     * @param aMinutes
     * @param aSeconds
     */
    public Duration(boolean negative, int aYears, int aMonths, int aDays,
                    int aHours, int aMinutes, double aSeconds) {
        isNegative = negative;
        years = aYears;
        months = aMonths;
        days = aDays;
        hours = aHours;
        minutes = aMinutes;
        setSeconds(aSeconds);
    }

    /**
     * Constructs Duration from a String in an xsd:duration format -
     * PnYnMnDTnHnMnS.
     *
     * @param duration String
     * @throws SchemaException if the string doesn't parse correctly.
     */
    public Duration(String duration) throws IllegalArgumentException {
        int position = 1;
        int timePosition = duration.indexOf("T");

        // P is required but P by itself is invalid
        if (duration.indexOf("P") == -1 || duration.equals("P")) {
            throw new IllegalArgumentException();
                   // Messages.getMessage("badDuration"));
        }

        // if present, time cannot be empty
        if (duration.lastIndexOf("T") == duration.length() - 1) {
            throw new IllegalArgumentException();
//                    Messages.getMessage("badDuration"));
        }

        // check the sign
        if (duration.startsWith("-")) {
            isNegative = true;
            position++;
        }

        // parse time part
        if (timePosition != -1) {
            parseTime(duration.substring(timePosition + 1));
        } else {
            timePosition = duration.length();
        }

        // parse date part
        if (position != timePosition) {
            parseDate(duration.substring(position, timePosition));
        }
    }

    /**
     * Constructs Duration from a Calendar.
     *
     * @param calendar Calendar
     * @throws IllegalArgumentException if the calendar object does not
     * represent any date nor time.
     */
    public Duration(boolean negative, Calendar calendar) throws
            IllegalArgumentException {
        this.isNegative = negative;
        this.years = calendar.get(Calendar.YEAR);
        this.months = calendar.get(Calendar.MONTH);
        this.days = calendar.get(Calendar.DATE);
        this.hours = calendar.get(Calendar.HOUR);
        this.minutes = calendar.get(Calendar.MINUTE);
        this.seconds = calendar.get(Calendar.SECOND);
        this.seconds += ((double) calendar.get(Calendar.MILLISECOND)) / 100;
        if (years == 0 && months == 0 && days == 0 && hours == 0 &&
            minutes == 0 && seconds == 0) {
            throw new IllegalArgumentException();
                    //Messages.getMessage("badCalendarForDuration"));
        }
    }

    /**
     * This method parses the time portion of a String that represents
     * xsd:duration - nHnMnS.
     *
     * @param time
     * @throws IllegalArgumentException if time does not match pattern
     *
     */
    public void parseTime(String time) throws IllegalArgumentException {
        if (time.length() == 0 || time.indexOf("-") != -1) {
            throw new IllegalArgumentException();
                    //Messages.getMessage("badTimeDuration"));
        }

        // check if time ends with either H, M, or S
        if (!time.endsWith("H") && !time.endsWith("M") && !time.endsWith("S")) {
            throw new IllegalArgumentException();
                    //Messages.getMessage("badTimeDuration"));
        }

        try {
            // parse string and extract hours, minutes, and seconds
            int start = 0;

            // Hours
            int end = time.indexOf("H");
            // if there is H in a string but there is no value for hours,
            // throw an exception
            if (start == end) {
                throw new IllegalArgumentException();
                        //Messages.getMessage("badTimeDuration"));
            }
            if (end != -1) {
                hours = Integer.parseInt(time.substring(0, end));
                start = end + 1;
            }

            // Minutes
            end = time.indexOf("M");
            // if there is M in a string but there is no value for hours,
            // throw an exception
            if (start == end) {
                throw new IllegalArgumentException();
//                        Messages.getMessage("badTimeDuration"));
            }

            if (end != -1) {
                minutes = Integer.parseInt(time.substring(start, end));
                start = end + 1;
            }

            // Seconds
            end = time.indexOf("S");
            // if there is S in a string but there is no value for hours,
            // throw an exception
            if (start == end) {
                throw new IllegalArgumentException();
                        //Messages.getMessage("badTimeDuration"));
            }

            if (end != -1) {
                setSeconds(Double.parseDouble(time.substring(start, end)));
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException();
                    //Messages.getMessage("badTimeDuration"));
        }
    }

    /**
     * This method parses the date portion of a String that represents
     * xsd:duration - nYnMnD.
     *
     * @param date
     * @throws IllegalArgumentException if date does not match pattern
     *
     */
    public void parseDate(String date) throws IllegalArgumentException {
        if (date.length() == 0 || date.indexOf("-") != -1) {
            throw new IllegalArgumentException();
                    //Messages.getMessage("badDateDuration"));
        }

        // check if date string ends with either Y, M, or D
        if (!date.endsWith("Y") && !date.endsWith("M") && !date.endsWith("D")) {
            throw new IllegalArgumentException();
                    //Messages.getMessage("badDateDuration"));
        }

        // catch any parsing exception
        try {
            // parse string and extract years, months, days
            int start = 0;
            int end = date.indexOf("Y");

            // if there is Y in a string but there is no value for years,
            // throw an exception
            if (start == end) {
                throw new IllegalArgumentException();
                       // Messages.getMessage("badDateDuration"));
            }
            if (end != -1) {
                years = Integer.parseInt(date.substring(0, end));
                start = end + 1;
            }

            // months
            end = date.indexOf("M");
            // if there is M in a string but there is no value for months,
            // throw an exception
            if (start == end) {
                throw new IllegalArgumentException();
                        //Messages.getMessage("badDateDuration"));
            }
            if (end != -1) {
                months = Integer.parseInt(date.substring(start, end));
                start = end + 1;
            }

            end = date.indexOf("D");
            // if there is D in a string but there is no value for days,
            // throw an exception
            if (start == end) {
                throw new IllegalArgumentException();
                       // Messages.getMessage("badDateDuration"));
            }
            if (end != -1) {
                days = Integer.parseInt(date.substring(start, end));
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException();
                    //Messages.getMessage("badDateDuration"));
        }
    }

    /**
     *
     */
    public boolean isNegative() {
        return isNegative;
    }

    /**
     *
     */
    public int getYears() {
        return years;
    }

    /**
     *
     */
    public int getMonths() {
        return months;
    }

    /**
     *
     */
    public int getDays() {
        return days;
    }

    /**
     *
     */
    public int getHours() {
        return hours;
    }

    /**
     *
     */
    public int getMinutes() {
        return minutes;
    }

    /**
     *
     */
    public double getSeconds() {
        return seconds;
    }

    /**
     * @param negative
     */
    public void setNegative(boolean negative) {
        isNegative = negative;
    }

    /**
     * @param years
     */
    public void setYears(int years) {
        this.years = years;
    }

    /**
     * @param months
     */
    public void setMonths(int months) {
        this.months = months;
    }

    /**
     * @param days
     */
    public void setDays(int days) {
        this.days = days;
    }

    /**
     * @param hours
     */
    public void setHours(int hours) {
        this.hours = hours;
    }

    /**
     * @param minutes
     */
    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    /**
     * @param seconds
     * @deprecated use {@link #setSeconds(double) setSeconds(double)}
     * instead
     */
    public void setSeconds(int seconds) {
        this.seconds = seconds;
    }

    /**
     * Sets the seconds. NOTE: The fractional value of seconds is rounded up to
     * milliseconds.
     *
     * @param seconds double
     */
    public void setSeconds(double seconds) {
        this.seconds = ((double) (Math.round(seconds * 100))) / 100;
    }

    /**
     * This returns the xml representation of an xsd:duration object.
     */
    public String toString() {
        StringBuffer duration = new StringBuffer();

        duration.append("P");

        if (years != 0) {
            duration.append(years).append("Y");
        }
        if (months != 0) {
            duration.append(months).append("M");
        }
        if (days != 0) {
            duration.append(days).append("D");
        }
        if (hours != 0 || minutes != 0 || seconds != 0.0) {
            duration.append("T");

            if (hours != 0) {
                duration.append(hours).append("H");

            }
            if (minutes != 0) {
                duration.append(minutes).append("M");

            }
            if (seconds != 0) {
                if (seconds == (int) seconds) {
                    duration.append((int) seconds).append("S");
                } else {
                    duration.append(seconds).append("S");
                }
            }
        }

        if (duration.length() == 1) {
            duration.append("T0S");
        }

        if (isNegative) {
            duration.insert(0, "-");
        }

        return duration.toString();
    }

    /**
     * The equals method compares the time represented by duration object, not
     * its string representation.
     * Hence, a duration object representing 65 minutes is considered equal to a
     * duration object representing 1 hour and 5 minutes.
     *
     * @param object
     */
    public boolean equals(Object object) {
        if (!(object instanceof Duration)) {
            return false;
        }

        Duration duration = (Duration) object;

        return this.isNegative == duration.isNegative &&
                this.getAsCalendar().equals(duration.getAsCalendar());
    }

    public int hashCode() {
        int hashCode = 0;

        if (isNegative) {
            hashCode++;
        }
        hashCode += years;
        hashCode += months;
        hashCode += days;
        hashCode += hours;
        hashCode += minutes;
        hashCode += seconds;
        // milliseconds
        hashCode += (seconds * 100) % 100;

        return hashCode;
    }

    /**
     * Returns duration as a calendar.  Due to the way a Calendar class works,
     * the values for particular fields may not be the same as obtained through
     * getter methods.  For example, if a duration's object getMonths
     * returns 20, a similar call on a calendar object will return 1 year and
     * 8 months.
     *
     * @return Calendar
     */
    public Calendar getAsCalendar() {
        return getAsCalendar(Calendar.getInstance());
    }

    /**
     * Returns duration as a calendar.  Due to the way a Calendar class works,
     * the values for particular fields may not be the same as obtained through
     * getter methods.  For example, if a Duration's object getMonths
     * returns 20, a similar call on a Calendar object will return 1 year and
     * 8 months.
     *
     * @param startTime Calendar
     * @return Calendar
     */
    public Calendar getAsCalendar(Calendar startTime) {
        Calendar ret = (Calendar) startTime.clone();
        ret.set(Calendar.YEAR, years);
        ret.set(Calendar.MONTH, months);
        ret.set(Calendar.DATE, days);
        ret.set(Calendar.HOUR, hours);
        ret.set(Calendar.MINUTE, minutes);
        ret.set(Calendar.SECOND, (int) seconds);
        ret.set(Calendar.MILLISECOND,
                (int) (seconds * 100 - Math.round(seconds) * 100));
        return ret;
    }
}
