define([
		"jquery"
	],
	function (jq) {
		var choice = {
				"left_top": {},
				"left_center": {"top": "50%", "margin-top": "-19px"},
				"left_bottom": {"bottom": "0"},
				"right_top": {"right": "0"},
				"right_center": {"right": "0", "top": "50%", "margin-top": "-19px"},
				"right_bottom": {"right": "0", "bottom": "0"},
				"top_left": {},
				"top_center": {"left": "50%", "margin-left": "-19px"},
				"top_right": {"right": "0"},
				"bottom_left": {"bottom": "-50px"},
				"bottom_center": {"bottom": "-50px", "left": "50%", "margin-left": "-19px"},
				"bottom_right": {"bottom": "-50px", "right": "0"}
			},
			content = {
				"left_top": {"margin-left": "50px"},
				"left_center": {"margin-left": "50px"},
				"left_bottom": {"margin-left": "50px"},
				"right_top": {"margin-right": "50px"},
				"right_center": {"margin-right": "50px"},
				"right_bottom": {"margin-right": "50px"},
				"top_left": {"margin-top": "50px"},
				"top_center": {"margin-top": "50px"},
				"top_right": {"margin-top": "50px"},
				"bottom_left": {"margin-bottom": "50px"},
				"bottom_center": {"margin-bottom": "50px"},
				"bottom_right": {"margin-bottom": "50px"}
			};

		return function (context, metadata) {
			var m_container = null,
				m_choiceElement = null,
				m_children = [],
				m_choiceButtonElement = null,
				m_resultElement = null,
				m_containerHeight = 0,
				m_sGroupId = null,

				m_sCheckboxPosition = "left_top",
				m_sChoiceType = "default",
				m_sChoiceStyle = "default",

				m_sCheckedBorderColor = "#000000",
				m_sBorderWidth = 1,
				m_sMarginWidth = 0,
				m_sFeedbackStyle = "icon",
				m_sFeedbackRightBorderColor = "#00ff00",
				m_sFeedbackWrongBorderColor = "#ff0000",
				m_sFeedbackBorderWidth = 1,
				m_sFeedbackMarginWidth = 0,

				m_bUserChoice = false,
				m_bChecked = false,
				m_bIsRight = false,
				m_Instance = null,

				hasPointerEventSupport = context.device.hasPointerEventSupport(),
				isMobileDevice = context.device.isMobile(),

				startEvent = isMobileDevice ? "touchstart" : (hasPointerEventSupport ? "pointerdown" : "mousedown"),
				stopEvent = isMobileDevice ? "touchend touchleave" : (hasPointerEventSupport ? "pointerup pointerout" : "mouseup mouseout");

			function init() {
				var parameterContainer = metadata.parameters;

				m_container = jq(context.getElement());
				m_children = m_container.children();

				m_sCheckboxPosition = parameterContainer.get("checkbox_position", "left_top");
				m_sChoiceType = parameterContainer.get("type", "default");
				m_sChoiceStyle = parameterContainer.get("style", "default");

				m_sCheckedBorderColor = parameterContainer.get("checked_border_color", "#000000");
				m_sBorderWidth = parameterContainer.asNumber("border_width", 1);
				m_sMarginWidth = parameterContainer.asNumber("margin_width", 0);
				m_sFeedbackStyle = parameterContainer.get("feedback", "icon");
				m_sFeedbackRightBorderColor = parameterContainer.get("feedback_right_border_color", "#00ff00");
				m_sFeedbackWrongBorderColor = parameterContainer.get("feedback_wrong_border_color", "#ff0000");
				m_sFeedbackBorderWidth = parameterContainer.asNumber("feedback_border_width", 1);
				m_sFeedbackMarginWidth = parameterContainer.asNumber("feedback_margin_width", 0);

				m_bIsRight = parameterContainer.asBool("is_right", false);
				m_sGroupId = parameterContainer.asNumber("toggle_group_id", 1);
			}

			function createChoiceElement() {
				m_choiceElement = jq(document.createElement("div"));
				m_choiceElement.attr("id", metadata.getId() + "_Choice");

				switch (m_sChoiceStyle) {
					case "border":
						m_choiceElement
							.css({
								"position": "absolute",
								"width": "100%",
								"height": "100%",
								"z-index": m_container.css("z-index")
							});
						break;
					default:
						m_choiceElement
							.css(choice[m_sCheckboxPosition])
							.css({
								"position": "absolute",
								"width": "38px",
								"height": "38px",
								"z-index": m_container.css("z-index")
							});
				}
				m_container.append(m_choiceElement);
			}

			function createChoiceButton() {
				m_choiceButtonElement = jq(document.createElement("div"));
				m_choiceButtonElement.attr("id", metadata.getId() + "_ChoiceButton");

				switch (m_sChoiceStyle) {
					case "border":
						m_choiceButtonElement
							.css({
								"position": "absolute",
								"width": "100%",
								"height": "100%",
								"border-width": (m_sBorderWidth + "px"),
								"border-color": "transparent",
								"border-style": "solid",
								"margin-left": ("-" + (m_sBorderWidth + m_sMarginWidth) + "px"),
								"margin-top": ("-" + (m_sBorderWidth + m_sMarginWidth) + "px"),
								"padding": (m_sMarginWidth + "px")
							});
						break;
					default:
						m_choiceButtonElement
							.css({
								"width": "38px",
								"height": "38px",
								"background-image": "url('" + context.getPath() + m_sChoiceStyle + ".png')"
							});
				}
				m_choiceButtonElement.css({
					"z-index": m_container.css("z-index"),
					"cursor": "pointer"
				});
				m_choiceElement.append(m_choiceButtonElement);
			}

			function createResultElement() {
				m_resultElement = jq(document.createElement("div"));
				m_resultElement.attr("id", metadata.getId() + "_Result");
				switch (m_sFeedbackStyle) {
					case "border":
						m_resultElement.css({
							"position": "absolute",
							"width": "100%",
							"height": "100%",
							"border-width": (m_sFeedbackBorderWidth + "px"),
							"border-color": "transparent",
							"border-style": "solid",
							"margin-left": ("-" + (m_sFeedbackBorderWidth + m_sFeedbackMarginWidth) + "px"),
							"margin-top": ("-" + (m_sFeedbackBorderWidth + m_sFeedbackMarginWidth) + "px"),
							"padding": (m_sFeedbackMarginWidth + "px")
						});
						break;
					default:
						m_resultElement.css({
							"position": "absolute",
							"width": "22px",
							"height": "22px",
							"left": "-11px",
							"top": "-11px",
							"background-image": "url('" + context.getPath() + (m_bIsRight ? "testmarkright" : "testmarkwrong") + ".png')"
						});
				}
				m_resultElement.css("z-index", m_choiceElement.css("z-index"));
				m_choiceElement.append(m_resultElement);
				m_resultElement.hide();
			}

			function setChecked(checked) {
				if(context.page.quiz.hasQuestion()) {
					context.page.quiz.setSelected(m_Instance, checked);
				}
				m_bChecked = checked;
				switch (m_sChoiceStyle) {
					case "border":
						m_choiceButtonElement.css("border-color", (checked ? m_sCheckedBorderColor : "transparent"));
						break;
					default:
						m_choiceButtonElement.css("background-position", checked ? "-76px 0" : "0 0");
				}
			}

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

				context.page.event.bindOnEnter(m_Instance);
				context.page.group.event.bind(m_Instance, m_sGroupId, "onSingleChoiceClick");

				m_container.on(startEvent, {}, onButtonEventStart);
				m_container.on(stopEvent, {}, onButtonEventStop);
			}

			function removeEvents() {
				m_container.off(startEvent);
				m_container.off(stopEvent);
			}

			function showResultSymbol() {
				switch (m_sFeedbackStyle) {
					case "border":
						m_resultElement.css("border-color", (m_bChecked === m_bIsRight ? m_sFeedbackRightBorderColor : m_sFeedbackWrongBorderColor));
						break;
					default:
						m_resultElement.css("background-image", "url('" + context.getPath() + (m_bChecked === m_bIsRight ? "testmarkright" : "testmarkwrong") + ".png')");
				}
				m_resultElement.show();
			}

			function onButtonEventStart() {
				context.stage.trigger.lock(metadata.getId());

				m_bUserChoice = !m_bChecked;
				setChecked(m_bUserChoice);

				context.page.group.event.fire(m_Instance, m_sGroupId, "onSingleChoiceClick");

				return true;
			}

			function onButtonEventStop() {
				setTimeout(function () {
					context.stage.trigger.unlock(metadata.getId());
				}, 100);
				return true;
			}

			function rearangeDescendant() {
				switch (m_sChoiceStyle) {
					case "border":
						break;
					default:
						m_container.children(".ttkfPresObjRef")
							.addClass("content")
							.css(content[m_sCheckboxPosition]);
				}
			}

			function calculateContainerHeight() {
				if (m_containerHeight !== 0) {
					return;
				}

				jq.each(m_children, function (i) {
					m_containerHeight += jq(m_children[i]).height();
				});
			}

			function setContainerHeight() {
				m_container.height(m_containerHeight);
				m_container.parent().height(m_containerHeight);
			}

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

					init();

					createChoiceElement();
					createChoiceButton();
					createResultElement();
					rearangeDescendant();
					context.page.quiz.add(m_Instance, m_sGroupId, m_bIsRight);
					setChecked(false);
					bindEvents();
				},

				onEnterPage: function () {
					switch (m_sChoiceStyle) {
						case "border":
							break;
						default:
							calculateContainerHeight();
							setContainerHeight();
					}
				},

				onSingleChoiceClick: function (event, senderId) {
					if (senderId == metadata.getId()) {
						return;
					}

					m_bUserChoice = false;
					setChecked(false);
				},

				onUserSolution: function () {
					removeEvents();
					setChecked(m_bUserChoice);
					showResultSymbol();
				},

				onBestPracticeSolution: function () {
					removeEvents();
					m_resultElement.hide();
					setChecked(m_bIsRight);
				}
			};
		};
	});