/*
 * Copyright (C) 2016 Google Inc.
 *
 * 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.googlecode.android_scripting.facade.media;

import android.app.Service;
import android.media.MediaPlayer;
import android.net.Uri;

import com.googlecode.android_scripting.facade.EventFacade;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcDefault;
import com.googlecode.android_scripting.rpc.RpcParameter;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

/**
 * This facade exposes basic mediaPlayer functionality. <br>
 * <br>
 * <b>Usage Notes:</b><br>
 * mediaPlayerFacade maintains a list of media streams, identified by a user supplied tag. If the
 * tag is null or blank, this tag defaults to "default"<br>
 * Basic operation is: mediaPlayOpen("file:///sdcard/MP3/sample.mp3","mytag",true)<br>
 * This will look for a media file at /sdcard/MP3/sample.mp3. Other urls should work. If the file
 * exists and is playable, this will return a true otherwise it will return a false. <br>
 * If play=true, then the media file will play immediately, otherwise it will wait for a
 * {@link #mediaPlayStart mediaPlayerStart} command. <br>
 * When done with the resource, use {@link #mediaPlayClose mediaPlayClose} <br>
 * You can get information about the loaded media with {@link #mediaPlayInfo mediaPlayInfo} This
 * returns a map with the following elements:
 * <ul>
 * <li>"tag" - user supplied tag identifying this mediaPlayer.
 * <li>"loaded" - true if loaded, false if not. If false, no other elements are returned.
 * <li>"duration" - length of the media in milliseconds.
 * <li>"position" - current position of playback in milliseconds. Controlled by
 * {@link #mediaPlaySeek mediaPlaySeek}
 * <li>"isplaying" - shows whether media is playing. Controlled by {@link #mediaPlayPause
 * mediaPlayPause} and {@link #mediaPlayStart mediaPlayStart}
 * <li>"url" - the url used to open this media.
 * <li>"looping" - whether media will loop. Controlled by {@link #mediaPlaySetLooping
 * mediaPlaySetLooping}
 * </ul>
 * <br>
 * You can use {@link #mediaPlayList mediaPlayList} to get a list of the loaded tags. <br>
 * {@link #mediaIsPlaying mediaIsPlaying} will return true if the media is playing.<br>
 * <b>Events:</b><br>
 * A playing media will throw a <b>"media"</b> event on completion. NB: In remote mode, a media file
 * will continue playing after the script has finished unless an explicit {@link #mediaPlayClose
 * mediaPlayClose} event is called.
 *
 * @author Robbie Matthews (rjmatthews62@gmail.com)
 */

public class MediaPlayerFacade extends RpcReceiver implements MediaPlayer.OnCompletionListener {

    private final Service mService;
    static private final Map<String, MediaPlayer> mPlayers = new Hashtable<String, MediaPlayer>();
    static private final Map<String, String> mUrls = new Hashtable<String, String>();

    private final EventFacade mEventFacade;

    public MediaPlayerFacade(FacadeManager manager) {
        super(manager);
        mService = manager.getService();
        mEventFacade = manager.getReceiver(EventFacade.class);
    }

    private String getDefault(String tag) {
        return (tag == null || tag.equals("")) ? "default" : tag;
    }

    private MediaPlayer getPlayer(String tag) {
        tag = getDefault(tag);
        return mPlayers.get(tag);
    }

    private String getUrl(String tag) {
        tag = getDefault(tag);
        return mUrls.get(tag);
    }

    private void putMp(String tag, MediaPlayer player, String url) {
        tag = getDefault(tag);
        mPlayers.put(tag, player);
        mUrls.put(tag, url);
    }

    private void removeMp(String tag) {
        tag = getDefault(tag);
        MediaPlayer player = mPlayers.get(tag);
        if (player != null) {
            player.stop();
            player.release();
        }
        mPlayers.remove(tag);
        mUrls.remove(tag);
    }

    @Rpc(description = "Open a media file", returns = "true if play successful")
    public synchronized boolean mediaPlayOpen(@RpcParameter(name = "url",
                                                            description = "url of media resource")
    String url, @RpcParameter(name = "tag", description = "string identifying resource")
    @RpcDefault(value = "default")
    String tag, @RpcParameter(name = "play", description = "start playing immediately")
    @RpcDefault(value = "true")
    Boolean play) {
        removeMp(tag);
        MediaPlayer player = getPlayer(tag);
        player = MediaPlayer.create(mService, Uri.parse(url));
        if (player != null) {
            putMp(tag, player, url);
            player.setOnCompletionListener(this);
            if (play) {
                player.start();
            }
        }
        return player != null;
    }

    @Rpc(description = "pause playing media file", returns = "true if successful")
    public synchronized boolean mediaPlayPause(
            @RpcParameter(name = "tag", description = "string identifying resource")
            @RpcDefault(value = "default")
            String tag) {
        MediaPlayer player = getPlayer(tag);
        if (player == null) {
            return false;
        }
        player.pause();
        return true;
    }

