/*
 * 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 java.util.ArrayList;

import org.w3c.dom.DOMException;
import org.w3c.dom.smil.ElementTime;
import org.w3c.dom.smil.SMILElement;
import org.w3c.dom.smil.Time;
import org.w3c.dom.smil.TimeList;

import android.util.Log;

public abstract class ElementTimeImpl implements ElementTime {
    private static final String TAG = "ElementTimeImpl";

    private static final String FILL_REMOVE_ATTRIBUTE = "remove";
    private static final String FILL_FREEZE_ATTRIBUTE = "freeze";
    private static final String FILL_HOLD_ATTRIBUTE = "hold";
    private static final String FILL_TRANSITION_ATTRIBUTE = "transition";
    private static final String FILL_AUTO_ATTRIBUTE   = "auto";
    private static final String FILL_ATTRIBUTE_NAME   = "fill";
    private static final String FILLDEFAULT_ATTRIBUTE_NAME   = "fillDefault";

    final SMILElement mSmilElement;

    /*
     * Internal Interface
     */
    ElementTimeImpl(SMILElement element) {
        mSmilElement = element;
    }

    // Default implementation. Override if required.
    int getBeginConstraints() {
        return TimeImpl.ALLOW_ALL;
    }

    // Default implementation. Override if required
    int getEndConstraints() {
        return TimeImpl.ALLOW_ALL;
    }

    /**
     * To get the parent node on the ElementTime tree. It is in opposition to getTimeChildren.
     * @return the parent ElementTime. Returns <code>null</code> if there is no parent.
     */
    abstract ElementTime getParentElementTime();

    /*
     * ElementTime Interface
     */

    public TimeList getBegin() {
        String[] beginTimeStringList = mSmilElement.getAttribute("begin").split(";");

        // TODO: Check other constraints on parsed values, e.g., "single, non-negative offset values
        ArrayList<Time> beginTimeList = new ArrayList<Time>();
        // Initialize Time instances and add them to Vector
        for (int i = 0; i < beginTimeStringList.length; i++) {
            try {
                beginTimeList.add(new TimeImpl(beginTimeStringList[i], getBeginConstraints()));
            } catch (IllegalArgumentException e) {
                // Ignore badly formatted times
            }
        }
        if (beginTimeList.size() == 0) {
            /*
             * What is the right default value?
             *
             * In MMS SMIL, this method may be called either on an instance of:
             *
             * 1 - ElementSequentialTimeContainer (The SMILDocument)
             * 2 - ElementParallelTimeContainer (A Time-Child of the SMILDocument, which is a seq)
             * 3 - ElementTime (A SMILMediaElement).
             *
             * 1 - In the first case, the default start time is obviously 0.
             * 2 - In the second case, the specifications mentions that
             *      "For children of a sequence, the only legal value for begin is
             *      a (single) non-negative offset value. The default begin value is 0."
             * 3 - In the third case, the specification mentions that
             *      "The default value of begin for children of a par is 0."
             *
             * In short, if no value is specified, the default is always 0.
             */

            beginTimeList.add(new TimeImpl("0", TimeImpl.ALLOW_ALL));
        }
        return new TimeListImpl(beginTimeList);
    }

    public float getDur() {
        float dur = 0;
        try {
            String durString = mSmilElement.getAttribute("dur");
            if (durString != null) {
                dur = TimeImpl.parseClockValue(durString) / 1000f;
            }
        } catch (IllegalArgumentException e) {
            // Do nothing and return the minimum value
        }

        return dur;
    }

    public TimeList getEnd() {
        ArrayList<Time> endTimeList = new ArrayList<Time>();

        String[] endTimeStringList = mSmilElement.getAttribute("end").split(";");
        int len = endTimeStringList.length;
        if (!((len == 1) && (endTimeStringList[0].length() == 0))) {  // Ensure the end field is set.
            // Initialize Time instances and add them to Vector
            for (int i = 0; i < len; i++) {
                try {
                    endTimeList.add(new TimeImpl(endTimeStringList[i],
                            getEndConstraints()));
                } catch (IllegalArgumentException e) {
                    // Ignore badly formatted times
                    Log.e(TAG, "Malformed time value.", e);
                }
            }
        }

        // "end" time is not specified
        if (endTimeList.size() == 0) {
            // Get duration
            float duration = getDur();

            if (duration < 0) {
                endTimeList.add(new TimeImpl("indefinite", getEndConstraints()));
            } else {
                // Get begin
                TimeList begin = getBegin();
                for (int i = 0; i < begin.getLength(); i++) {
                    endTimeList.add(new TimeImpl(
                            // end = begin + dur
                            begin.item(i).getResolvedOffset() + duration + "s",
                            getEndConstraints()));
                }
            }
        }

        return new TimeListImpl(endTimeList);
    }

    private boolean beginAndEndAreZero() {
        TimeList begin = getBegin();
        TimeList end = getEnd();
        if (begin.getLength() == 1 && end.getLength() == 1) {
            Time beginTime = begin.item(0);
            Time endTime = end.item(0);
            return beginTime.getOffset() == 0. && endTime.getOffset() == 0.;
        }
        return false;
    }

    public short getFill() {
        String fill = mSmilElement.getAttribute(FILL_ATTRIBUTE_NAME);
        if (fill.equalsIgnoreCase(FILL_FREEZE_ATTRIBUTE)) {
            return FILL_FREEZE;
        } else if (fill.equalsIgnoreCase(FILL_REMOVE_ATTRIBUTE)) {
            return FILL_REMOVE;
        } else if (fill.equalsIgnoreCase(FILL_HOLD_ATTRIBUTE)) {
            // FIXME handle it as freeze for now
            return FILL_FREEZE;
        } else if (fill.equalsIgnoreCase(FILL_TRANSITION_ATTRIBUTE)) {
            // FIXME handle it as freeze for now
            return FILL_FREEZE;
        } else if (!fill.equalsIgnoreCase(FILL_AUTO_ATTRIBUTE)) {
            /*
             * fill = default
             * The fill behavior for the element is determined by the value of the fillDefault
             * attribute.  This is the default value.
             */
            short fillDefault = getFillDefault();
            if (fillDefault != FILL_AUTO) {
                return fillDefault;
            }
        }

        /*
         * fill = auto
         * The fill behavior for this element depends on whether the element specifies any of
         * the attributes that define the simple or active duration:
         *  - If none of the attributes dur, end, repeatCount or repeatDur are specified on
         *    the element, then the element will have a fill behavior identical to that if it were
         *    specified as "freeze".
         *  - Otherwise, the element will have a fill behavior identical to that if it were
         *    specified as "remove".
         */
        if (((mSmilElement.getAttribute("dur").length() == 0) &&
                (mSmilElement.getAttribute("end").length() == 0) &&
                (mSmilElement.getAttribute("repeatCount").length() == 0) &&
                (mSmilElement.getAttribute("repeatDur").length() == 0)) ||
                beginAndEndAreZero()) {
            return FILL_FREEZE;
        } else {
            return FILL_REMOVE;
        }
    }

    public short getFillDefault() {
        String fillDefault = mSmilElement.getAttribute(FILLDEFAULT_ATTRIBUTE_NAME);
        if (fillDefault.equalsIgnoreCase(FILL_REMOVE_ATTRIBUTE)) {
            return FILL_REMOVE;
        } else if (fillDefault.equalsIgnoreCase(FILL_FREEZE_ATTRIBUTE)) {
            return FILL_FREEZE;
        } else if (fillDefault.equalsIgnoreCase(FILL_AUTO_ATTRIBUTE)) {
            return FILL_AUTO;
        } else if (fillDefault.equalsIgnoreCase(FILL_HOLD_ATTRIBUTE)) {
            // FIXME handle it as freeze for now
            return FILL_FREEZE;
        } else if (fillDefault.equalsIgnoreCase(FILL_TRANSITION_ATTRIBUTE)) {
            // FIXME handle it as freeze for now
            return FILL_FREEZE;
        } else {
            /*
             * fillDefault = inherit
             * Specifies that the value of this attribute (and of the fill behavior) are
             * inherited from the fillDefault value of the parent element.
             * This is the default value.
             */
            ElementTime parent = getParentElementTime();
            if (parent == null) {
                /*
                 * fillDefault = auto
                 * If there is no parent element, the value is "auto".
                 */
                return FILL_AUTO;
            } else {
                return ((ElementTimeImpl) parent).getFillDefault();
            }
        }
    }

    public float getRepeatCount() {
        String repeatCount = mSmilElement.getAttribute("repeatCount");
        try {
            float value = Float.parseFloat(repeatCount);
            if (value > 0) {
                return value;
            } else {
                return 0; // default
            }
        } catch (NumberFormatException e) {
            return 0; // default
        }
    }

    public float getRepeatDur() {
        try {
            float repeatDur =
                TimeImpl.parseClockValue(mSmilElement.getAttribute("repeatDur"));
            if (repeatDur > 0) {
                return repeatDur;
            } else {
                return 0; // default
            }
        } catch (IllegalArgumentException e) {
            return 0; // default
        }
    }

    public short getRestart() {
        String restart = mSmilElement.getAttribute("restart");
        if (restart.equalsIgnoreCase("never")) {
            return RESTART_NEVER;
        } else if (restart.equalsIgnoreCase("whenNotActive")) {
            return RESTART_WHEN_NOT_ACTIVE;
        } else {
            return RESTART_ALWAYS; // default
        }
    }

    public void setBegin(TimeList begin) throws DOMException {
        // TODO Implement this
        mSmilElement.setAttribute("begin", "indefinite");
    }

    public void setDur(float dur) throws DOMException {
        // In SMIL 3.0, the dur could be a timecount-value which may contain fractions.
        // However, in MMS 1.3, the dur SHALL be expressed in integer milliseconds.
        mSmilElement.setAttribute("dur", Integer.toString((int)(dur * 1000)) + "ms");
    }

    public void setEnd(TimeList end) throws DOMException {
        // TODO Implement this
        mSmilElement.setAttribute("end", "indefinite");
    }

    public void setFill(short fill) throws DOMException {
        if (fill == FILL_FREEZE) {
            mSmilElement.setAttribute(FILL_ATTRIBUTE_NAME, FILL_FREEZE_ATTRIBUTE);
        } else {
            mSmilElement.setAttribute(FILL_ATTRIBUTE_NAME, FILL_REMOVE_ATTRIBUTE); // default
        }
    }

    public void setFillDefault(short fillDefault) throws DOMException {
        if (fillDefault == FILL_FREEZE) {
            mSmilElement.setAttribute(FILLDEFAULT_ATTRIBUTE_NAME, FILL_FREEZE_ATTRIBUTE);
        } else {
            mSmilElement.setAttribute(FILLDEFAULT_ATTRIBUTE_NAME, FILL_REMOVE_ATTRIBUTE);
        }
    }

    public void setRepeatCount(float repeatCount) throws DOMException {
        String repeatCountString = "indefinite";
        if (repeatCount > 0) {
            repeatCountString = Float.toString(repeatCount);
        }
        mSmilElement.setAttribute("repeatCount", repeatCountString);
    }

    public void setRepeatDur(float repeatDur) throws DOMException {
        String repeatDurString = "indefinite";
        if (repeatDur > 0) {
            repeatDurString = Float.toString(repeatDur) + "ms";
        }
        mSmilElement.setAttribute("repeatDur", repeatDurString);
    }

    public void setRestart(short restart) throws DOMException {
        if (restart == RESTART_NEVER) {
            mSmilElement.setAttribute("restart", "never");
        } else if (restart == RESTART_WHEN_NOT_ACTIVE) {
            mSmilElement.setAttribute("restart", "whenNotActive");
        } else {
            mSmilElement.setAttribute("restart", "always");
        }
    }
}
