// com.tts.navigation.accessibility.handler
define( [
    "jquery"
],
    function (
        jq
    ) {

    "use strict";

    /**
        * @constructor
        */
    return function ( context, metadata ) {
        var shellElement,
            instance,
            buttonInitialized = false,
            isInAuthoringMode = false,
            registeredTabNavigations = new Array(),
            tabCounter = 0,
            isStandardPlayer = context.getPlayerName() === "standard",
            enableOnTab = metadata.parameters.asBool("enable-on-tab", false),
            alwaysOn = metadata.parameters.asBool("accessibility-always-on", false),
            stayAlwaysOn = metadata.parameters.asBool("stay-always-on", false),
            lastStateVariableName = "AccessibilityModeLastState",
            lastStateNamespace = "AccessibilityMode",
            selectionDirection = "next",
            allInactiveWatchdog = 0;


        // create an object shield so we are able to select and drag element
        function createAuthoringShield(shellElement) {
            var authoringView = jq(document.createElement("div"))
                    .css({
                        "width": "100%",
                        "height": "100%",
                        "display": "block",
                        "opacity": "0.15",
                        "background-image": "url(\"" + context.getPath() + "invis.png\")",
                        "overflow": "hidden"
                    }),
                caption = jq(document.createElement("span"))
                    .css({
                        "position": "absolute",
                        "display": "block",
                        "top": "100%",
                        "left": "5px",
                        "color": "#000000",
                        "font-size": "16px",
                        "line-height": "100%"
                    })
                    .text("TAB navigation hanlder");
            shellElement.append(authoringView).append(caption);
        }

        function createButton() {
            if ( buttonInitialized ) {
                return;
            }
            buttonInitialized = true;

            shellElement.attr({
                "aria-hidden": "true",
                "speak": "none",
                "tabindex": "-1"
            })
            .css({
                "width": metadata.getWidth() + "px",
                "height": metadata.getHeight() + "px",
                "display": "none",
                "visibility": "hidden"
            } );

            if ( isInAuthoringMode ) {
                createAuthoringShield( shellElement );
            }
        }

        function getRegisteredTabNavigations() {
            registeredTabNavigations = context.stage.variable.get("registeredTabNavigations", "tts");

            if (!registeredTabNavigations || !(registeredTabNavigations.length > 0)) {
                registeredTabNavigations = new Array();
            }
        }

        function orderRegisteredTabNavigations() {
            function compare(a, b) {
                if (a.order < b.order) {
                    return -1;
                }
                if (a.order > b.order) {
                    return 1;
                }
                return 0;
            }

            registeredTabNavigations.sort(compare);
        }

        function setNextTabNavigationSelection() {
            if (tabCounter >= registeredTabNavigations.length-1) {
                tabCounter = 0;
            } else {
                tabCounter = tabCounter + 1;
            }
        }

        function setPreviousTabNavigationSelection() {
            if (tabCounter <= 0) {
                tabCounter = registeredTabNavigations.length - 1;
            } else {
                tabCounter = tabCounter - 1;
            }
        }

        function resetTabNavigations() {
            registeredTabNavigations.length = 0;
            tabCounter = 0;
            allInactiveWatchdog = 0;
            context.stage.variable.set("registeredTabNavigations", false, "tts");
        }

        function setLastState(param) {
            context.stage.variable.set(lastStateVariableName, param, lastStateNamespace);
        }

        function getLastState() {
            var value = context.stage.variable.get(lastStateVariableName, lastStateNamespace);

            return value ? value : false;
        }

        function onEnableOnTab(e) {
            if (e.keyCode == 9) {
                context.stage.accessibility.turnAccessibilityModeOn();
            }
        }

		// revealing public API
		return {
			onLoading: function () {
                instance = this;
                if (!isStandardPlayer) {
                    context.page.event.bindOnEnter(instance);
                    context.page.event.bindOnExit(instance);
                    context.stage.accessibility.bindOnAccessibilityModeChanged(instance);
                    context.page.event.bind(instance, "onInactiveTabNavigationSelection");
                }
                shellElement = jq(context.getElement());
                isInAuthoringMode = !!context.stage.isInAuthoringMode();
                createButton();
            },

            onEnterPage: function () {
                if (!isStandardPlayer) {
                    if (enableOnTab) {
                        document.addEventListener('keyup', onEnableOnTab);
                    }
                }
            },

            onExitPage: function () {
                if (!isStandardPlayer) {
                    resetTabNavigations();
                    if (enableOnTab) {
                        document.removeEventListener('keyup', onEnableOnTab);
                    }
                }
            },

            onAllComponentsReady: function () {
                if (!isStandardPlayer) {
                    getRegisteredTabNavigations();
                    orderRegisteredTabNavigations();

                    if (alwaysOn) {
                        context.stage.accessibility.turnAccessibilityModeOn();
                        return;
                    }

                    if (stayAlwaysOn) {
                        var value = getLastState();

                        if (value) {
                            context.stage.accessibility.turnAccessibilityModeOn();
                        }
                        return;
                    }
                }
            },

            onAccessibilityModeChanged: function ( dataHTML5, dataHTML4 ) {
                if (!isStandardPlayer) {
                    var params = dataHTML4 || dataHTML5;

                    if (params.isActive) {
                        if (!alwaysOn && !stayAlwaysOn) {
                            tabCounter = 0;
                        }
                        
                        allInactiveWatchdog = registeredTabNavigations.length;
                        if (stayAlwaysOn) {
                            setLastState(true);
                        }
                        setTimeout(function () {
                            context.page.event.fire(instance, "onTabNavigationSelection", registeredTabNavigations[tabCounter]);
                        }, 10);
                    } else {
                        if (alwaysOn) {
                            allInactiveWatchdog = registeredTabNavigations.length;
                            setTimeout(function () {
                                context.stage.accessibility.turnAccessibilityModeOn();
                            }, 10);
                            return;
                        } 

                        if (stayAlwaysOn) {
                            var value = getLastState();

                            if (value) {
                                allInactiveWatchdog = registeredTabNavigations.length;
                                setTimeout(function () {
                                    context.stage.accessibility.turnAccessibilityModeOn();
                                }, 10);
                            }
                            return;
                        }

                        tabCounter = 0;
                        allInactiveWatchdog = 0;
                        setTimeout(function () {
                            context.page.event.fire(instance, "onTabNavigationOff");
                        }, 10);
                    }
                }
            },

            onAccessibilityKeyPressed: function (dataHTML5, dataHTML4) {
                if (!isStandardPlayer) {
                    var params = dataHTML4 || dataHTML5;

                    if (params.keyCode == 9 && !params.shiftPressed == true) {
                        setNextTabNavigationSelection();
                        selectionDirection = "next";
                        setTimeout(function () {
                            context.page.event.fire(instance, "onTabNavigationSelection", registeredTabNavigations[tabCounter]);
                        }, 10);
                    }
                    if (params.keyCode == 9 && params.shiftPressed == true) {
                        setPreviousTabNavigationSelection();
                        selectionDirection = "previous";
                        setTimeout(function () {
                            context.page.event.fire(instance, "onTabNavigationSelection", registeredTabNavigations[tabCounter]);
                        }, 10);
                    }
                    if (params.keyCode == 32 || params.keyCode == 13) {
                        setTimeout(function () {
                            context.page.event.fire(instance, "onTabNavigationFire", registeredTabNavigations[tabCounter]);
                        }, 10);
                    }
                }
            },

            onInactiveTabNavigationSelection: function (dataHTML5, dataHTML4) {
                if (!isStandardPlayer) {
                    if (selectionDirection === "next") {
                        setNextTabNavigationSelection();
                    }
                    if (selectionDirection === "previous") {
                        setPreviousTabNavigationSelection();
                    }
                    allInactiveWatchdog == allInactiveWatchdog - 1;
                    if (allInactiveWatchdog >= 0) {
                        setTimeout(function () {
                            context.page.event.fire(instance, "onTabNavigationSelection", registeredTabNavigations[tabCounter]);
                        }, 10);
                    } else {
                        tabCounter = 0;
                        allInactiveWatchdog = 0;
                        setTimeout(function () {
                            context.page.event.fire(instance, "onTabNavigationOff");
                        }, 10);
                    }
                }
            }
		};
	};
});
