/*
 * 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 java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;

import org.w3c.dom.NodeList;
import org.w3c.dom.events.DocumentEvent;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.smil.ElementParallelTimeContainer;
import org.w3c.dom.smil.ElementSequentialTimeContainer;
import org.w3c.dom.smil.ElementTime;
import org.w3c.dom.smil.Time;
import org.w3c.dom.smil.TimeList;

import android.util.Log;

/**
 * The SmilPlayer is responsible for playing, stopping, pausing and resuming a SMIL tree.
 * <li>It creates a whole timeline before playing.</li>
 * <li>The player runs in a different thread which intends not to block the main thread.</li>
 */
public class SmilPlayer implements Runnable {
    private static final String TAG = "Mms/smil";
    private static final boolean DEBUG = false;
    private static final boolean LOCAL_LOGV = false;
    private static final int TIMESLICE = 200;

    private static enum SmilPlayerState {
        INITIALIZED,
        PLAYING,
        PLAYED,
        PAUSED,
        STOPPED,
    }

    private static enum SmilPlayerAction {
        NO_ACTIVE_ACTION,
        RELOAD,
        STOP,
        PAUSE,
        START,
        NEXT,
        PREV
    }

    public static final String MEDIA_TIME_UPDATED_EVENT = "mediaTimeUpdated";

    private static final Comparator<TimelineEntry> sTimelineEntryComparator =
        new Comparator<TimelineEntry>() {
        public int compare(TimelineEntry o1, TimelineEntry o2) {
            return Double.compare(o1.getOffsetTime(), o2.getOffsetTime());
        }
    };

    private static SmilPlayer sPlayer;

    private long mCurrentTime;
    private int mCurrentElement;
    private int mCurrentSlide;
    private ArrayList<TimelineEntry> mAllEntries;
    private ElementTime mRoot;
    private Thread mPlayerThread;
    private SmilPlayerState mState = SmilPlayerState.INITIALIZED;
    private SmilPlayerAction mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
    private ArrayList<ElementTime> mActiveElements;
    private Event mMediaTimeUpdatedEvent;

    private static ArrayList<TimelineEntry> getParTimeline(
            ElementParallelTimeContainer par, double offset, double maxOffset) {
        ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>();

        // Set my begin at first
        TimeList myBeginList = par.getBegin();
        /*
         * Begin list only contain 1 begin time which has been resolved.
         * @see com.android.mms.dom.smil.ElementParallelTimeContainerImpl#getBegin()
         */
        Time begin = myBeginList.item(0);
        double beginOffset = begin.getResolvedOffset() + offset;
        if (beginOffset > maxOffset) {
            // This element can't be started.
            return timeline;
        }
        TimelineEntry myBegin = new TimelineEntry(beginOffset, par, TimelineEntry.ACTION_BEGIN);
        timeline.add(myBegin);

        TimeList myEndList = par.getEnd();
        /*
         * End list only contain 1 end time which has been resolved.
         * @see com.android.mms.dom.smil.ElementParallelTimeContainerImpl#getEnd()
         */
        Time end = myEndList.item(0);
        double endOffset = end.getResolvedOffset() + offset;
        if (endOffset > maxOffset) {
            endOffset = maxOffset;
        }
        TimelineEntry myEnd = new TimelineEntry(endOffset, par, TimelineEntry.ACTION_END);

        maxOffset = endOffset;

        NodeList children = par.getTimeChildren();
        for (int i = 0; i < children.getLength(); ++i) {
            ElementTime child = (ElementTime) children.item(i);
            ArrayList<TimelineEntry> childTimeline = getTimeline(child, offset, maxOffset);
            timeline.addAll(childTimeline);
        }

        Collections.sort(timeline, sTimelineEntryComparator);

        // Add end-event to timeline for all active children
        NodeList activeChildrenAtEnd = par.getActiveChildrenAt(
                (float) (endOffset - offset) * 1000);
        for (int i = 0; i < activeChildrenAtEnd.getLength(); ++i) {
            timeline.add(new TimelineEntry(endOffset,
                    (ElementTime) activeChildrenAtEnd.item(i),
                    TimelineEntry.ACTION_END));
        }

        // Set my end at last
        timeline.add(myEnd);

        return timeline;
    }

