// com.tts.initial.html5.play.modes
define( [
    "jquery",
    "./playmodes.builder",
    "./locals",
    "./accessibility.builder"
],
function (
    jq,
    PlaymodesBuilder,
    uiText,
    AccessibilityBuilder
){

    "use strict";

    /**
     * @constructor
     */

    return function (context, metadata) {

        var shellElement,
            button,
            buttonInitialized = false,
            isInAuthoringMode = false,
            isInPreviewMode = false,
            pointerUpEventName, pointerDownEventName, pointerMoveEventName, pointerLeaveEventName,
            fonts = [
                'Arial, Helvetica, sans-serif',
                '"Times New Roman", Times, serif',
                'Verdana, Geneva, sans-serif',
                '"Courier New", Courier, monospace',
                'Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif',
                '"Droid Serif", "Times New Roman", Times, serif'
            ],
            accessinilityTooltipsMenuDiv,
            accessibilityTooltipMode,
            accessibilityTooltipInteractive,
            accessibilityKeyMode = metadata.parameters.get( "accessibility-key-mode", null ),
            accessibilityLocation = metadata.parameters.asNumber( "accessibility-location", 0 ),
            accessibilityPositionX = metadata.parameters.asNumber( "accessibility-position-x", -6 ),
            accessibilityPositionY = metadata.parameters.asNumber( "accessibility-position-y", -6 );

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

            initPointerEventNames();

            var scParams = metadata.parameters,
                imageArray = {
                    button : loadImage("button", scParams.get("bg_image", null)),
                    marker : loadImage("marker", scParams.get("marker_image", null))
                };

            button = new PlaymodesBuilder({
                pointerEvents : {
                    pointerUp : pointerUpEventName,
                    pointerDown : pointerDownEventName,
                    pointerMove : pointerMoveEventName,
                    pointerLeave : pointerLeaveEventName
                },
                instanceID : metadata.getId(),
                AuthoringMode : isInAuthoringMode,
                PreviewMode : isInPreviewMode,

                menuWidth : scParams.asNumber("menu_width", "200"),
                menuHeight : scParams.asNumber("menu_height", "64"),
                position : scParams.asNumber("menu_location", "1"),
                menuPositionX: scParams.asNumber("menu_position_x", "0"),
                menuPositionY: scParams.asNumber("menu_position_y", "0"),
                borderColor : scParams.get("border_color", "#999999"),
                borderWidth : scParams.asNumber("border_width", "2"),
                borderTransparency : (scParams.asNumber("border_transparency", "0")),
                fillColor : scParams.get("fill_color", "#ffffff"),
                fillTransparency : (scParams.asNumber("fill_color_transparency", "0")),
                separatorColor : scParams.get("separator_color", "#d1d1d1"),
                separatorWidth : scParams.asNumber("separator_width", "2"),
                separatorTransparency : (scParams.asNumber("separator_transparency", "0")),

                image : imageArray,

                fontFamily : getFont(scParams.get("font_family","0")),
                fontSize : scParams.get("font_size", "14"),
                textColor : scParams.get("text_color", "#142534"),
                textHoverColor : scParams.get("text_hover_color", "#fd7326"),
                textBackgroundColor : scParams.get("text_background_color", "#fd7e2f"),
                textBackgroundHoverColor : scParams.get("text_background_hover_color", "#fd7e2f"),
                paddingLeft : scParams.asNumber("padding_left", "10"),
                paddingRight : scParams.asNumber("padding_right", "10"),
                paddingTop : scParams.asNumber("padding_top", "2"),
                paddingBottom : scParams.asNumber("padding_bottom", "2"),

                entryTexts : {
                    interactive : getText( "text_interactive", "player.navigation.modes.interactive"),
                    presentation : getText( "text_presentation", "player.navigation.modes.presentation" ),
                    film : getText( "text_film", "player.navigation.modes.film" )
                },
                caption : getText("tooltip","player.navigation.modes.tooltip"),

                showMenuInAuthoringMode: scParams.asBool( "show_menu_in_authoring_mode" ),

                accessibilityKeys: {
                    interactive: metadata.parameters.get( "accessibility-key-interactive", null ),
                    presentation: metadata.parameters.get( "accessibility-key-presentation", null ),
                    film: metadata.parameters.get( "accessibility-key-film", null ),
                    accessibilityLocation: accessibilityLocation,
                    accessibilityPositionX: accessibilityPositionX,
                    accessibilityPositionY: accessibilityPositionY
                }
            }, context, metadata).build();

            shellElement.css({
                "width": (imageArray.button.width / 3) + "px",
                "height": (imageArray.button.height / 3) + "px"
            });

            shellElement.append( button.getElement() );

            if ( accessibilityKeyMode ) {
                accessibilityTooltipMode = new AccessibilityBuilder( accessibilityKeyMode, accessibilityLocation, accessibilityPositionX, accessibilityPositionY ).build();
                shellElement.append( accessibilityTooltipMode.getElement() );
            }

            accessinilityTooltipsMenuDiv = jq( document.createElement( "div" ) )
                .css( {
                    "position": "absolute",
                    "top": -scParams.asNumber( "menu_position_y", "0" ) + "px",
                    "left": -scParams.asNumber( "menu_position_x", "0" ) + "px",
                    "width": "0px",
                    "height": scParams.asNumber( "menu_height", "64" ) + "px"
                } );

            if ( metadata.parameters.get( "accessibility-key-interactive", null ) ) {
                accessibilityTooltipInteractive = new AccessibilityBuilder( metadata.parameters.get( "accessibility-key-interactive", null ), accessibilityLocation, accessibilityPositionX, accessibilityPositionY ).build();
                accessinilityTooltipsMenuDiv.append( accessibilityTooltipInteractive.getElement() );
            }

            shellElement.append( accessinilityTooltipsMenuDiv );

            context.page.interaction.provokesFeedback( button.getHotSpotElement(), false );
            context.page.interaction.provokesAutosolve( button.getHotSpotElement(), false );

            if (isInAuthoringMode) {
                createAuthoringShield();
            }
        }

        function getText( parameterName, defaultTextName ) {
            var paramValue = jq.trim( metadata.parameters.get(parameterName,"") );
			return ( paramValue.length > 0 ) ? paramValue : uiText.get( defaultTextName, metadata.stage.getContentLanguage() );
        }

        function loadImage(key, image) {

            var result = {};

                if (image) {
                    result.fileNameURL = context.stage.getSharedPath() + image.fileName;
                    result.width = image.width;
                    result.height = image.height;
                }
                else {
                    switch(key){
                        case "button": 
                            result.fileNameURL = context.getPath() + "playmodes.png";
                            result.width = 150;
                            result.height = 150;
                            break;
                        case "marker": 
                            result.fileNameURL = context.getPath() + "marker.png";
                            result.width = 14;
                            result.height = 14;
                            break;
                        default:
                            return null;
                    } 
                }      

            return result;
        }

        function getFont( index ) {
            var fontIndex = (index > 0 && index < fonts.length) ? index-1: 0;
            return fonts[fontIndex];
        }

         // create an object shield so we are able to select and drag element
         function createAuthoringShield() {
            shellElement.append(jq(document.createElement("div"))
                .css({
                    "position": "absolute",
                    "left": 0,
                    "top": 0,
                    "background-color": "transparent",
                    "opacity": "0.4",
                    "width": "100%",
                    "height": "100%",
                    "z-index": "9999"
                }));
        }

        function initPointerEventNames() {
            if( !pointerUpEventName ) {
                var nodeName = getHotspotElementNodeName();

                pointerUpEventName = context.device.getDownEvents( nodeName );
                pointerDownEventName = context.device.getUpEvents( nodeName );
                pointerMoveEventName = context.device.getMoveEvents( nodeName );
                pointerLeaveEventName = context.device.getReleaseEvents( nodeName );
            }
        }

        function cancelEvent( e ){
            e.preventDefault();
            e.stopPropagation();
        }

        function bindEvents() {

            if (context.stage.isInAuthoringMode()) {
                return;
            }

            if (!button || !buttonInitialized) {
                return;
            }

            removeEvents();
            context.device.attachFirstSupportedEvent( button.getHotSpotElement(), pointerDownEventName, button.onMouseDown );
            context.device.attachFirstSupportedEvent( button.getHotSpotElement(), pointerMoveEventName, button.onMouseOver );
            context.device.attachFirstSupportedEvent( button.getHotSpotElement(), pointerLeaveEventName, button.onMouseLeave );
            context.device.attachFirstSupportedEvent( button.getHotSpotElement(), pointerUpEventName, button.onMouseUp );

            jq(button.getHotSpotElement()).on("dblclick", cancelEvent );
        }

        function removeEvents() {
            unlockNavigation();
            if (!button || !buttonInitialized) {
                return;
            }

            initPointerEventNames(shellElement);
            context.device.removeFirstSupportedEvent( button.getHotSpotElement(), pointerDownEventName, button.onMouseDown );
            context.device.removeFirstSupportedEvent( button.getHotSpotElement(), pointerMoveEventName, button.onMouseOver );
            context.device.removeFirstSupportedEvent( button.getHotSpotElement(), pointerLeaveEventName, button.onMouseLeave );
            context.device.removeFirstSupportedEvent( button.getHotSpotElement(), pointerUpEventName, button.onMouseUp );

            jq(button.getHotSpotElement()).off("dblclick", cancelEvent );
        }

        function getHotspotElementNodeName() {
            return shellElement.get(0).nodeName
                ? shellElement.get(0).nodeName
                : "document";
        }

        function initializePlayMode(){

            var defaultPlayMode = metadata.stage.getDefaultPlayMode(),
                individualPlayMode = metadata.page.getIndividualPlayMode(),
                playMode = individualPlayMode !== "none" ? individualPlayMode : defaultPlayMode;

            if (playMode === "presentation") {
                button.setPresentationMode();
                return;
            }

            if (playMode === "film") {
                button.setFilmMode();
                return;
            }

            button.setInteractiveMode();
        }

        function unlockNavigation() {
            if (context.stage.isInAuthoringMode() || (typeof(context.stage.trigger) === "undefined")) {
                return;
            }
            context.stage.trigger.unlock( metadata.getId() );
        }

        // revealing public API
        return {
            onLoading: function () {

                context.page.event.bindOnEnter(this);
                context.page.event.bindOnExit(this);
                context.stage.event.bindOnPlayModeChanged( this );
                context.stage.accessibility.bindOnAccessibilityModeChanged( this );

                shellElement = jq(context.getElement());

                isInAuthoringMode = !!context.stage.isInAuthoringMode();
                isInPreviewMode = !!context.stage.isInPreviewMode();

                initializeButton(shellElement);
            },
            onPlayModeChanged: function (dataHTML5, dataHTML4) {
                var params = dataHTML4 || dataHTML5;

                if ( params.mode === "presentation" ) {
                    button.setPresentationMode();
                    return;
                }

                if ( params.mode === "film" ) {
                    button.setFilmMode();
                    return;
                }

                button.setInteractiveMode();
            },
            onEnterPage: function() {
                button.onEnterPage();
                initializePlayMode();
                bindEvents();
            },
            onExitPage: function() {
                removeEvents();
                context.stage.accessibility.turnAccessibilityModeOff();
                button.onExitPage();
            },
            onAccessibilityModeChanged: function ( dataHTML5, dataHTML4 ) {
                var params = dataHTML4 || dataHTML5;

                if ( params.isActive ) {
                    accessibilityTooltipMode.show();
                    button.showAccessibilityTooltips();
                } else {
                    accessibilityTooltipMode.hide();
                    button.hideAccessibilityTooltips();
                }
            },
            onAccessibilityKeyPressed: function ( dataHTML5, dataHTML4 ) {
                var params = dataHTML4 || dataHTML5;

                if ( params.keyCode == accessibilityTooltipMode.getKeyCode() ) {
                    button.toggleMenu();
                    return;
                }

                var accessibilityKeys = button.getAccessibilityKeyCodes();

                if ( params.keyCode == accessibilityKeys.interactive ) {
                    context.stage.accessibility.turnAccessibilityModeOff();
                    button.setInteractiveMode();
                    return;
                }

                if ( params.keyCode == accessibilityKeys.presentation ) {
                    context.stage.accessibility.turnAccessibilityModeOff();
                    button.setPresentationMode();
                    return;
                }

                if ( params.keyCode == accessibilityKeys.film ) {
                    context.stage.accessibility.turnAccessibilityModeOff();
                    button.setFilmMode();
                    return;
                }
            }
        };
    };
});
