/*
 * Copyright (C) 2007-2008 Esmertec AG.
 * Copyright (C) 2007-2008 The Android Open Source Project
 *
 * 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 com.android.mms.dom.smil;

import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.smil.Time;

public class TimeImpl implements Time {
    static final int ALLOW_INDEFINITE_VALUE = (1 << 0);
    static final int ALLOW_OFFSET_VALUE     = (1 << 1);
    static final int ALLOW_SYNCBASE_VALUE   = (1 << 2);
    static final int ALLOW_SYNCTOPREV_VALUE = (1 << 3);
    static final int ALLOW_EVENT_VALUE      = (1 << 4);
    static final int ALLOW_MARKER_VALUE     = (1 << 5);
    static final int ALLOW_WALLCLOCK_VALUE  = (1 << 6);
    static final int ALLOW_NEGATIVE_VALUE   = (1 << 7);
    static final int ALLOW_ALL              = 0xFF;

    short mTimeType;
    boolean mResolved;
    double mResolvedOffset;

    /**
     * Creates a TimeImpl representation of a time-value represented as a String.
     * Time-values have the following syntax:
     * <p>
     * <pre>
     * Time-val ::= ( smil-1.0-syncbase-value
     *                          | "indefinite"
     *                          | offset-value
     *                          | syncbase-value
     *                          | syncToPrev-value
     *                          | event-value
     *                          | media-marker-value
     *                          | wallclock-sync-value )
     * Smil-1.0-syncbase-value ::=
     *          "id(" id-ref ")" ( "(" ( "begin" | "end" | clock-value ) ")" )?
     * Offset-value         ::= ( "+" | "-" )? clock-value
     * Syncbase-value       ::= ( id-ref "." ( "begin" | "end" ) ) ( ( "+" | "-" ) clock-value )?
     * SyncToPrev-value     ::= ( "prev.begin" | "prev.end" ) ( ( "+" | "-" ) clock-value )?
     * Event-value          ::= ( id-ref "." )? ( event-ref  ) ( ( "+" | "-" ) clock-value )?
     * Media-marker-value   ::= id-ref ".marker(" marker-name ")"
     * Wallclock-sync-value ::= "wallclock(" wallclock-value ")"
     * </pre>
     *
     * @param timeValue A String in the representation specified above
     * @param constraints Any combination of the #ALLOW_* flags
     * @return  A TimeImpl instance representing
     * @exception java.lang.IllegalArgumentException if the timeValue input
     *          parameter does not comply with the defined syntax
     * @exception java.lang.NullPointerException if the timekValue string is
     *          <code>null</code>
     */
    TimeImpl(String timeValue, int constraints) {
        /*
         * We do not support yet:
         *      - smil-1.0-syncbase-value
         *      - syncbase-value
         *      - syncToPrev-value
         *      - event-value
         *      - Media-marker-value
         *      - Wallclock-sync-value
         */
        // Will throw NullPointerException if timeValue is null
        if (timeValue.equals("indefinite")
                && ((constraints & ALLOW_INDEFINITE_VALUE) != 0) ) {
            mTimeType = SMIL_TIME_INDEFINITE;
        } else if ((constraints & ALLOW_OFFSET_VALUE) != 0) {
            int sign = 1;
            if (timeValue.startsWith("+")) {
                timeValue = timeValue.substring(1);
            } else if (timeValue.startsWith("-")) {
                timeValue = timeValue.substring(1);
                sign = -1;
            }
            mResolvedOffset = sign*parseClockValue(timeValue)/1000.0;
            mResolved = true;
            mTimeType = SMIL_TIME_OFFSET;
        } else {
            throw new IllegalArgumentException("Unsupported time value");
        }
    }

    /**
     * Converts a String representation of a clock value into the float
     * representation used in this API.
     * <p>
     * Clock values have the following syntax:
     * </p>
     * <p>
     * <pre>
     * Clock-val         ::= ( Full-clock-val | Partial-clock-val | Timecount-val )
     * Full-clock-val    ::= Hours ":" Minutes ":" Seconds ("." Fraction)?
     * Partial-clock-val ::= Minutes ":" Seconds ("." Fraction)?
     * Timecount-val     ::= Timecount ("." Fraction)? (Metric)?
     * Metric            ::= "h" | "min" | "s" | "ms"
     * Hours             ::= DIGIT+; any positive number
     * Minutes           ::= 2DIGIT; range from 00 to 59
     * Seconds           ::= 2DIGIT; range from 00 to 59
     * Fraction          ::= DIGIT+
     * Timecount         ::= DIGIT+
     * 2DIGIT            ::= DIGIT DIGIT
     * DIGIT             ::= [0-9]
     * </pre>
     *
     * @param clockValue A String in the representation specified above
     * @return  A float value in milliseconds that matches the string
     *          representation given as the parameter
     * @exception java.lang.IllegalArgumentException if the clockValue input
     *          parameter does not comply with the defined syntax
     * @exception java.lang.NullPointerException if the clockValue string is
     *          <code>null</code>
     */
    public static float parseClockValue(String clockValue) {
        try {
            float result = 0;

            // Will throw NullPointerException if clockValue is null
            clockValue = clockValue.trim();

            // Handle first 'Timecount-val' cases with metric
            if (clockValue.endsWith("ms")) {
                result = parseFloat(clockValue, 2, true);
            } else if (clockValue.endsWith("s")) {
                result = 1000*parseFloat(clockValue, 1, true);
            } else if (clockValue.endsWith("min")) {
                result = 60000*parseFloat(clockValue, 3, true);
            } else if (clockValue.endsWith("h")) {
                result = 3600000*parseFloat(clockValue, 1, true);
            } else {
                // Handle Timecount-val without metric
                try {
                    return parseFloat(clockValue, 0, true) * 1000;
                } catch (NumberFormatException _) {
                    // Ignore
                }

                // Split in {[Hours], Minutes, Seconds}
                String[] timeValues = clockValue.split(":");

                // Read Hours if present and remember location of Minutes
                int indexOfMinutes;
                if (timeValues.length == 2) {
                    indexOfMinutes = 0;
                } else if (timeValues.length == 3) {
                    result = 3600000*(int)parseFloat(timeValues[0], 0, false);
                    indexOfMinutes = 1;
                } else {
                    throw new IllegalArgumentException();
                }

                // Read Minutes
                int minutes = (int)parseFloat(timeValues[indexOfMinutes], 0, false);
                if ((minutes >= 00) && (minutes <= 59)) {
                    result += 60000*minutes;
                } else {
                    throw new IllegalArgumentException();
                }

                // Read Seconds
                float seconds = parseFloat(timeValues[indexOfMinutes + 1], 0, true);
                if ((seconds >= 00) && (seconds < 60)) {
                    result += 60000*seconds;
                } else {
                    throw new IllegalArgumentException();
                }

            }
            return result;
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException();
        }
    }

    /**
     * Parse a value formatted as follows:
     * <p>
     * <pre>
     * Value    ::= Number ("." Decimal)? (Text)?
     * Number   ::= DIGIT+; any positive number
     * Decimal  ::= DIGIT+; any positive number
     * Text     ::= CHAR*;   any sequence of chars
     * DIGIT    ::= [0-9]
     * </pre>
     * @param value The Value to parse
     * @param ignoreLast The size of Text to ignore
     * @param parseDecimal Whether Decimal is expected
     * @return The float value without Text, rounded to 3 digits after '.'
     * @throws IllegalArgumentException if Decimal was not expected but encountered
     */
    private static float parseFloat(String value, int ignoreLast, boolean parseDecimal) {
        // Ignore last characters
        value = value.substring(0, value.length() - ignoreLast);

        float result;
        int indexOfComma = value.indexOf('.');
        if (indexOfComma != -1) {
            if (!parseDecimal) {
                throw new IllegalArgumentException("int value contains decimal");
            }
            // Ensure that there are at least 3 decimals
            value = value + "000";
            // Read value up to 3 decimals and cut the rest
            result = Float.parseFloat(value.substring(0, indexOfComma));
            result += Float.parseFloat(
                    value.substring(indexOfComma + 1, indexOfComma + 4))/1000;
        } else {
            result = Integer.parseInt(value);
        }

        return result;
    }

    /*
     * Time Interface
     */

    public boolean getBaseBegin() {
        // TODO Auto-generated method stub
        return false;
    }

    public Element getBaseElement() {
        // TODO Auto-generated method stub
        return null;
    }

    public String getEvent() {
        // TODO Auto-generated method stub
        return null;
    }

    public String getMarker() {
        // TODO Auto-generated method stub
        return null;
    }

    public double getOffset() {
        // TODO Auto-generated method stub
        return 0;
    }

    public boolean getResolved() {
        return mResolved;
    }

    public double getResolvedOffset() {
        return mResolvedOffset;
    }

    public short getTimeType() {
        return mTimeType;
    }

    public void setBaseBegin(boolean baseBegin) throws DOMException {
        // TODO Auto-generated method stub

    }

    public void setBaseElement(Element baseElement) throws DOMException {
        // TODO Auto-generated method stub

    }

    public void setEvent(String event) throws DOMException {
        // TODO Auto-generated method stub

    }

    public void setMarker(String marker) throws DOMException {
        // TODO Auto-generated method stub

    }

    public void setOffset(double offset) throws DOMException {
        // TODO Auto-generated method stub

    }
}