    private static ArrayList<TimelineEntry> getSeqTimeline(
            ElementSequentialTimeContainer seq, double offset, double maxOffset) {
        ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>();
        double orgOffset = offset;

        // Set my begin at first
        TimeList myBeginList = seq.getBegin();
        /*
         * Begin list only contain 1 begin time which has been resolved.
         * @see com.android.mms.dom.smil.ElementSequentialTimeContainerImpl#getBegin()
         */
        Time begin = myBeginList.item(0);
        double beginOffset = begin.getResolvedOffset() + offset;
        if (beginOffset > maxOffset) {
            // This element can't be started.
            return timeline;
        }
        TimelineEntry myBegin = new TimelineEntry(beginOffset, seq, TimelineEntry.ACTION_BEGIN);
        timeline.add(myBegin);

        TimeList myEndList = seq.getEnd();
        /*
         * End list only contain 1 end time which has been resolved.
         * @see com.android.mms.dom.smil.ElementSequentialTimeContainerImpl#getEnd()
         */
        Time end = myEndList.item(0);
        double endOffset = end.getResolvedOffset() + offset;
        if (endOffset > maxOffset) {
            endOffset = maxOffset;
        }
        TimelineEntry myEnd = new TimelineEntry(endOffset, seq, TimelineEntry.ACTION_END);

        maxOffset = endOffset;

        // Get children's timelines
        NodeList children = seq.getTimeChildren();
        for (int i = 0; i < children.getLength(); ++i) {
            ElementTime child = (ElementTime) children.item(i);
            ArrayList<TimelineEntry> childTimeline = getTimeline(child, offset, maxOffset);
            timeline.addAll(childTimeline);

            // Since the child timeline has been sorted, the offset of the last one is the biggest.
            offset = childTimeline.get(childTimeline.size() - 1).getOffsetTime();
        }

        // Add end-event to timeline for all active children
        NodeList activeChildrenAtEnd = seq.getActiveChildrenAt(
                (float) (endOffset - orgOffset));
        for (int i = 0; i < activeChildrenAtEnd.getLength(); ++i) {
            timeline.add(new TimelineEntry(endOffset,
                    (ElementTime) activeChildrenAtEnd.item(i),
                    TimelineEntry.ACTION_END));
        }

        // Set my end at last
        timeline.add(myEnd);

        return timeline;
    }

    private static ArrayList<TimelineEntry> getTimeline(ElementTime element,
            double offset, double maxOffset) {
        if (element instanceof ElementParallelTimeContainer) {
            return getParTimeline((ElementParallelTimeContainer) element, offset, maxOffset);
        } else if (element instanceof ElementSequentialTimeContainer) {
            return getSeqTimeline((ElementSequentialTimeContainer) element, offset, maxOffset);
        } else {
            // Not ElementTimeContainer here
            ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>();

            TimeList beginList = element.getBegin();
            for (int i = 0; i < beginList.getLength(); ++i) {
                Time begin = beginList.item(i);
                if (begin.getResolved()) {
                    double beginOffset = begin.getResolvedOffset() + offset;
                    if (beginOffset <= maxOffset) {
                        TimelineEntry entry = new TimelineEntry(beginOffset,
                                element, TimelineEntry.ACTION_BEGIN);
                        timeline.add(entry);
                    }
                }
            }

            TimeList endList = element.getEnd();
            for (int i = 0; i < endList.getLength(); ++i) {
                Time end = endList.item(i);
                if (end.getResolved()) {
                    double endOffset = end.getResolvedOffset() + offset;
                    if (endOffset <= maxOffset) {
                        TimelineEntry entry = new TimelineEntry(endOffset,
                                element, TimelineEntry.ACTION_END);
                        timeline.add(entry);
                    }
                }
            }

            Collections.sort(timeline, sTimelineEntryComparator);

            return timeline;
        }
    }

    private SmilPlayer() {
        // Private constructor
    }

    public static SmilPlayer getPlayer() {
        if (sPlayer == null) {
            sPlayer = new SmilPlayer();
        }
        return sPlayer;
    }

    public synchronized boolean isPlayingState() {
        return mState == SmilPlayerState.PLAYING;
    }

    public synchronized boolean isPlayedState() {
        return mState == SmilPlayerState.PLAYED;
    }

    public synchronized boolean isPausedState() {
        return mState == SmilPlayerState.PAUSED;
    }

    public synchronized boolean isStoppedState() {
        return mState == SmilPlayerState.STOPPED;
    }

    private synchronized boolean isPauseAction() {
        return mAction == SmilPlayerAction.PAUSE;
    }

    private synchronized boolean isStartAction() {
        return mAction == SmilPlayerAction.START;
    }

    private synchronized boolean isStopAction() {
        return mAction == SmilPlayerAction.STOP;
    }

    private synchronized boolean isReloadAction() {
        return mAction == SmilPlayerAction.RELOAD;
    }

    private synchronized boolean isNextAction() {
      return mAction == SmilPlayerAction.NEXT;
    }

