// com.tts.initial.html5.quiz.result.back
// HTML4 / HTML5: No dif
define([
    "jquery",
    "./locals",
    "./button.state",
    "./image.button.builder",
    "./svg.button.builder"
],
function(
    jq,
    uiText,
    ButtonState,
    ImageButtonBuilder,
    SvgButtonBuilder
){

	"use strict";

    /**
	 * @constructor
	 */
	return function (context, metadata) {
        var shellElement,
            button,
            buttonInitialized = false,
            m_buttonEnabled = false,
            isStandardPlayer = context.getPlayerName() === "standard",
            allPages,
			pageId = metadata.page.getId(),
            hasStageTriggerSupport = true,
            isInAuthoringMode = false,
            lastVisitedEvaluationPageId,
            lastVisitedEvaluationPage,
            pointerUpEventNames,
            pointerDownEventNames,
            pointerMoveEventNames,
            pointerLeaveEventNames;

        function loadBackgroundImage() {

			var deferred = jq.Deferred(),
				defaultImage = new Image(),
				metadataParameters = metadata.parameters,
				backgroundImage = metadataParameters.get("bg_image", null),
				backgroundFileName,
				result = {};

			defaultImage.onload = function() {
				result.width = this.width;
				result.height = this.height / 3;
				deferred.resolve(result);
			};

			if (backgroundImage) {
				backgroundFileName = context.stage.getSharedPath() + backgroundImage.fileName;
			}
			else {
				backgroundFileName = context.getPath() + "back_to_quiz_result.png";
			}

			result.fileName = backgroundFileName;
			defaultImage.src = backgroundFileName;

			return deferred.promise();
		}

		// create an object shield so we are able to select and drag element
		function createAuthoringShield(shellElement) {
			shellElement.append(jq(document.createElement("div"))
				.css({
					"position": "absolute",
					"left": 0,
					"top": 0,
					"background-color": "transparent",
					"opacity": "0.4",
					"width": "100%",
					"height": "100%",
					"z-index": "9999"
				}));
		}

		function lockNavigation() {
			if (isInAuthoringMode || (!hasStageTriggerSupport)) {
				return;
			}
			context.stage.trigger.lock(metadata.getId());
		}

		function unlockNavigation() {
			if (isInAuthoringMode || (!hasStageTriggerSupport)) {
				return;
			}
			context.stage.trigger.unlock(metadata.getId());
		}

		function onMouseOver() {
            if( !button.hasState( ButtonState.Pressed ) ) {
                button.changeState( ButtonState.Hover );
            }
		}

		function onMouseDown() {
			lockNavigation();
            button.changeState( ButtonState.Pressed );
		}

		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 onMouseUp(e) {
			unlockNavigation();
            button.changeState( ButtonState.Default );

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

            if ( lastVisitedEvaluationPageId && lastVisitedEvaluationPage ) {
                if ( context.getPlayerName() == "html5" ) {
                    cancelEvent();
                    context.stage.navigation.gotoPageById( lastVisitedEvaluationPageId );
                } else {
                    cancelEvent();
                    context.stage.navigation.gotoPage( lastVisitedEvaluationPage );
                }
            }
        }

        function isPageBefore( pageId1, pageId2 ) {
            var isBefore = false;

            for ( var i = 0; i < allPages.length; i++ ) {
                if ( allPages[i].getId() == pageId1 ) {
                    isBefore = true;
                    break;
                }
                if( allPages[i].getId() == pageId2 ) {
                    isBefore = false;
                    break;
                }
            }

            return isBefore;
        }

		function enableButton(){
			if (buttonInitialized && !m_buttonEnabled) {

			    button.changeState( ButtonState.Default );

				bindEvents();

				m_buttonEnabled = true;
			}
		}

		function onMouseLeave() {
			unlockNavigation();
            button.changeState( ButtonState.Default );
		}

        function initPointerEventNames() {
            if( !pointerUpEventNames ) {
                var nodeName = getHotspotElementNodeName();
                pointerDownEventNames = context.device.getDownEvents( nodeName );
                pointerUpEventNames = context.device.getUpEvents( nodeName );
                pointerMoveEventNames = context.device.getMoveEvents( nodeName );
                pointerLeaveEventNames = context.device.getReleaseEvents( nodeName );
            }
        }

        function getHotspotElementNodeName() {
            return button.getHotspotElement().nodeName
                ? button.getHotspotElement().nodeName
                : "document";
        }

		function bindEvents() {

			if (isInAuthoringMode) {
				return;
			}

            if (!button || !buttonInitialized) {
                return;
            }

            removeEvents();
            context.device.attachFirstSupportedEvent( button.getHotspotElement(), pointerDownEventNames, onMouseDown );
            context.device.attachFirstSupportedEvent( button.getHotspotElement(), pointerMoveEventNames, onMouseOver );
            context.device.attachFirstSupportedEvent( button.getHotspotElement(), pointerLeaveEventNames, onMouseLeave );
            context.device.attachFirstSupportedEvent( button.getHotspotElement(), pointerUpEventNames, onMouseUp );
        }

        function removeEvents() {
            unlockNavigation();
            if (!button || !buttonInitialized) {
                return;
            }

            initPointerEventNames();
            context.device.removeFirstSupportedEvent( button.getHotspotElement(), pointerDownEventNames, onMouseDown );
            context.device.removeFirstSupportedEvent( button.getHotspotElement(), pointerMoveEventNames, onMouseOver );
            context.device.removeFirstSupportedEvent( button.getHotspotElement(), pointerLeaveEventNames, onMouseLeave );
            context.device.removeFirstSupportedEvent( button.getHotspotElement(), pointerUpEventNames, onMouseUp );
        }

		function initializeButton(){
            if( buttonInitialized ){
                return;
            }
            buttonInitialized = true;

            shellElement.css({
                "width": metadata.getWidth() + "px",
                "height": metadata.getHeight() + "px"
            });

            button = metadata.parameters.asBool( "use_svg" ) ? createSvgButton() : createImageButton();
            shellElement.append( button.getHotspotElement() );

            context.page.interaction.provokesAutosolve( button.getHotspotElement(), false );

            enableButton();

            if (isInAuthoringMode) {
                createAuthoringShield( shellElement );
            }
		}

        function createImageButton(){

            var scParams = metadata.parameters,
                imageButton = new ImageButtonBuilder({
                    width: metadata.getWidth(),
                    height: metadata.getHeight(),
                    caption: uiText.get("player.navigation.button.back_to_overall_evaluation", metadata.stage.getContentLanguage()),
                    color : scParams.get("color", "#919191"),
                    text : {
                        content : scParams.get("text", ""),
                        fontFamily : getFontStyle( scParams.asNumber("font-family", "1") ),
                        fontSize : scParams.asNumber("font-size", "14"),
                        orientation : scParams.get("text_orientation", "center"),
                        verticalAlignment: scParams.get("text_vertical_align", "middle"),
                        paddingLeft : Math.abs(scParams.asNumber("padding-left", "10")),
                        paddingRight : Math.abs(scParams.asNumber("padding-right", "10")),
                        paddingTop : Math.abs(scParams.asNumber("padding-top", "10")),
                        paddingBottom : Math.abs(scParams.asNumber("padding-bottom", "10"))
                    }
                }).build();

            loadBackgroundImage().then( function( buttonImage ) {
                applyButtonImage( buttonImage );
            });

            return imageButton;
        }

		function createSvgButton() {

            var scParams = metadata.parameters;
            return new SvgButtonBuilder({
                id: "svg_" + pageId + "_" + metadata.getId(),
                width: metadata.getWidth(),
                height: metadata.getHeight(),
                caption: uiText.get("player.navigation.button.next", metadata.stage.getContentLanguage()),
                colors: {
                    default: {
                        icon: scParams.get("color_svg_icon_default", "#ffffff"),
                        bg: scParams.get("color_svg_background_default", "#707070")
                    },
                    hover: {
                        icon: scParams.get("color_svg_icon_hover", "#ffffff"),
                        bg: scParams.get("color_svg_background_hover", "#fd7e2f")
                    },
                    pressed: {
                        icon: scParams.get("color_svg_icon_pressed", "#ffffff"),
                        bg: scParams.get("color_svg_background_pressed", "#df7a3b")
                    },
                    inactive: {
                        icon: scParams.get("color_svg_icon_inactive", "#a9a9a9"),
                        bg: scParams.get("color_svg_background_inactive", "#707070")
                    }
                }
            }).build();
        }

        function getFontStyle( paramValue ) {
            switch( paramValue ) {
                case 2:
                    return "\"Times New Roman\", Times, serif";
                case 3:
                    return "Verdana, Geneva, sans-serif";
                case 4:
                    return "\"Courier New\", Courier, monospace";
                default:
                    return "Arial, Helvetica, sans-serif";
            }
        }

        function applyButtonImage( buttonImage ){

            var buttonWidth = buttonImage.width,
                buttonHeight = buttonImage.height;

            shellElement.css({
                "width": buttonWidth + "px",
                "height": buttonHeight + "px"
            });

            button.changeImage( buttonWidth, buttonHeight, buttonImage.fileName );
        }

        function cancelEvent( e ) {
            context.device.cancelEvent( e );
        }

        function getPages() {
            var result = new Array();

            if ( context.stage.isInAuthoringMode() ) {
                return metadata.stage.pages;
            }

            if ( context.getPlayerName() == "html5" ) {
                result = metadata.stage.getMainPath().getPages();
            } else {
                var learningPaths = metadata.stage.getLearningPaths(),
                    result;

                for ( var i = 0; i < learningPaths.length; i++ ) {
                    result = result.concat( learningPaths[i].pages );
                }
            }

            return result;
        }

        function getPage( id ) {
            var page = null;

            if ( !id ) {
                return null;
            }

            for ( var p in allPages ) {
                if ( allPages.hasOwnProperty( p ) && allPages[p].getId() === id ) {
                    return allPages[p];
                }
            }

            return page;
        }

        function getLastVisitedEvaluationPage() {
            allPages = getPages();
            lastVisitedEvaluationPageId = context.stage.variable.get( "evaluationPageId", "tts.scoreDetailed" );
            lastVisitedEvaluationPage = getPage( lastVisitedEvaluationPageId );
        }

        function showElement() {
            if ( isStandardPlayer ) {
                shellElement.css( { "display": "block" } );
            } else {
                shellElement.parent().css( { "display": "block" } );
            }
        }

        function hideElement() {
            if ( isStandardPlayer ) {
                shellElement.css( { "display": "none" } );
            } else {
                shellElement.parent().css( { "display": "none" } );
            }
        }

		// revealing public API
		return {
			onLoading: function () {
			    var instance = this;

				context.page.event.bindOnEnter(instance);
                context.page.event.bindOnExit(this);

				shellElement = jq(context.getElement());

                hasStageTriggerSupport = !!context.stage.trigger;
                isInAuthoringMode = !!context.stage.isInAuthoringMode();

				// because of some problems with loading SVG while it is hidden on page,
				// we initialize SVG button onEnterPage
				if (!isStandardPlayer || isInAuthoringMode) {
					initializeButton();
				}
			},

			onEnterPage: function (){
				// because of some problems with loading SVG while it is hidden on page,
				// we initialize SVG button onEnterPage
				if (!buttonInitialized) {
					initializeButton();
                }

                getLastVisitedEvaluationPage();

                if ( lastVisitedEvaluationPageId && lastVisitedEvaluationPage && isPageBefore( pageId, lastVisitedEvaluationPageId) ) {
                    showElement();
                    bindEvents();
                } else {
                    hideElement();
                }
            },

            onExitPage: function () {
                if ( lastVisitedEvaluationPageId && lastVisitedEvaluationPage && isPageBefore( pageId, lastVisitedEvaluationPageId )) {
                    hideElement();
                    removeEvents();
                }
			}

		};
	};
});
