/**
 * MailAFriend
 * Provides mail a friend functionality to the product page
 * @constructor
 * @param {String} productName The name of the product
 * @param {Number} productId The product id
  */
function MailAFriend(productName, productId)
{
	if (typeof productName != "string") 
	{
			throw new Error("Invalid argument: productName is missing or not a string");
	}

	// Private
	var self			= this,
		socket			= new Socket(),
		dom				= new DOM(),
		mailafriendForm, completed;

	// Get the height of the page
	if (window.innerHeight != null)
	{
		var pageHeight = window.innerHeight;
	}
	else
	{
		if (document.body != null)
		{
			var pageHeight = document.body.clientHeight;
		}
		else
		{
			var pageHeight = null;
		}
	}

	// Preload a few images
	dom.create("img", {src : "/images/default/toggle_active_background.png"}, null);
	dom.create("img", {src : "/images/default/product_mailafriend_toggle_background.png"}, null);
	dom.create("img", {src : "/images/default/product_mailafriend_background.png"}, null);
	dom.create("img", {src : "/images/default/product_mailafriend_container_background.png"}, null);

	// Heading
	var heading = [
		dom.create(
			"div",
			{id: "product_mailafriend_heading"},
			[
				dom.create(
					"h3",
					null,
					["Mail dit product naar een vriend"]
				),
				dom.create(
					"a",
					{
						href	: "#",
						title	: "Sluiten",
						onclick	: close
					},
					["Sluiten"]
				)
			]
		)
	];

	// Heading (close button disabled)
	var headingCloseDisabled = [
		dom.create(
			"div",
			{id: "product_mailafriend_heading"},
			[
				dom.create(
					"h3",
					null,
					["Mail dit product naar een vriend"]
				),
				dom.create(
					"span",
					{
						title		: "Sluiten"
					},
					["Sluiten"]
				)
			]
		)
	];

	// Mail-a-Friend form
	var mailAFriendForm = [
		dom.create(
			"p",
			null,
			["Is dit product interessant voor een vriend? Laat het hem weten via e-mail."]
		),

		dom.create(
			"form",
			{
				action 	: "/mailafriend?sendmailafriend=true",
				id		: "product_mailafriend_form"
			},
			[
				// "To section"
				dom.create(
					"div",
					{id : "product_mailafriend_to"},
					[
						dom.create(
							"h4",
							null,
							["Aan"]
						),

						// Addressee name
						dom.create(
							"div",
							null,
							[
								dom.create(
									"label",
									{htmlFor	: "to_name"},
									["Naam *"]
								),
								dom.create(
									"input",
									{
										type	: "text",
										name	: "to_name",
										id		: "to_name"
									},
									null
								)
							]
						),

						//  Addressee e-mail
						dom.create(
							"div",
							null,
							[
								dom.create(
									"label",
									{htmlFor	: "to_email"},
									["E-mail *"]
								),
								dom.create(
									"input",
									{
										type	: "text",
										name	: "to_email",
										id		: "to_email"
									},
									null
								)
							]
						)
					]
				),

				// "From section"
				dom.create(
					"div",
					{id : "product_mailafriend_from"},
					[
						dom.create(
							"h4",
							null,
							["Van"]
						),

						// Sender name
						dom.create(
							"div",
							null,
							[
								dom.create(
									"label",
									{htmlFor	: "from_name"},
									["Naam *"]
								),
								dom.create(
									"input",
									{
										type	: "text",
										name	: "from_name",
										id		: "from_name"
									},
									null
								)
							]
						),

						//  Sender e-mail
						dom.create(
							"div",
							null,
							[
								dom.create(
									"label",
									{htmlFor	: "from_email"},
									["E-mail *"]
								),
								dom.create(
									"input",
									{
										type	: "text",
										name	: "from_email",
										id		: "from_email"
									},
									null
								)
							]
						)
					]
				),

				// Message
				dom.create(
					"div",
					{id : "product_mailafriend_message"},
					[
						dom.create(
							"h4",
							null,
							[
								dom.create(
									"label",
									{htmlFor : "message"},
									["Bericht"]
								),
								dom.create(
									"span",
									null,
									["(optioneel)"]
								)
							]
						),
						dom.create(
							"textarea",
							{
								name	: "message",
								id		: "message",
								rows	: 4,
								columns	: 60
							},
							null
						)
					]
				),

				// Send copy to self
				dom.create(
					"div",
					{id : "product_mailafriend_copy"},
					[
						// Checkbox
						dom.create(
							"input",
							{
								type	: "checkbox",
								name	: "sendcopy",
								id   	: "sendcopy",
								value	: "Y"
							},
							null
						),
						dom.create(
							"label",
							{htmlFor : "sendcopy"},
							[" Stuur mij een kopie van deze mail"]
						)
					]
				),

				// Send button
				dom.create(
					"div",
					{id: "product_mailafriend_send"},
					[	dom.create(
							"input",
							{
								type	: "hidden",
								name	: "productid",
								value	: productId
							}
						),
						dom.create(
							"a",
							{
								href	: "#",
								onclick	: submit
							},
							["verzenden"]
						)
					]
				),

				// Privacy statement
				dom.create(
					"div",
					{id : "product_mailafriend_privacy"},
					[
						dom.create(
							"p",
							null,
							[
								"Wij verstrekken je gegevens niet aan derden. ",
								dom.create("br",null,null),
								"(",
								dom.create(
									"a",
									{
										href		: "/klantenservice/item/541/veiligheid-en-privacy.html#item541",
										className	: "external",
										title		: "Bekijk ons privacybeleid"
									},
									[
										"privacybeleid",
										dom.create(
											"img",
											{
												src : "/images/default/anchor_external.png",
												alt	: "Externe pagina"
											},
											null
										)
									]
								),
								")."
							]
						)
					]
				)
			]
		)
	];

	var mailAFriendContainer = dom.create(
		"div",
		{id : "product_mailafriend"},
		[
			dom.create(
				"div",
				{
					id 			: "product_mailafriend_container"
				},
				(function() {
					return [].concat(heading, mailAFriendForm);
				})()
			)
		]
	);

	/**
	 * 	Fields
	 */

	var mailAFriendButton = dom.create(
		"li",
		{id : "product_mailafriend_toggle"},
		[
			dom.create(
				"a",
				{
					href		: "#product_mailafriend",
					title		: "Mail dit product",
					className	: "js",
					onclick		: function() {
									var toggle = dom.extend(this);

									if (toggle.hasClass("active")) 
									{
										toggle.removeClass("active");

										if (pageHeight != null && pageHeight < 1000)
										{
											dom.getById("layout_wrapper").style.paddingBottom = "0";
										}
										
										mailAFriendContainer.removeClass("active");
									}
									else
									{
										toggle.addClass("active");

										if (pageHeight != null && pageHeight < 1000)
										{
											dom.getById("layout_wrapper").style.paddingBottom = "250px";
										}
										dom.getById("product_mailafriend_toggle").appendChild(mailAFriendContainer);
										mailAFriendContainer.addClass("active");

										addValidation();
									}
									return false;
								}
				},
				[
					dom.create(
						"img",
						{
							src			: "/images/default/product_links_mailafriend.png",
							alt			: ""
						},
						null
					),
					dom.create(
						"span",
						null,
						["Mail dit product"]
					)
				]
			)
		]
	);

	addMailAFriendButton(mailAFriendButton);

	function addMailAFriendButton(mailAFriendButton)
	{
		if (!dom.getById("product_links"))
		{
			return false;
		}

		var linkContainer = dom.getById("product_links");
		if (!linkContainer.getFirstByTagName('ul'))
		{
			linkContainer.appendChild(
				dom.create(
					"ul",
					null,
					null
				)
			);
		}

		if (!dom.getById("product_folder_toggle")) 
		{
			linkContainer.getFirstByTagName('ul').appendChild(mailAFriendButton);
		}
		else
		{
			linkContainer.getFirstByTagName('ul').insertBefore(mailAFriendButton, dom.getById("product_folder_toggle"));
		}
	}


	/**
	 * close the mailafriend
	 * @return {boolean} false
	 */
	function close() {
		dom.getById("product_mailafriend").removeClass("active");
		dom.extend(dom.getById("product_mailafriend").parentNode).getFirstByTagName("a").removeClass("active");

		return false;
	}

	// Loading
	var loading = [
		dom.create(
			"div",
			{id : "product_mailafriend_loading"},
			[
				dom.create(
					"p",
					null,
					["Een ogenblik geduld, je opdracht wordt verzonden."]
				)
			]
		)
	];
	
	// Something went wrong
	var error = [
		dom.create(
			"div",
			{id : "product_mailafriend_error"},
			[
				dom.create(
					"p",
					null,
					["Door een technische storing kunnen we je mail op dit moment niet versturen. Probeer het later opnieuw. Onze excuses voor het ongemak."]
				)
			]
		)
	];


	/**
	 * Add formvalidation to mailafriend
	 * @requires Form needs the formvalidator class Form
	 */
	function addValidation()
	{
		mailafriendForm				= new Form(dom.getById("product_mailafriend_form"));
		var mailafriendFormRows		= new FormRows(),
			mailafriendFormNotices	= new FormNotices();

		mailafriendForm.addEventListener(Form.FIELD_ADDED, mailafriendFormRows.add);
		mailafriendForm.addEventListener(Form.VALIDATION_COMPLETE, mailafriendFormNotices.update);

		// Name To
		var nameToField = new InputField(dom.getById("to_name"));
		nameToField.addRequirement(new FormatRequirement(FormatRequirement.NOT_EMPTY, new Notice(" ", ["Vul s.v.p. de " , dom.create("a", {href : "#" + nameToField.getElement().id, onclick: nameToField.focus}, ["naam"]), " van de geadresseerde in."])));
		nameToField.addEventListener(Field.VALIDATION_COMPLETE, mailafriendFormRows.update);
		mailafriendForm.addField(nameToField);

		// Email To
		var emailToField = new InputField(dom.getById("to_email"));
		emailToField.addRequirement(new FormatRequirement(FormatRequirement.NOT_EMPTY, new Notice(" ", ["Het ", dom.create("a", {href : "#" + emailToField.getElement().id, onclick: emailToField.focus}, ["e-mailadres"]), " van de geadresseerde is niet ingevuld."])));
		emailToField.addRequirement(new FormatRequirement(FormatRequirement.EMAIL_ADDRESS, new Notice(" ", [getVousOuTu("Uw ", "Je ") , dom.create("a", {href : "#" + emailToField.getElement().id, onclick: emailToField.focus}, ["e-mailadres"]), " van de geadresseerde is niet correct ingevuld."])));
		emailToField.addEventListener(Field.VALIDATION_COMPLETE, mailafriendFormRows.update);
		mailafriendForm.addField(emailToField);

		// Name From
		var nameFromField = new InputField(dom.getById("from_name"));
		nameFromField.addRequirement(new FormatRequirement(FormatRequirement.NOT_EMPTY, new Notice(" ", ["Vul s.v.p. uw ", dom.create("a", {href : "#" + nameFromField.getElement().id, onclick: nameFromField.focus}, ["naam"]), "  in."])));
		nameFromField.addEventListener(Field.VALIDATION_COMPLETE, mailafriendFormRows.update);
		mailafriendForm.addField(nameFromField);

		// Email From
		var emailFromField = new InputField(dom.getById("from_email"));
		emailFromField.addRequirement(new FormatRequirement(FormatRequirement.NOT_EMPTY, new Notice(" ", ["Uw ", dom.create("a", {href : "#" + emailFromField.getElement().id, onclick: emailFromField.focus}, ["e-mailadres"]), " is niet ingevuld"])));
		emailFromField.addRequirement(new FormatRequirement(FormatRequirement.EMAIL_ADDRESS, new Notice(" ", [getVousOuTu("Uw ", "Je ") , dom.create("a", {href : "#" + emailFromField.getElement().id, onclick: emailFromField.focus}, ["e-mailadres"]), " is niet correct ingevuld"])));
		emailFromField.addEventListener(Field.VALIDATION_COMPLETE, mailafriendFormRows.update);
		mailafriendForm.addField(emailFromField);
	}


	/**
	 * onsubmit function
	 * @return {boolean} false
	 */
	function submit()
	{
		if (mailafriendForm.validate() == true)
		{
			// Get the entered information, used in the 'completed' message and request
			var toNameValue	 	= dom.getById("to_name").value,
				fromNameValue 	= dom.getById("from_name").value,
				toEmailValue	= dom.getById("to_email").value,
				fromEmailValue 	= dom.getById("from_email").value,
				messageValue 	= dom.getById("message").value;

			if (dom.getById("sendcopy").checked)
			{
				var sendcopyValue 	= "Y";
			}
			else
			{
				var sendcopyValue 	= "N";
			}

			var form = dom.getById("product_mailafriend_form");
			
			// 'Completed' message
			completed = dom.create(
				"div",
				{
					id : "product_mailafriend_completed"
				},
				[
					dom.create(
						"p",
						null,
						["Bedankt voor je belangstelling! " + toNameValue + " heeft je bericht over de " +productName+ " ontvangen."]
					),
					dom.create(
						"div",
						{id : "product_mailafriend_close"},
						[
							dom.create(
								"a",
								{
									href	: "#",
									title	: "Sluiten",
									onclick	: close
								},
								["Sluiten"]
							)
						]
					)
				]
			);

			// The validator requires the request to be asynchronous, as other requirements may depend on the result of the request
			socket.request(
				form.action,
				{
					productid	: productId,
					to_name		: toNameValue,
					from_name 	: fromNameValue,
					to_email	: toEmailValue,
					from_email	: fromEmailValue,
					message		: messageValue,
					sendcopy	: sendcopyValue
				},
				true,
				true
			);

			dom.getById("product_mailafriend").replaceChild(
				dom.create(
					"div",
					{id : "product_mailafriend_container"},
					[].concat(headingCloseDisabled, loading)
				),
				dom.getById("product_mailafriend_container", true)
			);
		}
		return false;
	}

	socket.addEventListener(Socket.LOADED, function()
	{
		if (socket.getStatus() == 200) 
		{
			if (typeof urchinTracker != "undefined") 
			{
				urchinTracker("/mailafriend/g4s1.html");
			}

			setTimeout(function() 
			{
				dom.getById("product_mailafriend").replaceChild(
				dom.create(
					"div",
					{id : "product_mailafriend_container"},
					[].concat(heading, completed)
					),
					dom.getById("product_mailafriend_container", true)
				);
				
			}, 750);
		}
	});



	/**
	 * FormRows
	 * @constructor
	 */
	function FormRows()
	{
		var fields = {};

		this.add		= add;
		this.update		= update;
		this.loading	= loading;

		/**
		 * add formrows
		 * @event
		 * @param {Event} event
		 */
		function add(event)
		{
			if (event.target in fields == false && (event.target instanceof InputField || event.target instanceof SelectField || event.target instanceof DateField))
			{
				var field = (fields[event.target] = event.target);

				// Get the row
				field.row = dom.extend(field.getElement().parentNode);

				if (field.row.hasClass("validation") == false)
				{
					field.row.addClass("validation");

					// Create and append notifier
					field.notifier = dom.create("span", {className : "validation"}, [
						dom.create("img", {src : "/images/default/validation_neutral_icon.png"})
					]);

					field.row.appendChild(fields[field].notifier);

					// Set notices
					field.failedNotice = null;
					field.passedNotice = null;

					// Validate (if the field has a value)
					if ((event.target instanceof InputField || event.target instanceof SelectField || event.target instanceof DateField) && field.getElement().value != "")
					{
						field.validate(Field.VALIDATION_TRIGGER_FIELD_ADDED);
					}
				}
			}
		}

		/**
		 * update formrows
		 * @event
		 * @param {Event} event
		 */
		function update(event)
		{
			var field = fields[event.target];

			if (field == undefined)
			{
				throw new Error("Unknown field.");
			}

			// If there's a notice present, remove it
			if (field.notifier.lastChild && field.notifier.lastChild.nodeType == 3)
			{
				field.notifier.removeChild(field.notifier.lastChild);
			}

			// Clear the classes, if present
			field.row.removeClass("failed");
			field.row.removeClass("passed");
	
			// Validation failed, update the notifier
			if (field.getValid() == false)
			{
				field.passedNoticeNotice = null;

				if (field.failedNotice == null || field.getValidationTrigger() == Field.VALIDATION_TRIGGER_BLUR || field.getValidationTrigger() == Field.VALIDATION_TRIGGER_CHANGE || field.getValidationTrigger() == Field.VALIDATION_TRIGGER_SUBMIT)
				{
					if (field.getFailedNotice() != null)
					{
						field.failedNotice = field.getFailedNotice().getPlainText();
					}
				}

				field.row.addClass("failed");

				field.notifier.getFirstByTagName("img").src = "/images/default/validation_failed_icon.png";

				if (field.failedNotice != null)
				{
					field.notifier.appendChild(dom.createText(field.failedNotice));
				}
			}
			// Passed validation
			else if (field.getValid() == true)
			{
				field.failedNotice = null;

				if (field.getPassedNotice() != null)
				{
					field.passedNotice = field.getPassedNotice().getPlainText();
				}

				field.row.addClass("passed");

				field.notifier.getFirstByTagName("img").src = "/images/default/validation_passed_icon.png";

				if (field.passedNotice != null)
				{
					field.notifier.appendChild(dom.createText(field.passedNotice));
				}
			}
			// No validation required
			else if (field.getValid() == null)
			{
				field.notifier.getFirstByTagName("img").src = "/images/default/validation_neutral_icon.png";
			}
		}

		/**
		 * add loading class
		 * @event
		 * @param {Event} event
		 */
		function loading(event)
		{
			var field = fields[event.target];

			if (field == undefined)
			{
				throw new Error("Unknown field.");
			}

			if (event.type == Field.VALIDATION_STARTED)
			{
				field.row.addClass("loading");
			}
			else if (event.type == Field.VALIDATION_COMPLETE)
			{
				field.row.removeClass("loading");
			}
		}
	}

	/**
	 * Formnotices constructor
	 * @constructor
	 */
	function FormNotices()
	{
		// Private
		var list = dom.create("ul", {id : "product_mailafriend_errormessages"});

		// Public
		this.update = update;

		/**
		 * clear the error list
		 */
		function clear()
		{
			list.remove();
	
			while (list.firstChild) 
			{
				list.removeChild(list.firstChild);
			}
		}

		/**
		 * update formnotices
		 * @event
		 * @param {Event} event
		 */
		function update(event)
		{
			clear();

			var notices = event.target.getFailedNotices();

			if (notices.length > 0)
			{
				for (var i = 0; i < notices.length; i++)
				{
					list.appendChild(dom.create("li", null, notices[i].getHTML()));
				}

				var parentContainer = dom.getById("product_mailafriend_form");
				parentContainer.insertBefore(list,dom.getById("product_mailafriend_privacy"));
			}
		}
	}
}