    private synchronized boolean isPrevAction() {
      return mAction == SmilPlayerAction.PREV;
    }

    public synchronized void init(ElementTime root) {
        mRoot = root;
        mAllEntries = getTimeline(mRoot, 0, Long.MAX_VALUE);
        mMediaTimeUpdatedEvent = ((DocumentEvent) mRoot).createEvent("Event");
        mMediaTimeUpdatedEvent.initEvent(MEDIA_TIME_UPDATED_EVENT, false, false);
        mActiveElements = new ArrayList<ElementTime>();
    }

    public synchronized void play() {
        if (!isPlayingState()) {
            mCurrentTime = 0;
            mCurrentElement = 0;
            mCurrentSlide = 0;
            mPlayerThread = new Thread(this, "SmilPlayer thread");
            mState = SmilPlayerState.PLAYING;
            mPlayerThread.start();
        } else {
            Log.w(TAG, "Error State: Playback is playing!");
        }
    }

    public synchronized void pause() {
        if (isPlayingState()) {
            mAction = SmilPlayerAction.PAUSE;
            notifyAll();
        } else {
            Log.w(TAG, "Error State: Playback is not playing!");
        }
    }

    public synchronized void start() {
        if (isPausedState()) {
            resumeActiveElements();
            mAction = SmilPlayerAction.START;
            notifyAll();
        } else if (isPlayedState()) {
            play();
        } else {
            Log.w(TAG, "Error State: Playback can not be started!");
        }
    }

    public synchronized void stop() {
        if (isPlayingState() || isPausedState()) {
            mAction = SmilPlayerAction.STOP;
            notifyAll();
        } else if (isPlayedState()) {
            actionStop();
        }
    }

    public synchronized void stopWhenReload() {
        endActiveElements();
    }

    public synchronized void reload() {
        if (isPlayingState() || isPausedState()) {
            mAction = SmilPlayerAction.RELOAD;
            notifyAll();
        } else if (isPlayedState()) {
            actionReload();
        }
    }

    public synchronized void next() {
      if (isPlayingState() || isPausedState()) {
        mAction = SmilPlayerAction.NEXT;
        notifyAll();
      }
    }

    public synchronized void prev() {
      if (isPlayingState() || isPausedState()) {
        mAction = SmilPlayerAction.PREV;
        notifyAll();
      }
    }

    private synchronized boolean isBeginOfSlide(TimelineEntry entry) {
        return (TimelineEntry.ACTION_BEGIN == entry.getAction())
                    && (entry.getElement() instanceof SmilParElementImpl);
    }

    private synchronized void reloadActiveSlide() {
        mActiveElements.clear();
        beginSmilDocument();

        for (int i = mCurrentSlide; i < mCurrentElement; i++) {
            TimelineEntry entry = mAllEntries.get(i);
            actionEntry(entry);
        }
        seekActiveMedia();
    }

    private synchronized void beginSmilDocument() {
        TimelineEntry entry = mAllEntries.get(0);
        actionEntry(entry);
    }

    private synchronized double getOffsetTime(ElementTime element) {
        for (int i = mCurrentSlide; i < mCurrentElement; i++) {
            TimelineEntry entry = mAllEntries.get(i);
            if (element.equals(entry.getElement())) {
                return entry.getOffsetTime() * 1000;  // in ms
            }
        }
        return -1;
    }

    private synchronized void seekActiveMedia() {
        for (int i = mActiveElements.size() - 1; i >= 0; i--) {
            ElementTime element = mActiveElements.get(i);
            if (element instanceof SmilParElementImpl) {
                return;
            }
            double offset = getOffsetTime(element);
            if ((offset >= 0) && (offset <= mCurrentTime)) {
                if (LOCAL_LOGV) {
                    Log.v(TAG, "[SEEK]  " + " at " + mCurrentTime
                            + " " + element);
                }
                element.seekElement( (float) (mCurrentTime - offset) );
            }
        }
    }

    private synchronized void waitForEntry(long interval)
            throws InterruptedException {
        if (LOCAL_LOGV) {
            Log.v(TAG, "Waiting for " + interval + "ms.");
        }

        long overhead = 0;

        while (interval > 0) {
            long startAt = System.currentTimeMillis();
            long sleep = Math.min(interval, TIMESLICE);
            if (overhead < sleep) {
                wait(sleep - overhead);
                mCurrentTime += sleep;
            } else {
                sleep = 0;
                mCurrentTime += overhead;
            }

            if (isStopAction() || isReloadAction() || isPauseAction() || isNextAction() ||
                isPrevAction()) {
                return;
            }

            ((EventTarget) mRoot).dispatchEvent(mMediaTimeUpdatedEvent);

            interval -= TIMESLICE;
            overhead = System.currentTimeMillis() - startAt - sleep;
        }
    }

