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

    "use strict";

    /**
     * @constructor
     */

    return function( options, context, metadata ){

        var backgroundPositions = {},
            imageButton,
            currentState,
            ButtonState = {
                Default : "btn_state_default",
                Hover : "btn_state_hover",
                Pressed : "btn_state_pressed"
            },
            isStandardPlayer = context.getPlayerName() === "standard";
        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;

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

            if (options.caption) {
                imageButton.attr({
                    "title": options.caption
                })
            }

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

        function changeState ( buttonState ){

            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 fireTriggerOnMouseOver(){
            setTimeout(function(){
                context.page.event.trigger(options.instance, "tg_mouseover");
            }, 10);
        }

        function fireTriggerOnMouseLeave(){
            setTimeout(function(){
                context.page.event.trigger(options.instance, "tg_mouseleave");
            }, 10);
        }

        function fireTriggerOnUp(){
            setTimeout(function(){
                context.page.event.trigger(options.instance, "tg_pressed");
            }, 10);
        }

        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;

            if ( !origEvent ) {
                return true;
            } else {
                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 cancelEvent(e){
            if ( isStandardPlayer ) {
                e.preventDefault();
                e.stopPropagation();
            }
        }

        function onBlur() {
            changeState(ButtonState.Default);

            imageButton.off("focusout");
            imageButton.trigger("blur");
        }

        function onFocus() {
            changeState(ButtonState.Hover);

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

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

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

                        fireTriggerOnUp();
                    },
                    onAccessibilityKeyPressed: function () {
                        changeState(ButtonState.Hover);
                        fireTriggerOnUp();
                        changeState(ButtonState.Default);
                    },
                    focusButton: function () {
                        onFocus();
                    },
                    blurButton: function () {
                        onBlur();
                    }
                }
            }
        }
    }
});
