// com.tts.initial.html5.quiz.millionaire
// HTML4 / HTML5: No differences
define( [
	"./accessibility.builder",
	"jquery"
], function (
		AccessibilityBuilder,
		jq
	) {

	"use strict";

	/**
	 * @constructor
	 */
	return function (context, metadata) {
		var isStandardPlayer = context.getPlayerName() === "standard",
			instance = null,
			container = null,
			icon = null,
			clickZoneElement = null,
			groupId = null,
			choiceImage = "",
			choicePicWidth = 64,
			choicePicHeight = 32,
			BACKGROUND_POSITION = {},
			isChecked = false,
			isRight = false,
			elementType = "tRadio",
			elementVariableId = "",
        	pageEvaluatedId,
			elementVariableNameSpace = "com_tts_quiz",
			answerID = metadata.getId(),
			clickDownEvent = undefined,
            moveEvent = undefined,
			clickUpEvent = undefined,
			isAssessmentMode = context.stage.isInAssessmentMode(),
			accessibilityModeAvailable = true,
			accessibilityTooltip,
			accessibilityKey = metadata.parameters.get("accessibility-key", "KeyNone" ),
			accessibilityLocation = metadata.parameters.asNumber( "accessibility-location", 0 ),
			accessibilityPositionX = metadata.parameters.asNumber( "accessibility-position-x", -6 ),
			accessibilityPositionY = metadata.parameters.asNumber( "accessibility-position-y", -6 );

		function buildVariableId() {
			var baseId = "checkedValue" + metadata.getId() + "_";
			if ( elementType === "tCheck" ) {
				return baseId + answerID + "_" + groupId;
			}
			return baseId + groupId;
		}

        function initPointerEventNames() {

            if( clickDownEvent ) {
                return;
            }

            var nodeName = clickZoneElement.get(0).nodeName;
            clickDownEvent = context.device.getDownEvents( nodeName );
            clickUpEvent = context.device.getUpEvents( nodeName );
            moveEvent = context.device.getMoveEvents( nodeName );
        }

		function initializeParameters(parameters) {
			isRight = parameters.asBool( "is_right" );
			//elementType = parameters.get( "element_type" );
			groupId = parameters.get("toggle_group_id");
			elementVariableId = buildVariableId();

			var savedVariableValue,
				backgroundImage = parameters.get( "state_picture", null ),
				backgroundImageAssessment = parameters.get( "state_picture_assessment", null ),
				path = context.getPath();

			if ( isAssessmentMode && backgroundImageAssessment ) {
				backgroundImage = backgroundImageAssessment;
			}

			if (backgroundImage) {
				choiceImage = context.stage.getSharedPath() + backgroundImage.fileName;
				choicePicWidth = backgroundImage.width;
				choicePicHeight = parseInt(backgroundImage.height / 12);
			} else if ( elementType === "tRadio" ) {
				choiceImage = path + "radiobutton.png";
			} else {
				choiceImage = path + "checkbox.png";
			}

			BACKGROUND_POSITION = {
				"DEFAULT": "0px 0px",
				"HOVER": "0px " + -choicePicHeight + "px",
				"PRESSED": "0px " + (-2 * choicePicHeight) + "px",
				"INACTIVE": "0px " + (-3 * choicePicHeight) + "px",
				"SELECTED": "0px " + (-4 * choicePicHeight) + "px",
				"SELECTED_HOVER": "0px " + (-5 * choicePicHeight) + "px",
				"SELECTED_RIGHT": "0px " + (-6 * choicePicHeight) + "px",
				"SELECTED_WRONG": "0px " + (-7 * choicePicHeight) + "px",
				"NOT_SELECTED_WRONG": "0px " + (-8 * choicePicHeight) + "px",
				"NOT_SELECTED_RIGHT": "0px " + (-9 * choicePicHeight) + "px",
				"SAMPLE_SELECTED": "0px " + (-10 * choicePicHeight) + "px",
				"SAMPLE_NOT_SELECTED": "0px " + (-11 * choicePicHeight) + "px"
			};

			savedVariableValue = parseInt(context.stage.variable.get(elementVariableId, elementVariableNameSpace));
			savedVariableValue = !isNaN(savedVariableValue) ? savedVariableValue : 0;
			if (savedVariableValue && savedVariableValue === answerID) {
				isChecked = true;
			}

		}

		function isEvaluated() {

			if (context.stage.isInPreviewMode()) {
				return false;
			}

			if (isStandardPlayer) {
				return context.stage.variable.get(pageEvaluatedId, elementVariableNameSpace);
			}

			return context.page.quiz.hasQuestion() && context.page.quiz.getQuestion().isFinalized();
		}

		function createChoiceElement() {
			container = jq(context.getElement())
				.css({
					"width": choicePicWidth + "px",
					"height": choicePicHeight + "px"
				});

			icon = jq(document.createElement("div"))
				.css({
					"position": "absolute",
					"background-image": "url(\"" + choiceImage + "\")",
					"background-repeat": "no-repeat",
					"background-position": (isChecked ? BACKGROUND_POSITION.SELECTED : BACKGROUND_POSITION.DEFAULT),
					"-webkit-tap-highlight-color": "rgba(0,0,0,0)",
					"width": choicePicWidth + "px",
					"height": choicePicHeight + "px",
					"padding-right": "2px"
				});
			container.append( icon );

			if ( accessibilityKey !== "KeyNone" ) {
				accessibilityTooltip = new AccessibilityBuilder( accessibilityKey, accessibilityLocation, accessibilityPositionX, accessibilityPositionY ).build();
				container.append( accessibilityTooltip.getElement() );
			}

			context.stage.isInAuthoringMode()
				? createAuthoringShield()
				: createClickZoneElement();
		}

		function createAuthoringShield() {
			container.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 createClickZoneElement() {
			clickZoneElement = jq(document.createElement("div"))
				.attr("id", answerID + "_ChoiceClickZone")
				.css({
					"position": "absolute",
					"background-color": "transparent",
					"-webkit-tap-highlight-color": "rgba(0,0,0,0)",
					"width": choicePicWidth + "px",
					"height": choicePicHeight + "px",
					"cursor": "pointer",
					"z-index": "9999"
				});

			container.append(clickZoneElement);
		}

        function reset(){

            if (isStandardPlayer) {
                context.stage.variable.set(pageEvaluatedId, false, elementVariableNameSpace);
            }

            setChecked( false );
        }

		function setChecked(checked) {
			context.page.quiz.setSelected(instance, checked);
			isChecked = checked;
			icon.css("background-position", checked ? BACKGROUND_POSITION.SELECTED : BACKGROUND_POSITION.DEFAULT);
			context.page.event.trigger(instance, checked ? "toggleOn" : "toggleOff");
		}

		function lockNavigation() {
			if(context.stage.trigger !== undefined) {
				context.stage.trigger.lock(answerID);
			}
		}

		function unlockNavigation() {
			if(context.stage.trigger !== undefined) {
				context.stage.trigger.unlock(answerID);
			}
		}

        function bindEvents() {

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

			removeEvents();

			if ( elementType === "tRadio" ) {
				context.page.group.event.bind( instance, groupId + elementType, "onSingleChoiceClick" );
			}

            var clickZoneHtmlElement = clickZoneElement.get(0);
            if (!context.device.isMobile()) {
                context.device.attachFirstSupportedEvent( clickZoneHtmlElement, moveEvent, onMouseMove );
                context.device.attachFirstSupportedEvent( clickZoneHtmlElement, "mouseout", onMouseOut );
			}

            context.device.attachFirstSupportedEvent( clickZoneHtmlElement, clickDownEvent, onButtonPressed );
            context.device.attachFirstSupportedEvent( clickZoneHtmlElement, clickUpEvent, onButtonReleased );
            context.device.attachFirstSupportedEvent( clickZoneHtmlElement, "touchmove", cancelEvent );

		}

		function cancelEvent(e) {
            if(e && e.preventDefault) {
                e.preventDefault();
            }
            if(e && e.stopPropagation()) {
                e.stopPropagation();
            }
            return false;
		}

        function onMouseOut() {
            icon.css("background-position", (isChecked ? BACKGROUND_POSITION.SELECTED : BACKGROUND_POSITION.DEFAULT));
            unlockNavigation();
        }

        function onMouseMove() {
            icon.css("background-position", (isChecked ? BACKGROUND_POSITION.SELECTED_HOVER : BACKGROUND_POSITION.HOVER));
		}

		function removeEvents() {

		    initPointerEventNames();

            var clickZoneHtmlElement = clickZoneElement.get(0);
            context.device.removeFirstSupportedEvent( clickZoneHtmlElement, clickDownEvent, onButtonPressed );
            context.device.removeFirstSupportedEvent( clickZoneHtmlElement, clickUpEvent, onButtonReleased );

            if (!context.device.isMobile()) {
                context.device.removeFirstSupportedEvent( clickZoneHtmlElement, moveEvent, onMouseMove );
                context.device.removeFirstSupportedEvent( clickZoneHtmlElement, "mouseout", onMouseOut );
            }

             context.device.removeFirstSupportedEvent( clickZoneHtmlElement, "touchmove", cancelEvent );
    	}

		function showResultSymbol(isCorrectAnswer, selectedByUser) {
			if (isCorrectAnswer) {
				icon.css("background-position", (selectedByUser ? BACKGROUND_POSITION.SELECTED_RIGHT : BACKGROUND_POSITION.NOT_SELECTED_WRONG));
			}
			else {
				icon.css("background-position", (selectedByUser ? BACKGROUND_POSITION.SELECTED_WRONG : BACKGROUND_POSITION.NOT_SELECTED_RIGHT));
			}
		}

		function onButtonPressed() {
			icon.css("background-position", BACKGROUND_POSITION.PRESSED);
			lockNavigation();
		}

		function onButtonReleased() {

			unlockNavigation();
			setChecked(!isChecked);

			// save the user selection
			if (isChecked) {
				context.stage.variable.set(elementVariableId, answerID, elementVariableNameSpace);
			}
			else if ( elementType === "tCheck" ) {
				// Update variable value if the user deselects a checkbox.
				// This is not necessary for radio buttons, because there is only one variable for the whole question.
				context.stage.variable.set( elementVariableId, false, elementVariableNameSpace );
			}

			if ( elementType === "tRadio" ) {
				context.page.group.event.fire( instance, groupId + elementType, "onSingleChoiceClick" );
			}

			if (!context.device.isMobile()) {
				icon.css("background-position", (isChecked ? BACKGROUND_POSITION.SELECTED_HOVER : BACKGROUND_POSITION.HOVER));
			}
			setTimeout(function() {
				context.page.quiz.evaluate();
			}, 10);
		}

		function calculateClickZonePosition() {
			var containerChildren,
				childElement,
				offset = container.offset(),
				childOffset,
				childMaxPos,
				position = {
					left: offset.left,
					top: offset.top,
					width: choicePicWidth,
					height: choicePicHeight
				};

			containerChildren = context.getChildren();
			if (!containerChildren || containerChildren.length === 0) {
				return position;
			}

			offset = container.offset();
			position.left = offset.left;
			position.top = offset.top;
			position.width = container.width() > parseInt(choicePicWidth) ? container.width() : parseInt(choicePicWidth);
			position.height = container.height() > parseInt(choicePicHeight) ? container.height() : parseInt(choicePicHeight);

			jq.each(containerChildren, function (i, e) {
				childElement = jq(e);
				if (!childElement.is(":visible")) {
					return;
				}

				childOffset = childElement.offset();

				if (childOffset.left < offset.left) {
					position.left = childOffset.left;
				}

				if (childOffset.top < offset.top) {
					position.top = childOffset.top;
				}

				childMaxPos = childOffset.left + childElement.width();
				if (childMaxPos > (position.left + position.width)) {
					position.width = (childOffset.left - position.left) + childElement.width();
				}

				childMaxPos = childOffset.top + childElement.height();
				if (childMaxPos > (position.top + position.height)) {
					position.height = (childOffset.top - position.top) + childElement.height();
				}
			});

			return position;
		}

		function adjustClickZoneSize() {
			var position = calculateClickZonePosition();
			clickZoneElement
				.offset(position)
				.width(position.width)
				.height(position.height);
		}

		function switchToUserSolution() {
			removeEvents();
			accessibilityModeAvailable = false;

			if (isStandardPlayer) {
				context.stage.variable.set(pageEvaluatedId, true, elementVariableNameSpace);
			}

			unlockNavigation();

			showResultSymbol(isRight, isChecked);
		}

		function switchToBestPracticeSolution() {
			removeEvents();
			accessibilityModeAvailable = false;
			unlockNavigation();
			icon.css("background-position", (isRight ? BACKGROUND_POSITION.SAMPLE_SELECTED : BACKGROUND_POSITION.SAMPLE_NOT_SELECTED));
		}

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

				isChecked = false;

				context.page.event.bindOnEnter(instance);
				context.page.event.bindOnExit( instance );
				context.page.quiz.event.bindOnEvaluateTestRun( instance );
				context.page.quiz.event.bindOnUserSolution( instance );
				context.page.quiz.event.bindOnBestPracticeSolution( instance );
				if ( accessibilityKey !== "KeyNone" ) {
					context.stage.accessibility.bindOnAccessibilityModeChanged( this );
				}

				initializeParameters(metadata.parameters);
				createChoiceElement();
				context.page.quiz.add( instance, groupId + elementType, isRight);

				if( context.stage.isInAuthoringMode() ) {
					setChecked(isRight);
				}
			},

			onEnterPage: function () {
				pageEvaluatedId = metadata.page.getId() + "_evaluated";

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

				adjustClickZoneSize();

				if( !isStandardPlayer && isEvaluated() ) {
					switchToUserSolution();
					return;
				}

				reset();
                bindEvents();
			},

            onExitPage: function () {
				removeEvents();
			},

			onEvaluateTestRun: function ( dataHTML5 ) {

				context.page.event.trigger( instance, "evaluation" );
				if ( isStandardPlayer ) {
					return;
				}

				if ( dataHTML5.isFinalized || dataHTML5.currentTestRun >= dataHTML5.testRuns ) {
					context.page.quiz.switchToUserSolution();
				}
			},

            onSingleChoiceClick: function (event, senderId) {
				if (senderId !== answerID) {
					setChecked(false);
				}
			},

			onUserSolution: switchToUserSolution,

			onBestPracticeSolution: switchToBestPracticeSolution,

			onAccessibilityModeChanged: function ( dataHTML5, dataHTML4 ) {
				if ( !accessibilityModeAvailable ) {
					return;
				}

				var params = dataHTML4 || dataHTML5;

				if ( params.isActive ) {
					accessibilityTooltip.show();
				} else {
					accessibilityTooltip.hide();
				}
			},

			onAccessibilityKeyPressed: function ( dataHTML5, dataHTML4 ) {
				if ( !accessibilityModeAvailable ) {
					return;
				}

				var params = dataHTML4 || dataHTML5;

				if ( params.keyCode == accessibilityTooltip.getKeyCode() ) {
					onButtonReleased();
				}
			}
		};
	};
});