    public synchronized int getDuration() {
         if ((mAllEntries != null) && !mAllEntries.isEmpty()) {
             return (int) mAllEntries.get(mAllEntries.size() - 1).mOffsetTime * 1000;
         }
         return 0;
    }

    public synchronized int getCurrentPosition() {
        return (int) mCurrentTime;
    }

    private synchronized void endActiveElements() {
        for (int i = mActiveElements.size() - 1; i >= 0; i--) {
            ElementTime element = mActiveElements.get(i);
            if (LOCAL_LOGV) {
                Log.v(TAG, "[STOP]  " + " at " + mCurrentTime
                        + " " + element);
            }
            element.endElement();
        }
    }

    private synchronized void pauseActiveElements() {
        for (int i = mActiveElements.size() - 1; i >= 0; i--) {
            ElementTime element = mActiveElements.get(i);
            if (LOCAL_LOGV) {
                Log.v(TAG, "[PAUSE]  " + " at " + mCurrentTime
                        + " " + element);
            }
            element.pauseElement();
        }
    }

    private synchronized void resumeActiveElements() {
        int size = mActiveElements.size();
        for (int i = 0; i < size; i++) {
            ElementTime element = mActiveElements.get(i);
            if (LOCAL_LOGV) {
                Log.v(TAG, "[RESUME]  " + " at " + mCurrentTime
                        + " " + element);
            }
            element.resumeElement();
        }
    }

    private synchronized void waitForWakeUp() {
        try {
            while ( !(isStartAction() || isStopAction() || isReloadAction() ||
                    isNextAction() || isPrevAction()) ) {
                wait(TIMESLICE);
            }
            if (isStartAction()) {
                mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
                mState = SmilPlayerState.PLAYING;
            }
        } catch (InterruptedException e) {
            Log.e(TAG, "Unexpected InterruptedException.", e);
        }
    }

    private synchronized void actionEntry(TimelineEntry entry) {
        switch (entry.getAction()) {
            case TimelineEntry.ACTION_BEGIN:
                if (LOCAL_LOGV) {
                    Log.v(TAG, "[START] " + " at " + mCurrentTime + " "
                            + entry.getElement());
                }
                entry.getElement().beginElement();
                mActiveElements.add(entry.getElement());
                break;
            case TimelineEntry.ACTION_END:
                if (LOCAL_LOGV) {
                    Log.v(TAG, "[STOP]  " + " at " + mCurrentTime + " "
                            + entry.getElement());
                }
                entry.getElement().endElement();
                mActiveElements.remove(entry.getElement());
                break;
            default:
                break;
        }
    }

    private synchronized TimelineEntry reloadCurrentEntry() {
        // Check if the position is less than size of all entries
        if (mCurrentElement < mAllEntries.size()) {
            return mAllEntries.get(mCurrentElement);
        } else {
            return null;
        }
    }

    private void stopCurrentSlide() {
        HashSet<TimelineEntry> skippedEntries = new HashSet<TimelineEntry>();
        int totalEntries = mAllEntries.size();
        for (int i = mCurrentElement; i < totalEntries; i++) {
            // Stop any started entries, and skip the not started entries until
            // meeting the end of slide
            TimelineEntry entry = mAllEntries.get(i);
            int action = entry.getAction();
            if (entry.getElement() instanceof SmilParElementImpl &&
                    action == TimelineEntry.ACTION_END) {
                actionEntry(entry);
                mCurrentElement = i;
                break;
            } else if (action == TimelineEntry.ACTION_END && !skippedEntries.contains(entry)) {
                    actionEntry(entry);
            } else if (action == TimelineEntry.ACTION_BEGIN) {
                skippedEntries.add(entry);
            }
        }
    }

    private TimelineEntry loadNextSlide() {
      TimelineEntry entry;
      int totalEntries = mAllEntries.size();
      for (int i = mCurrentElement; i < totalEntries; i++) {
          entry = mAllEntries.get(i);
          if (isBeginOfSlide(entry)) {
              mCurrentElement = i;
              mCurrentSlide = i;
              mCurrentTime = (long)(entry.getOffsetTime() * 1000);
              return entry;
          }
      }
      // No slide, finish play back
      mCurrentElement++;
      entry = null;
      if (mCurrentElement < totalEntries) {
          entry = mAllEntries.get(mCurrentElement);
          mCurrentTime = (long)(entry.getOffsetTime() * 1000);
      }
      return entry;
    }

