/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright (c) 2015 Adobe Systems Incorporated. All rights reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */

/*global CSInterface, CSEvent, themeManager, $, window, document*/

(function () {
    "use strict";


    var GeneratorConnection = require("../common/js/GeneratorConnection"),
        TemplateManager     = require("./js/TemplateManager"),
        JSXRunner           = require("../common/JSXRunner");

    var IPCMessage          = require("preview-common/IPCMessage");

    var csInterface = new CSInterface();

    var $getTheApp,
        $devices,
        $content = $("#content");

    var genconn,
        generatorConnected,
        generatorLaunched = false,
        hasConnected = false;

    var Affordance = {
        BUSY: "busy",
        READY_TO_PAIR: "ready-to-pair",
        NOT_LOGGED_IN: "not-logged-in",
        OFFLINE: "no-internet"
    };

    var ConnectionStatus  = IPCMessage.connectionStatus,
        cepEvents         = IPCMessage.cepEvents;

    function distributePanes() {
        var $title = $("#title-container"),
            $device = $("#device-container");

        if ($title.is(":visible") && $device.is(":visible")) {
            var contentHeight = $content.height(),
                titleHeight = $title.height();

            $device.css({height: (contentHeight - titleHeight) - 32});
        }
    }

    function handleResize() {
        distributePanes();
    }


    function updateDeviceList(devices) {
        if ($getTheApp === undefined) {
            return;
        }

        if ($devices) {
            $devices.remove();
        }

        if (devices.length > 0) {
            $getTheApp.addClass("hidden");
            $getTheApp.remove();
            TemplateManager.renderTemplate("devices", {devices: devices}).then(
                function($template) {
                        $devices = $template;
                        $content.html($devices);
                });

            setTimeout(distributePanes, 15);
        } else {
            $getTheApp.removeClass("hidden");
            $content.html($getTheApp);
        }
    }

 /*
    function addBogusDevices() {
        updateDeviceList([
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}},
            {name: "boafdsafasfsdafsadfsadfsadfasdfasdfasdfasdfasdfasdfasdfasdfsdagus", resolution: {height: 6500, width: 1700}}
        ]);
    }
*/

    // handle IPC messages from the generator
    function _handleGeneratorMessage(message) {
        switch(message.payload.messageType) {
            case IPCMessage.types.PANELOPENEDACK:
                // generator acknowledged our panel opened message.  Ask for the device list.
                genconn.sendMessage({
                    messageType: IPCMessage.types.REQUESTDEVICELIST
                });
                break;
            case IPCMessage.types.DEVICELIST:
                // generator sent the full list of connected devices
                updateDeviceList(message.payload.deviceList);
                break;
            case IPCMessage.types.DEVICECONNECTED:
                // remember if we've connected to the Preview app on a device at least once
                if (!hasConnected) {
                    hasConnected = true;
                }
                break;
            default:
                // unknown message type
                console.log("com.adobe.preview/PSPanel: received unknown Generator message type: " + JSON.stringify(message.payload.messageType));
        }
    }
    
    function disableRunningGenerator() {
        JSXRunner.runJSX("isGeneratorRunning", null, function (isRunning) {
            if (isRunning === "true") {
                JSXRunner.runJSX("disableGenerator");
                generatorLaunched = false;
            }
        });
    }
    
    /**
     * Sets preferences to disable generator on next PS launch *AND* to disable Preview from auto-starting
     *   generator whenever the Preview panel is opened.
     *
     * DEBUGGING TIP:
     *   This function is useful when running generator external from Photoshop -- eg. running locally within
     *   node.  To invoke, open Chrome Dev Tools on PSPanel (http://localhost:8198/), and enter the
     *   following command into the console:
     *      window.disableGeneratorAutoStart()
     *   Upon receiving the message, preferences will be set so that, on the next launch of PS, the internal
     *   generator will not be started *AND* Preview will not attempt auto-start it either.
     *  
     */
    window.disableGeneratorAutoStart = function() {
        window.localStorage.setItem("DEV-do-not-auto-start-generator", "internal-generator-off");
        
        disableRunningGenerator();
        
        return "DEV-MODE - auto-start generator disabled";
    };

    // ensure that Generator is running
    function ensureGeneratorRunning() {
        //comment the following line out once and run... then forever you can enjoy not having it auto-start generator
        //window.localStorage.setItem("DEV-do-not-auto-start-generator", "internal-generator-off");

        if (window.localStorage.getItem("DEV-do-not-auto-start-generator") !== "internal-generator-off") {
            // enable Generator if it isn't already running
            JSXRunner.runJSX("isGeneratorRunning", null, function (isRunning) {
                if (isRunning !== "true") {
                    JSXRunner.runJSX("ensureGenerator");
                    generatorLaunched = true;
                }
            });
        } else {
            console.warn("RUNNING IN DEV-MODE - NOT AUTO-STARTING GENERATOR. To reset, run this in the panel dev tools console:");
            console.log("window.localStorage.removeItem(\"DEV-do-not-auto-start-generator\");");
        }
    }

    // initialize the connection to the generator-preview plugin
    function _connectToGenerator() {
        // connect to Generator
        genconn = GeneratorConnection.connectToGenerator();

        // event handler to receive messages from the generator
        genconn.on("message", _handleGeneratorMessage);

        // try to reopen the connection if it closes
        genconn.on("close", function () {
            setTimeout(genconn.establishConnection.bind(genconn), GeneratorConnection.CONNECTION_RETRY_DELAY);
        });

        var firstConnectionAfterOpen = true;

        genconn.on("started", function () {
            // initialize the connection w/ the generator
            genconn.sendMessage({
                messageType: IPCMessage.types.REGISTERCEP,
                extension: IPCMessage.clients.CEPID_PSPANEL
            });

            // We only want to record a panel open event on the first run. After that, if a new generator
            // connection is established (because generator went away and came back), we want to
            // get an updated device list.
            if (firstConnectionAfterOpen) {
                genconn.sendMessage({
                    messageType: IPCMessage.types.PANELOPENED
                });
                firstConnectionAfterOpen = false;
            } else {
                genconn.sendMessage({
                    messageType: IPCMessage.types.REQUESTDEVICELIST
                });
            }

            generatorConnected = true;
        });
    }

    function setPanelStatusAffordance(statusClass) {
        if (!$content.hasClass(statusClass)) {
            if ($getTheApp && $getTheApp.length > 0 && $getTheApp.hasClass("hidden")) {
                updateDeviceList([]);

                if (generatorConnected) {
                    // make sure we get an updated device list
                    genconn.sendMessage({
                        messageType: IPCMessage.types.REQUESTDEVICELIST
                    });
                }
            }

            $content.removeClass().addClass(statusClass);
        }
    }

    function setConnectionStatus(status) {
        switch(status) {
        case ConnectionStatus.READY_TO_PAIR:
            setPanelStatusAffordance(Affordance.READY_TO_PAIR);
            break;
        case ConnectionStatus.INITIALIZING:
        case ConnectionStatus.ONLINE:
        case ConnectionStatus.LOGGING_IN:
            setPanelStatusAffordance(Affordance.BUSY);
            break;
        case ConnectionStatus.NOT_LOGGED_IN:
            setPanelStatusAffordance(Affordance.NOT_LOGGED_IN);
            break;
        case ConnectionStatus.OFFLINE:
        case ConnectionStatus.ERROR:
            setPanelStatusAffordance(Affordance.OFFLINE);
            break;
        default:
            console.log("com.adobe.preview/PSPanel: unknown status " + status);
            // just assume we're ready to pair in this case...
            setPanelStatusAffordance(Affordance.READY_TO_PAIR);
        }
    }

    function init() {
        themeManager.init();

        TemplateManager.renderTemplate("getapp").then(function($template) {
            $getTheApp = $template;
            $content.html($getTheApp);

            ensureGeneratorRunning();

            // wait to start the generator connection until after the template renders
            setConnectionStatus(ConnectionStatus.INITIALIZING);
            setTimeout(_connectToGenerator(), 10);

            var event = new CSEvent(cepEvents.PANEL_OPENED, "APPLICATION");
            csInterface.dispatchEvent(event);
        });

        csInterface.addEventListener(IPCMessage.cepEvents.CONNECTION_STATUS, function (e) {
            setConnectionStatus(e.data.newStatus);
        });

        // note: this callback is never called.  Waiting for bug fix: https://watsonexp.corp.adobe.com/#bug=3754552
        window.cep.util.registerExtensionUnloadCallback(function() {
            genconn.sendMessage({
                messageType: IPCMessage.types.PANELCLOSED
            });
            
            // if we launched Generator but it was never used before closing the panel, then disable it
            if (generatorLaunched && !hasConnected) {
                disableRunningGenerator();
            }
        });

        $(window).resize(handleResize);

        $(document).on("contextmenu", function() {
            return false;
        });

        //setTimeout(addBogusDevices, 1000);
    }

    init();

}());