    @Rpc(description = "Start playing media file.", returns = "true if successful")
    public synchronized boolean mediaPlayStart(
            @RpcParameter(name = "tag", description = "string identifying resource")
            @RpcDefault(value = "default")
            String tag) {
        MediaPlayer player = getPlayer(tag);
        if (player == null) {
            return false;
        }
        player.start();
        return mediaIsPlaying(tag);
    }

    @Rpc(description = "Stop playing media file.", returns = "true if successful")
    public synchronized boolean mediaPlayStop(
            @RpcParameter(name = "tag", description = "string identifying resource")
            @RpcDefault(value = "default")
            String tag) {
        MediaPlayer player = getPlayer(tag);
        if (player == null) {
            return false;
        }
        player.stop();
        return !mediaIsPlaying(tag) && player.getCurrentPosition() == 0;
    }

    @Rpc(description = "Stop all players.")
    public synchronized void mediaPlayStopAll() {
        for (MediaPlayer p : mPlayers.values()) {
            p.stop();
        }
    }

    @Rpc(description = "Seek To Position", returns = "New Position (in ms)")
    public synchronized int mediaPlaySeek(@RpcParameter(name = "msec",
                                                        description = "Position in millseconds")
    Integer msec, @RpcParameter(name = "tag", description = "string identifying resource")
    @RpcDefault(value = "default")
    String tag) {
        MediaPlayer player = getPlayer(tag);
        if (player == null) {
            return 0;
        }
        player.seekTo(msec);
        return player.getCurrentPosition();
    }

    @Rpc(description = "Close media file", returns = "true if successful")
    public synchronized boolean mediaPlayClose(
            @RpcParameter(name = "tag", description = "string identifying resource")
            @RpcDefault(value = "default")
            String tag) throws Exception {
        if (!mPlayers.containsKey(tag)) {
            return false;
        }
        removeMp(tag);
        return true;
    }

    @Rpc(description = "Checks if media file is playing.", returns = "true if playing")
    public synchronized boolean mediaIsPlaying(
            @RpcParameter(name = "tag", description = "string identifying resource")
            @RpcDefault(value = "default")
            String tag) {
        MediaPlayer player = getPlayer(tag);
        return (player == null) ? false : player.isPlaying();
    }

    @Rpc(description = "Information on current media", returns = "Media Information")
    public synchronized Map<String, Object> mediaPlayGetInfo(
            @RpcParameter(name = "tag", description = "string identifying resource")
            @RpcDefault(value = "default")
            String tag) {
        Map<String, Object> result = new HashMap<String, Object>();
        MediaPlayer player = getPlayer(tag);
        result.put("tag", getDefault(tag));
        if (player == null) {
            result.put("loaded", false);
        } else {
            result.put("loaded", true);
            result.put("duration", player.getDuration());
            result.put("position", player.getCurrentPosition());
            result.put("isplaying", player.isPlaying());
            result.put("url", getUrl(tag));
            result.put("looping", player.isLooping());
        }
        return result;
    }

    @Rpc(description = "Lists currently loaded media", returns = "List of Media Tags")
    public Set<String> mediaPlayList() {
        return mPlayers.keySet();
    }

    @Rpc(description = "Set Looping", returns = "True if successful")
    public synchronized boolean mediaPlaySetLooping(@RpcParameter(name = "enabled")
    @RpcDefault(value = "true")
    Boolean enabled, @RpcParameter(name = "tag", description = "string identifying resource")
    @RpcDefault(value = "default")
    String tag) {
        MediaPlayer player = getPlayer(tag);
        if (player == null) {
            return false;
        }
        player.setLooping(enabled);
        return true;
    }

    @Rpc(description = "Checks if media file is playing.", returns = "true if playing")
    public synchronized void mediaSetNext(
            @RpcParameter(name = "tag", description = "string identifying resource")
            @RpcDefault(value = "default")
            String tag,
            @RpcParameter(name = "next", description = "tag of the next track to play.")
            String next) {
        MediaPlayer player = getPlayer(tag);
        MediaPlayer nPlayer = getPlayer(next);
        if (player == null) {
            throw new NullPointerException("Non-existent player tag " + tag);
        }
        if (nPlayer == null) {
            throw new NullPointerException("Non-existent player tag " + next);
        }
        player.setNextMediaPlayer(nPlayer);
    }

    @Override
    public synchronized void shutdown() {
        for (String key : mPlayers.keySet()) {
            MediaPlayer player = mPlayers.get(key);
            if (player != null) {
                player.stop();
                player.release();
                player = null;
            }
        }
        mPlayers.clear();
        mUrls.clear();
    }

    @Override
    public void onCompletion(MediaPlayer player) {
        String tag = getTag(player);
        if (tag != null) {
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("action", "complete");
            data.put("tag", tag);
            mEventFacade.postEvent("media", data);
        }
    }

    private String getTag(MediaPlayer player) {
        for (Entry<String, MediaPlayer> m : mPlayers.entrySet()) {
            if (m.getValue() == player) {
                return m.getKey();
            }
        }
        return null;
    }
}