    private TimelineEntry loadPrevSlide() {
      int skippedSlides = 1;
      int latestBeginEntryIndex = -1;
      for (int i = mCurrentSlide; i >= 0; i--) {
        TimelineEntry entry = mAllEntries.get(i);
        if (isBeginOfSlide(entry)) {
            latestBeginEntryIndex = i;
          if (0 == skippedSlides-- ) {
            mCurrentElement = i;
            mCurrentSlide = i;
            mCurrentTime = (long)(entry.getOffsetTime() * 1000);
            return entry;
          }
        }
      }
      if (latestBeginEntryIndex != -1) {
          mCurrentElement = latestBeginEntryIndex;
          mCurrentSlide = latestBeginEntryIndex;
          return mAllEntries.get(mCurrentElement);
      }
      return null;
    }

    private synchronized TimelineEntry actionNext() {
        stopCurrentSlide();
        return loadNextSlide();
   }

    private synchronized TimelineEntry actionPrev() {
        stopCurrentSlide();
        return loadPrevSlide();
    }

    private synchronized void actionPause() {
        pauseActiveElements();
        mState = SmilPlayerState.PAUSED;
        mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
    }

    private synchronized void actionStop() {
        endActiveElements();
        mCurrentTime = 0;
        mCurrentElement = 0;
        mCurrentSlide = 0;
        mState = SmilPlayerState.STOPPED;
        mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
    }

    private synchronized void actionReload() {
        reloadActiveSlide();
        mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
    }

    public void run() {
        if (isStoppedState()) {
            return;
        }
        if (LOCAL_LOGV) {
            dumpAllEntries();
        }
        // Play the Element by following the timeline
        int size = mAllEntries.size();
        for (mCurrentElement = 0; mCurrentElement < size; mCurrentElement++) {
            TimelineEntry entry = mAllEntries.get(mCurrentElement);
            if (isBeginOfSlide(entry)) {
                mCurrentSlide = mCurrentElement;
            }
            long offset = (long) (entry.getOffsetTime() * 1000); // in ms.
            while (offset > mCurrentTime) {
                try {
                    waitForEntry(offset - mCurrentTime);
                } catch (InterruptedException e) {
                    Log.e(TAG, "Unexpected InterruptedException.", e);
                }

                while (isPauseAction() || isStopAction() || isReloadAction() || isNextAction() ||
                    isPrevAction()) {
                    if (isPauseAction()) {
                        actionPause();
                        waitForWakeUp();
                    }

                    if (isStopAction()) {
                        actionStop();
                        return;
                    }

                    if (isReloadAction()) {
                        actionReload();
                        entry = reloadCurrentEntry();
                        if (entry == null)
                            return;
                        if (isPausedState()) {
                            mAction = SmilPlayerAction.PAUSE;
                        }
                    }

                    if (isNextAction()) {
                        TimelineEntry nextEntry = actionNext();
                        if (nextEntry != null) {
                            entry = nextEntry;
                        }
                        if (mState == SmilPlayerState.PAUSED) {
                            mAction = SmilPlayerAction.PAUSE;
                            actionEntry(entry);
                        } else {
                            mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
                        }
                        offset = mCurrentTime;
                    }

                    if (isPrevAction()) {
                        TimelineEntry prevEntry = actionPrev();
                        if (prevEntry != null) {
                            entry = prevEntry;
                        }
                        if (mState == SmilPlayerState.PAUSED) {
                            mAction = SmilPlayerAction.PAUSE;
                            actionEntry(entry);
                        } else {
                            mAction = SmilPlayerAction.NO_ACTIVE_ACTION;
                        }
                        offset = mCurrentTime;
                    }
                }
            }
            mCurrentTime = offset;
            actionEntry(entry);
        }

        mState = SmilPlayerState.PLAYED;
    }

    private static final class TimelineEntry {
        final static int ACTION_BEGIN = 0;
        final static int ACTION_END   = 1;

        private final double mOffsetTime;
        private final ElementTime mElement;
        private final int mAction;

        public TimelineEntry(double offsetTime, ElementTime element, int action) {
            mOffsetTime = offsetTime;
            mElement = element;
            mAction  = action;
        }

        public double getOffsetTime() {
            return mOffsetTime;
        }

        public ElementTime getElement() {
            return mElement;
        }

        public int getAction() {
            return mAction;
        }

        public String toString() {
            return "Type = " + mElement + " offset = " + getOffsetTime() + " action = " + getAction();
        }
    }

    private void dumpAllEntries() {
        if (LOCAL_LOGV) {
            for (TimelineEntry entry : mAllEntries) {
                Log.v(TAG, "[Entry] "+ entry);
            }
        }
    }
}
