﻿/// <reference path="../jquery-1.4.1-vsdoc.js" />
/// <reference path="Plugin.Timer.js" />

// --------------------------------
//  Plugin author: Robert Koritnik
// --------------------------------
//  Depends on Plugin.Timer.js
// --------------------------------

(function($) {
	$.fn.popup = function(options) {
		/// <summary>Converts a selected set of elements into modeless popup windows that can be opened one at a time.</summary>
		/// <param name="options" type="Object">
		///		1. closeSelectorOutside (".toggle-popup") - this selector will be passed to prev() function and should locate element that is resposible for toggling popup window display
		///		2. closeSelectorInside (".close-popup") - this selector will be used to locate popup closing element within the popup window
		///		3. title (no deafult) - title can be set per popup window on element itself in "title" attribute or per page with his option
		///		4. messageSuccess (no default) - success message can be set per popup window on element itself in attribute "message-success" or per page with this option
		///		5. messageFail (no default) - fail message can be set per popup window on element itself in attribute "message-fail" or per page with this option
		///		6. useAjax (true) - if a popup window has a <form> element it will convert it to an ajax form and use jQuery to post requests to the server
		///		7. autoFocus (true) - when popup window is displayed, focus is automatically set on the first non empty input box (of whatever type - may as well be a button)
		///		8. onShow (none) - a function(popupInstance) that will be invoked when a popup window is displayed
		///		9. onSuccess (none) - a function(popupInstance, responseData) that will be invoked when ajax call was successful
		///		10. onFail (none) - a function(popupInstance) that will be invoked when ajax call failed
		///		11. onReset (none) - a function(popupInstance) that will be invoked right after the popup window form will be reset
		///		12. closeOnFail (false) - set to "true" when you want failed ajax calls to reset the form and close the popup window
		/// </param>
		/// <returns type="jQuery" />

		var emptyfn = function() { };

		// set default options
		options = $.extend({
			closeSelectorInside: ".close-popup",
			closeSelectorOutside: ".toggle-popup",
			title: "Notify window title should be set.",
			messageSuccess: "Notify window success message should be set.",
			messageFail: "Notify window fail message should be set.",
			useAjax: true,
			autoFocus: true,
			closeOnFail: false,
			onShow: emptyfn,
			onSuccess: emptyfn,
			onFail: emptyfn,
			onReset: emptyfn
		}, options || {});

		openedPopup = 0; // will be set to null after initialization
		togglePopup = function(popupWin) {
			// close popup if opened
			openedPopup && openedPopup.slideUp("fast");
			if (openedPopup === null || popupWin.data("unique") != openedPopup.data("unique"))
			{
				popupWin.slideDown("fast", function() {
					if (options.autoFocus === true)
					{
						$(":input[value='']:first", popupWin).focus();
					}
					if ($.isFunction(options.onShow))
					{
						options.onShow(popupWin);
					}
				});
				openedPopup = popupWin;
				return;
			}
			openedPopup = null;
		};

		var result = this.each(function(index, item) {
			var popup = $(item);
			// don't apply popup when it's already been applied
			if (popup.attr("viva-popup") && popup.attr("viva-popup") === "enabled")
			{
				return;
			}
			popup.attr("viva-popup", "enabled");

			options.title = popup.attr("title") || options.title;
			options.messageSuccess = popup.attr("message-success") || options.messageSuccess;
			options.messageFail = popup.attr("message-fail") || options.messageFail;
			popup.hide();
			popup.prev(options.closeSelectorOutside).click(function(e) {
				e.preventDefault();
				togglePopup(popup);
			});
			popup.data("unique", openedPopup++);
			$(options.closeSelectorInside, popup).click(function(e) {
				e.preventDefault();
				togglePopup(popup);
			});
			if ($("form", popup).length > 0 && options.useAjax === true)
			{
				$("form", popup).submit(function(e) { e.preventDefault(); });
				$("button[type=submit]", popup).click(function(e) {
					e.preventDefault();
					var form = $(this).closest("form");
					var closeLink = $(options.closeSelectorInside + ":first", popup);
					if (form && form.length == 1)
					{
						var data = form.serializeArray();
						jQuery.ajax({
							type: "POST",
							url: form.attr("action"),
							data: data,
							success: function(data, status, xhr) {
								// reset form and close popup
								form[0].reset();
								if ($.isFunction(options.onReset))
								{
									options.onReset(popup);
								}
								closeLink.click();
								// display success notification
								Viva.Notify.show(Viva.Notify.InformationType.Info, options.title, options.messageSuccess);
								// call success function
								if ($.isFunction(options.onSuccess))
								{
									$.runOnce("CreateSuccess", function() { options.onSuccess(popup, data); }, 250, true, this);
								}
							},
							error: function(xhr, status, error) {
								if (options.closeOnFail === true)
								{
									form[0].reset();
									if ($.isFunction(options.onReset))
									{
										options.onReset(popup);
									}
									closeLink.click();
								}
								// model exceptions are returned with HTTP status code = 400
								if (xhr.status == 400)
								{
									Viva.Notify.show(Viva.Notify.InformationType.Warning, options.title, xhr.responseText);
								}
								else
								{
									Viva.Notify.show(Viva.Notify.InformationType.Error, options.title, options.messageFail);
								}
								if ($.isFunction(options.onFail))
								{
									$.runOnce("CreateFail", function() { options.onFail(popup); }, 250, true, this);
								}
							}
						});
					}
				});
			}
		});
		openedPopup = null;
		return result;
	}
})(jQuery);
