define([
    "jquery",
    "./button.state",
    "./button.toggle.state"
],
function(
    jq,
    ButtonState,
    ButtonToggleState
){

    /**
     * @constructor
     */
    return function( options ){

        var buttonColors = {};

        buttonColors[ ButtonToggleState.On ] = {};
        buttonColors[ ButtonToggleState.On ][ ButtonState.Default ] = options.colors.default;
        buttonColors[ ButtonToggleState.On ][ ButtonState.Hover ] = options.colors.hover;
        buttonColors[ ButtonToggleState.On ][ ButtonState.Pressed ] = options.colors.pressed;
        buttonColors[ ButtonToggleState.On ][ ButtonState.Inactive ] = options.colors.inactive;

        buttonColors[ ButtonToggleState.Off ] = {};
        buttonColors[ ButtonToggleState.Off ][ ButtonState.Default ] = options.colors.default;
        buttonColors[ ButtonToggleState.Off ][ ButtonState.Hover ] = options.colors.hover;
        buttonColors[ ButtonToggleState.Off ][ ButtonState.Pressed ] = options.colors.pressed;
        buttonColors[ ButtonToggleState.Off ][ ButtonState.Inactive ] = options.colors.inactive;

        function createSvgPath(){

            return  '<svg id="' + options.id + '" width="' + options.width + 'px" height="' + (options.height * 4) + 'px" viewBox="0 0 44 176" preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background-color: transparent;">' +
                '<title>' + options.caption +'</title>' +
                '<defs></defs>' +
                '<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">' +
                '<g>' +
                '<g class="NavigationButton" transform="translate(0.000000, 0.000000)" fill="' + options.colors.default.bg + '">' +
                '<rect x="0" y="0" width="44" height="44"></rect>' +
                '<path class="NavigationButtonIcon_On" display="block" fill="' + options.colors.default.icon + '" d="M10,17.4712117 L15.5643778,17.4712117 L22.5689468,10.3199997 L22.5689468,33.1771426 L15.5643778,26.0259317 L10,26.0259317 L10,17.4712117 Z M24.8542099,17.1771426 L27.139473,17.1771426 L27.139473,26.3199997 L24.8542099,26.3199997 L24.8542099,17.1771426 Z M29.424736,13.7485711 L31.7099991,13.7485711 L31.7099991,29.7485711 L29.424736,29.7485711 L29.424736,13.7485711 Z" id="Combined-Shape" fill-rule="nonzero"></path>' +
                '<path class="NavigationButtonIcon_Off" display="none" fill="' + options.colors.default.icon + '" d="M15.534968,17.4859471 L10,11.9509792 L11.9509792,10 L34,32.0490208 L32.0490208,34 L22.5714286,24.5224077 L22.5714286,33.191878 L15.5654765,26.0406671 L10,26.0406671 L10,17.4859471 L15.534968,17.4859471 Z M18.8467355,14.1366551 L22.5714286,10.3347351 L22.5714286,17.8613482 L18.8467355,14.1366551 Z M27.1428571,22.4327768 L24.8571429,20.1470625 L24.8571429,17.191878 L27.1428571,17.191878 L27.1428571,22.4327768 Z M31.7142857,27.0042053 L29.4285714,24.718491 L29.4285714,13.7633065 L31.7142857,13.7633065 L31.7142857,27.0042053 Z" id="Combined-Shape" fill-rule="nonzero"></path>' +
                '</g>' +
                '</g>' +
                '</g>' +
                '</svg>';
        }

        function createButton(){

            var currentState = ButtonState.Default,
                currentToggleState = ButtonToggleState.On,
                svgButton = jq(document.createElement("div")),
                svg = svgButton.html( createSvgPath() )
                    .contents()
                    .addClass("sc-navigation")
                    .addClass("ttsButtonSoundOnOff")
                    .css({
                        "pointer-events" : "none"
                    })
                    .on("touchmove", function(e) {
                        e.preventDefault ? e.preventDefault() : true;
                    })
                    .get(0);

            var svgWrapper = jq(document.createElement("button"))
                .attr({
                    "title": options.caption,
                    "class": getClassName(currentToggleState, currentState),
                    "role": "button",
                    "tab-index": "0"
                })
                .css({
                    "cursor": "pointer",
                    "width": options.width + "px",
                    "height": options.height + "px",
                    "overflow": "hidden",
                    "padding": "0",
                    "border": "none",
                    "background": "none"
                });

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

            function changeState(buttonState, toggleState) {

                if (!toggleState) {
                    toggleState = currentToggleState;
                }

                if (!buttonState) {
                    buttonState = currentState;
                }

                var colors = buttonColors[toggleState][buttonState],
                    jqSvg = jq(svg),
                    oldClassName = getClassName(currentToggleState, currentState),
                    newClassName = getClassName(toggleState, buttonState);

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

                if (toggleState === ButtonToggleState.On) {
                    jqSvg.find("[class=NavigationButtonIcon_Off]").attr("display", "none");
                    jqSvg.find("[class=NavigationButtonIcon_On]").attr("display", "block");
                    jqSvg.find("[class=NavigationButtonIcon_On]").attr("fill", colors.icon);
                }
                else {
                    jqSvg.find("[class=NavigationButtonIcon_On]").attr("display", "none");
                    jqSvg.find("[class=NavigationButtonIcon_Off]").attr("display", "block");
                    jqSvg.find("[class=NavigationButtonIcon_Off]").attr("fill", colors.icon);
                }

                jqSvg.find("[class=NavigationButton]").attr("fill", colors.bg);
                jqSvg.css({
                    "cursor": buttonState !== ButtonState.Inactive ? "pointer" : "default"
                });
                if (currentToggleState === ButtonToggleState.On) {
                    if (options.ariaLabel || options.caption) {
                        svgWrapper.attr({
                            "title": options.caption,
                            "aria-label": options.ariaLabel ? options.ariaLabel : options.caption
                        })
                    }
                } else {
                    if (options.ariaLabel || options.caption) {
                        svgWrapper.attr({
                            "title": options.captionOff,
                            "aria-label": options.ariaLabelOff ? options.ariaLabelOff : options.captionOff
                        })
                    }
                }
            }

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

                changeState(buttonState, toggleState);

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

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

                changeState(buttonState, toggleState);

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

            svgWrapper.append(svg);

            return {
                getHotspotElement : function(){
                    return svgWrapper.get(0);
                },
                hasState : function( buttonState ){
                    return buttonState === currentState;
                },
                hasToggleState : function( buttonToggleState ){
                    return buttonToggleState === currentToggleState;
                },
                changeState : function( buttonState, toggleState ){
                    changeState(buttonState, toggleState);
                },
                focusButton: function () {
                    onFocus();
                },
                blurButton: function () {
                    onBlur();
                }
            };
        }

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

        return {
            build : createButton
        };
    };
});
