/*
 * Copyright (C) 2011 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 android.speech.tts;

import android.util.Log;

import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;

class AudioPlaybackHandler {
    private static final String TAG = "TTS.AudioPlaybackHandler";
    private static final boolean DBG = false;

    private final LinkedBlockingQueue<PlaybackQueueItem> mQueue =
            new LinkedBlockingQueue<PlaybackQueueItem>();
    private final Thread mHandlerThread;

    private volatile PlaybackQueueItem mCurrentWorkItem = null;

    AudioPlaybackHandler() {
        mHandlerThread = new Thread(new MessageLoop(), "TTS.AudioPlaybackThread");
    }

    public void start() {
        mHandlerThread.start();
    }

    private void stop(PlaybackQueueItem item) {
        if (item == null) {
            return;
        }

        item.stop(TextToSpeech.STOPPED);
    }

    public void enqueue(PlaybackQueueItem item) {
        try {
            mQueue.put(item);
        } catch (InterruptedException ie) {
            // This exception will never be thrown, since we allow our queue
            // to be have an unbounded size. put() will therefore never block.
        }
    }

    public void stopForApp(Object callerIdentity) {
        if (DBG) Log.d(TAG, "Removing all callback items for : " + callerIdentity);
        removeWorkItemsFor(callerIdentity);

        final PlaybackQueueItem current = mCurrentWorkItem;
        if (current != null && (current.getCallerIdentity() == callerIdentity)) {
            stop(current);
        }
    }

    public void stop() {
        if (DBG) Log.d(TAG, "Stopping all items");
        removeAllMessages();

        stop(mCurrentWorkItem);
    }

    /**
     * @return false iff the queue is empty and no queue item is currently
     *        being handled, true otherwise.
     */
    public boolean isSpeaking() {
        return (mQueue.peek() != null) || (mCurrentWorkItem != null);
    }

    /**
     * Shut down the audio playback thread.
     */
    public void quit() {
        removeAllMessages();
        stop(mCurrentWorkItem);
        mHandlerThread.interrupt();
    }

    /*
     * Atomically clear the queue of all messages.
     */
    private void removeAllMessages() {
        mQueue.clear();
    }

    /*
     * Remove all messages that originate from a given calling app.
     */
    private void removeWorkItemsFor(Object callerIdentity) {
        Iterator<PlaybackQueueItem> it = mQueue.iterator();

        while (it.hasNext()) {
            final PlaybackQueueItem item = it.next();
            if (item.getCallerIdentity() == callerIdentity) {
                it.remove();
                stop(item);
            }
        }
    }

    /*
     * The MessageLoop is a handler like implementation that
     * processes messages from a priority queue.
     */
    private final class MessageLoop implements Runnable {
        @Override
        public void run() {
            while (true) {
                PlaybackQueueItem item = null;
                try {
                    item = mQueue.take();
                } catch (InterruptedException ie) {
                    if (DBG) Log.d(TAG, "MessageLoop : Shutting down (interrupted)");
                    return;
                }

                // If stop() or stopForApp() are called between mQueue.take()
                // returning and mCurrentWorkItem being set, the current work item
                // will be run anyway.

                mCurrentWorkItem = item;
                item.run();
                mCurrentWorkItem = null;
            }
        }
    }

}
