// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
// ==UserScript==
// @include       http://youtube.com/*
// @include       http://*.youtube.com/*
// @include       https://youtube.com/*
// @include       https://*.youtube.com/*
// @require       utils.js
// ==/UserScript==

/* Testing URL:
 * http://www.youtube.com/watch?v=v1TsCud9QhU&feature=autoplay&list=PLDA83A73D581CEFCC&lf=plpp_play_all&playnext=120
 */

// This placeholder gets munged with real data at build time.
var WebappsGettextDict = JSON.parse(unescape(
    "%7B%22GETTEXT%22%3A%22PLACEHOLDER%22%7D"
));

var Unity = external.getUnityObject(1);
window.Unity = Unity;
unsafeWindow.Unity = window.Unity;

function getParams() {
    var query = window.location.search;
    var match, search = /([^&=]+)=?([^&]*)/g;
    var urlParams = {};

    query = query.substr(1);
    function decode(s) {
        var pl = /\+/g;
        return decodeURIComponent(s.replace(pl, " "));
    }

    match = search.exec(query);
    while (match) {
        urlParams[decode(match[1])] = decode(match[2]);
        match = search.exec(query);
    }
    return urlParams;
}

function evalInPageContext(func) {
    var script = document.createElement('script');
    script.appendChild(document.createTextNode('(' + func + ')();'));
    (document.body || document.head || document.documentElement).appendChild(script);
}

function musicPlayerSetup() {
    if (document.getElementById('upload-prompt-box')) {
        evalInPageContext(function () {
            // Chromium: This function is being injected into the webpage e.g. in a different
            // JS context than the content script's. You cannot close over content script variables.
            Unity = window.Unity || external.getUnityObject(1);
            Unity.acceptData(['video/mp4'], function (file) {
                var event = new CustomEvent("drop");
                event.type = "drop";
                event.dataTransfer = { files: [file] };
                event.dataTransfer.dropEffect = "copy";
                event.dataTransfer.effectAllowed = "all";
                event.dataTransfer.types = ["application/x-moz-file", "text/x-moz-url", "video/mp4", "Files"];
                event.dataTransfer.items = [{ kind: "file",
                                              type: "text/plain",
                                              getAsFile: function () { return file; }}];

                document.body.dispatchEvent(event);
            });
        });
    }

    var titleLabel = document.evaluate('//h1[@id="watch-headline-title"]/span',
                                       document,
                                       null,
                                       XPathResult.ANY_UNORDERED_NODE_TYPE,
                                       null).singleNodeValue;
    var artLocation = null;
    try {
        var id = getParams().v;
        if (id) {
            artLocation = 'http://i3.ytimg.com/vi/' + id + '/default.jpg';
        }
    } catch (e) {}
    var trackInfo = {
        title: titleLabel.title,
        album: null,
        artist: null,
        artLocation: artLocation
    };

    Unity.MediaPlayer.init("YouTube");

    Unity.MediaPlayer.setTrack(trackInfo);

    function changeState(dryRun) {
        // player don't have playVideo/pauseVideo methods
        // in greasemonkey context.
        var isPlaying;
        var player = document.getElementById('movie_player');
        if (player) {
            isPlaying = player.getPlayerState() === 1;
            if (!dryRun) {
                if (isPlaying) {
                    player.pauseVideo();
                } else {
                    player.playVideo();
                }
                isPlaying = !isPlaying;
            }
        } else { //html5 player
            var button = document.evaluate('//div[@id="movie_player-html5"]/div[3]/div/button[contains(@class, "html5-control")]', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue;
            isPlaying = String(button.className).match(/html5-pause-button/);
            if (!dryRun) {
                button.click();
                isPlaying = !isPlaying;
            }
        }
        // Chromium: This function is being injected into the webpage e.g. in a different
        // JS context than the content script's. You cannot close over content script variables.
        Unity = window.Unity || external.getUnityObject(1);
        if (isPlaying) {
            Unity.MediaPlayer.setPlaybackState(Unity.MediaPlayer.PlaybackState.PLAYING);
        } else {
            Unity.MediaPlayer.setPlaybackState(Unity.MediaPlayer.PlaybackState.PAUSED);
        }
    }
    Unity.MediaPlayer.onPlayPause(function () {
        evalInPageContext(changeState);
    });

    Unity.MediaPlayer.onNext(function () {
        launchClickEvent(document.getElementById("playlist-bar-next-button"));
    });

    Unity.MediaPlayer.onPrevious(function () {
        launchClickEvent(document.getElementById("playlist-bar-prev-button"));
    });

    evalInPageContext('function() {setInterval(function() {(' + String(changeState) + ')(true)}, 1000);}');
}

Unity.init({ name: "YouTube",
             domain: 'youtube.com',
             homepage: 'http://www.youtube.com',
             iconUrl: "icon://unity-webapps-youtube",
             onInit: musicPlayerSetup });
