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

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

        var buttonColors = {},
            currentState = ButtonState.Default,
            currentToggleState = ButtonToggleState.On,
            svgButton,
            svgWrapper,
            svg;

        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 hasState( buttonState ) {
            return buttonState === currentState;
        }

        function hasToggleState( buttonToggleState ) {
            return buttonToggleState === currentToggleState;
        }

        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"
            } );
        }

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

            svgWrapper = jq(document.createElement("div"))
                .attr({
                    "title" : options.caption,
                    "class" : getClassName( currentToggleState, currentState )
                })
                .css({
                    "cursor": "pointer",
                    "width": options.width + "px",
                    "height": options.height + "px",
                    "overflow": "hidden"
                } )
                .addClass( options.name )
                .append( svg );

            return {
                getElement : function(){
                    return svgWrapper.get(0);
                },
                onMouseOver: function () {
                    if ( !hasState( ButtonState.Pressed ) ) {
                        changeState( ButtonState.Hover, currentToggleState );
                    }
                },
                onMouseLeave: function () {
                    changeState( ButtonState.Default, currentToggleState );
                },
                onMouseDown: function () {
                    changeState( ButtonState.Pressed, currentToggleState );
                },
                onMouseUp: function () {
                    if ( hasToggleState( ButtonToggleState.On ) ) {
                        changeState( ButtonState.Default, ButtonToggleState.Off );
                    } else {
                        changeState( ButtonState.Default, ButtonToggleState.On );
                    }
                },
                toggleIcon: function () {
                    if ( hasState( ButtonState.On ) ) {
                        changeState( ButtonState.Off );
                    } else {
                        changeState( ButtonState.On )
                    }
                },
                onExitPage: function () {
                    changeState( ButtonState.Default, ButtonToggleState.On );
                },
                hideIcon: function () {
                    button.hide();
                },
                showIcon: function () {
                    button.show();
                },
                setLeftPosition: function ( xValue ) {
                    svgWrapper.css( {
                            "left": xValue + "px"
                        } )
                }
            };
        }

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

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