define([
    "jquery"
    ], function (
        jq
     ) {

    "use strict";

    /**
     * @constructor
     */

    return function( options, context, metadata ){

        var backgroundPositions = {},
            imageButton,
            currentState,
            currentToggleState,
            ButtonState = {
                Default : "btn_state_default",
                Hover : "btn_state_hover",
                Pressed : "btn_state_pressed"
            },
            ButtonToggleState = {
                Pause : "btn_state_pause",
                Resume : "btn_state_resume"
            };

        backgroundPositions[ ButtonToggleState.Pause ] = {};
        backgroundPositions[ ButtonToggleState.Pause ][ ButtonState.Default ] = "0 0";
        backgroundPositions[ ButtonToggleState.Pause ][ ButtonState.Hover ] = "0 " + (-(options.image.height / 3)) + "px";
        backgroundPositions[ ButtonToggleState.Pause ][ ButtonState.Pressed ] = "0 " + (-2 * (options.image.height / 3)) + "px";

        backgroundPositions[ ButtonToggleState.Resume ] = {};
        backgroundPositions[ ButtonToggleState.Resume ][ ButtonState.Default ] = "-" + (options.image.width / 2) + "px 0";
        backgroundPositions[ ButtonToggleState.Resume ][ ButtonState.Hover ] = "-" + (options.image.width / 2) + "px " + (-(options.image.height / 3)) + "px";
        backgroundPositions[ ButtonToggleState.Resume ][ ButtonState.Pressed ] = "-" + (options.image.width / 2) + "px " + (-2 * (options.image.height / 3)) + "px";


        backgroundPositions[ ButtonState.Default ] = "0 0";
        backgroundPositions[ ButtonState.Hover ] = "0 " + (-options.image.height / 3) + "px";
        backgroundPositions[ ButtonState.Pressed ] = "0 " + (-2 * (options.image.height / 3)) + "px";

        function createButton() {
            currentState = ButtonState.Default;
            currentToggleState = ButtonToggleState.Pause;

            imageButton = jq(document.createElement("button"))
                .attr({
                    "title": options.tooltip,
                    "role": "button",
                    "tab-index": "0"
                })
                .css({
                    "width": (options.image.width / 2) + "px",
                    "height": (options.image.height / 3) + "px",
                    "padding": "0",
                    "border": "none",
                    "background": "none",
                    "background-image": "url(\"" + options.image.fileNameURL + "\")",
                    "background-position": backgroundPositions[ currentToggleState ][ currentState ],
                    "cursor": "pointer"
                })

            if (options.ariaLabel || options.tooltip) {
                imageButton.attr({
                    "aria-label": options.ariaLabel ? options.ariaLabel : options.tooltip
                })
            }
        }

        function getClassName( toggleState, buttonState ){
            return toggleState + "_" + buttonState;
        }

        function changeState( buttonState, toggleState ){
            if( !toggleState ){
                toggleState = currentToggleState;
            }

            if( !buttonState ){
                buttonState = currentState;
            }

            var oldClassName = getClassName( currentToggleState, currentState ),
                newClassName = getClassName( toggleState, buttonState );

            imageButton.removeClass( oldClassName );
            currentState = buttonState;
            currentToggleState = toggleState;
            imageButton.addClass( newClassName );

            imageButton.css({
                "background-position": backgroundPositions[toggleState][buttonState],
                "cursor": "pointer"
            });

            if (toggleState === ButtonToggleState.Pause) {
                imageButton.attr({
                    "title": options.tooltip,
                    "aria-label": options.ariaLabel ? options.ariaLabel : options.tooltip
                })
            } else {
                imageButton.attr({
                    "title": options.tooltipResume,
                    "aria-label": options.ariaLabelResume ? options.ariaLabelResume : options.tooltipResume
                })
            }

            if( currentState === buttonState ){
                return;
            }

            var enabled = buttonState !== ButtonState.Inactive;

            imageButton.removeClass( currentState );
            currentState = buttonState;
            imageButton.addClass( buttonState );
            imageButton.css({
                "background-position": backgroundPositions[buttonState],
                "cursor": enabled ? "pointer" : "default"
            });
        }

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

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

        function isOnTarget(e) {
            var elem = e.target,
                origEvent = e.originalEvent,
                changedTouch = origEvent.changedTouches && origEvent.changedTouches.length > 0 ? origEvent.changedTouches[0] : undefined;

            if (changedTouch) {
                elem = document.elementFromPoint(changedTouch.clientX, changedTouch.clientY);
            }

            return e.target === elem;
        }

        function pause() {
            context.stage.accessibility.turnAccessibilityModeOff();

            if ( currentToggleState == ButtonToggleState.Pause ) {
                changeState( ButtonState.Hover, ButtonToggleState.Resume );
            } else {
                changeState( ButtonState.Hover, ButtonToggleState.Pause );
            }

            context.stage.navigation.pause();
        }

        function onBlur() {
            var buttonState = ButtonState.Default,
                toggleState = currentToggleState;

            changeState(buttonState, toggleState);
            imageButton.off("focusout");
            imageButton.trigger("blur");
        }

        function onFocus() {
            var buttonState = ButtonState.Hover,
                toggleState = currentToggleState;

            changeState(buttonState, toggleState);
            imageButton.trigger("focus");
            imageButton.on("focusout", onBlur);
        }

        return {
            build : function(){
                createButton();
                return{
                    getElement : function(){
                        return imageButton.get(0);
                    },
                    onMouseLeave : function(){
                        changeState(ButtonState.Default, currentToggleState);
                    },
                    onMouseOver : function(){
                        changeState(ButtonState.Hover, currentToggleState);
                    },
                    onMouseDown : function(e){
                        lockNavigation();
                        e.preventDefault();
                        e.stopPropagation();
                        changeState(ButtonState.Pressed, currentToggleState);
                    },
                    onMouseUp : function(e){
                        unlockNavigation();
                        e.preventDefault();
                        e.stopPropagation();
                        changeState(ButtonState.Default, currentToggleState);

                        if(!isOnTarget(e)){
                            return;
                        }

                        pause();
                    },
                    onEnterPage : function(){
                        changeState(ButtonState.Default, ButtonToggleState.Pause);
                    },
                    pause: function () {
                        pause();
                        changeState( ButtonState.Default, currentToggleState );
                    },
                    focusButton: function () {
                        onFocus();
                    },
                    blurButton: function () {
                        onBlur();
                    }
                }
            }
        }
    }
});
