define([
    "jquery",
    "./accessibility.builder"
],
    function (
        jq,
        AccessibilityBuilder
     ) {

    "use strict";

    /**
     * @constructor
     */

    return function( options, context, metadata ){

        var backgroundPositions = {},
            imageButton,
            textContainer,
            currentState,
            ButtonState = {
                Default: "btn_state_default",
                Hover: "btn_state_hover",
                Pressed: "btn_state_pressed"
            },
            accessibilityTooltip;

        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( {
                    "id": options.name,
                    "class": options.name,
                    "role": "button"
                } )
                .css( {
                    "width": options.image.width + "px",
                    "height": options.image.height / 3 + "px",
                    "text-align": options.label.horizontalAlign,
                    "padding": "0",
                    "border": "none",
                    "background": "none",
                    "background-image": "url(\"" + options.image.fileNameURL + "\")",
                    "background-position": backgroundPositions[currentState],
                    "background-repeat": "no-repeat",
                    "color": options.label.fontColor,
                    "font-family": options.label.fontFamily,
                    "font-size": options.label.fontSize + "px"
                } );

            imageButton.css(options.css);

            if (options.showLabel && options.label) {
                imageButton.attr({
                    "title": options.label.text
                })
            }

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

            if (options.label.verticalAlign === "middle") {
                imageButton.css("display", "table");
            }

            imageButton.append( createTextContent() );

            accessibilityTooltip = new AccessibilityBuilder(options.accessibilityKey, options.accessibilityLocation, options.accessibilityPositionX, options.accessibilityPositionY).build();
            if (accessibilityTooltip.getElement()) {
                imageButton.append( accessibilityTooltip.getElement() );
            }
        }

        function createTextContent() {
            textContainer = jq(document.createElement("div"))
                .attr({
                    "id": options.name + "TextContainer"
                })
                .css({
                    "width": options.image.width + "px",
                    "padding-right": options.label.paddingRight + "px",
                    "padding-left": options.label.paddingLeft + "px"
                });

            if (options.label.verticalAlign === "middle") {
                textContainer.css({
                        "display": "table-cell",
                        "vertical-align": "middle"
                    });
            }
            else {
                textContainer.css({
                        "position": "absolute",
                        "padding-top": options.label.paddingTop + "px",
                        "padding-bottom": options.label.paddingBottom + "px"
                    });

                textContainer.css(options.label.verticalAlign, "0");

                if( options.label.horizontalAlign === "right" ) {
                    textContainer.css(options.label.horizontalAlign, "0");
                }
            }

            if(options.label.tooltip){
                textContainer
                    .attr({
                        "title" : options.tooltip
                    })
            }

            if ( options.showLabel ) {
                textContainer.html( options.label.text );
            }
            return textContainer;
        }

        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 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 cancelEvent( e ) {
            if ( e && e.preventDefault ) {
                e.preventDefault();
            }

            if ( e && e.stopPropagation ) {
                e.stopPropagation();
            }

            return false;
        }

        return {
            build : function(){
                createButton();
                return {
                    getElement: function () {
                        return imageButton.get(0);
                    },
                    changeImage: function (width, height, filename) {

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

                        imageButton.css({
                            "width": width + "px",
                            "height": height + "px",
                            "background-image": "url(\"" + filename + "\")",
                            "background-position": backgroundPositions[currentState]
                        });
                    },
                    getAccessibilityKeyCode: function () {
                        return accessibilityTooltip.getKeyCode();
                    },
                    onMouseLeave : function(){
                        changeState( ButtonState.Default );
                        textContainer.css( {
                            "color": options.label.fontColor
                        })
                    },
                    onMouseOver : function(){
                        changeState( ButtonState.Hover );
                        textContainer.css( {
                            "color": options.label.fontColorHover
                        } )
                    },
                    onMouseDown : function(e){
                        lockNavigation();
                        cancelEvent( e );
                        changeState( ButtonState.Pressed );
                        textContainer.css( {
                            "color": options.label.fontColorPressed
                        } )
                    },
                    onMouseUp : function(e){
                        unlockNavigation();
                        cancelEvent( e );
                        changeState( ButtonState.Hover );
                        textContainer.css( {
                            "color": options.label.fontColorHover
                        } )

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

                        if(options.action){
                            options.action();
                        }
 
                        changeState( ButtonState.Default );
                        textContainer.css( {
                            "color": options.label.fontColor
                        } )
                    },
                    showAccessibilityTooltip: function () {
                        accessibilityTooltip.show();
                    },
                    hideAccessibilityTooltip: function () {
                        accessibilityTooltip.hide();
                    }
                }
            }
        }
    }
});