
/*
PLEASE DO NOT MAKE MODIFICATIONS TO THIS FILE TO ACCOMODATE FEATURES OR BUG FIXES THAT ARE NOT RELEVANT ACCROSS ALL SITES.
ALL CHANGES SHOULD BE EXPLAINED IN THE CHANGE HISTORY AND THE REVISION NUMBER SUBSEQUENTLY INCREMENTED.
*/

/*
--------------------------------------------------------------------------------------------------------------------------
StarmindModal
Provides general support for displaying modal overlays using Javascript.

Version: 1.2 (Rev. 001)
Required libraries: jQuery 1.4, StarmindHelper
Optional libraries: Knockout 1.21, jquery-tmpl (used with type: 'knockouttemplate')


Change history:
--------------------------------------------------------------------------------------------------------------------------

1.2.001: New support for knockout using jQuery templating.
1.1.002: StarmindModal_Helper methods moved to separate shared library.
1.1.001: Refactoring to provide ONE code-base for Electrolux-Appliances, Frigidaire, Ultralight and Icon.
1.0: First draft.


Usage examples:
--------------------------------------------------------------------------------------------------------------------------

This is the general format of the argument object that is passed to the StarmindModal.Create(id, args, ...) method.
args: {
	type:							selector/html/iframe/knockouttemplate
	closeButton:					true/false
	closeLayer:						true/false
	pattr/popupAttributes:			may contain all valid jQuery DOM Create attributes
	iattr/iframeAttributes:			may contain all valid jQuery DOM Create attributes
	cattr/containerAttributes:		may contain all valid jQuery DOM Create attributes
	lattr/layerAttributes:			may contain all valid jQuery DOM Create attributes
	cbattr/closeButtonAttributes:	may contain all valid jQuery DOM Create attributes
	fixed:							true/false
	template:						template id
	viewmodel:						knockout viewmodel
}

How to open a modal iframe:
StarmindModal.Create("modalid", { type: "iframe", closeButton: false, closeLayer: true, iattr: { src: "http://www.google.com" }, fixed: true }).Open();
*/

function ModalObject(args) {
	this.GetArgs = function(args) {
		return StarmindHelper.MergeAttrObject(
			{
				type: "iframe",
				closeButton: false,
				closeLayer: false,
				pattr: {}, popupAttributes: {},
				iattr: {}, iframeAttributes: {},
				cattr: {}, containerAttributes: {},
				lattr: {}, layerAttributes: {},
				cbattr: {}, closeButtonAttributes: {},
				fixed: false,
				viewmodel: null,
				template: null
			},
			args
		);
	}

	this.Args = this.GetArgs(args);
	this.Container = null;
	this.Layer = null;
	this.Popup = null;
	this.CloseBtn = null;
	this.Modal = null;
	this.HasBeenShownOnce = false;
	this.ViewModel = function() {
		return this.Args.viewmodel;
	};

	this.Init = function() {
		this.Args.closeButtonAttributes = this.Args.cbattr = StarmindHelper.MergeAttrObject(this.Args.closeButtonAttributes, this.Args.cbattr);
		this.Args.popupAttributes = this.Args.pattr = StarmindHelper.MergeAttrObject(this.Args.popupAttributes, this.Args.pattr);
		this.Args.iframeAttributes = this.Args.iattr = StarmindHelper.MergeAttrObject(this.Args.iframeAttributes, this.Args.iattr);
		this.Args.containerAttributes = this.Args.cattr = StarmindHelper.MergeAttrObject(this.Args.containerAttributes, this.Args.cattr);
		this.Args.layerAttributes = this.Args.lattr = StarmindHelper.MergeAttrObject(this.Args.layerAttributes, this.Args.lattr);

		this.Container = jQuery(
			'<div />', 
			StarmindHelper.MergeAttrObject(
				{ 'class': 'modal' },
				this.Args.cattr,
				{ style: 'position: absolute; left: 50%; width: 0px; top: 50%; height: 0px; visibility: hidden; z-index:10000;' }
			)
		);

		this.Layer = jQuery(
			'<div />', 
			StarmindHelper.MergeAttrObject(
				{ style: 'background-color: gray; opacity: 0.65; filter: alpha(opacity=65);' },
				this.Args.lattr,
				{ style: 'position: fixed; left: 0px; top: 0px; width: 100%; height: 100%;' }
			)
		);

		this.Popup = jQuery(
			'<div />', 
			StarmindHelper.MergeAttrObject(
				this.Args.pattr,
				{ style: 'position: absolute;' }
			)
		);

		//bind close button event
		if(this.Args.closeButton == true) {
			var closeContainer = jQuery('<div />', { style: 'position: relative; width: 0px; height: 0px; float: right;' });
			this.CloseBtn = jQuery(
				'<div />',
				StarmindHelper.MergeAttrObject(
					{ html: '<a href="#">Close</a>' },
					this.Args.cbattr,
					{ style: 'position: absolute; right: 5px; top: 5px; z-index: 10001; cursor: pointer;' }
				)
			);
			closeContainer.append(this.CloseBtn);

			this.Popup.append(closeContainer);
			jQuery(this.CloseBtn).bind("click", this, function(e) { e.data.Close(); return false; });
		}

		this.Container.append(this.Layer);
		this.Container.append(this.Popup);

		//bind layer close event
		if(this.Args.closeLayer != undefined && this.Args.closeLayer == true) {
			this.Layer.bind("click", this, function(e) { e.data.Close(); return false; });
		}

		//render content according to specified type
		switch(this.Args.type) {
			case "selector":
				if(this.Args.selector != undefined) {
					this.Modal = jQuery(this.Args.selector);
					this.Popup.append(this.Modal);
				}
			case "html":
				if(this.Args.html != undefined) {
					this.Modal = jQuery(this.Args.html);
					this.Popup.append(this.Modal);
				}
				break;
			case "iframe":
				this.Modal = jQuery(
					'<iframe />', 
					StarmindHelper.MergeAttrObject(
						{ style: 'border: none; margin: 0px;', frameborder: '0', scrolling: 'no', src: 'about:blank' },
						this.Args.iattr,
						{ style: 'width: 100%; height: 100%;' }
					)
				);

				this.Popup.append(this.Modal);
				break;
			case "knockouttemplate":
				if(this.Args.template != null && this.Args.viewmodel != null) {
					this.Modal = jQuery('<div />', { 'data-bind': 'template: { name: "' + this.Args.template + '" }' });
					this.Popup.append(this.Modal);
					ko.applyBindings(this.Args.viewmodel, this.Modal.get(0));
				}
			break;
		}

		jQuery("body").append(this.Container);

		if(this.Args.fixed != undefined && this.Args.fixed == true) jQuery(document).bind("scroll", this, function(e) { e.data.Reposition(); });
	}

	this.Init();

	this.Open = function(forceReload) {
		if(forceReload == true && this.HasBeenShownOnce == true) this.Reload();
		//this.Container.show();
		//this.Modal.show();
		this.Container.css("visibility", "visible");

		this.Reposition();

		//set flag to signal reloading is now permitted
		this.HasBeenShownOnce = true;
	}

	//currently only supports reloading of iframes (what else is there..?)
	this.Reload = function() {
		if(this.Args.type == "iframe") {
			this.Modal.contents().find("body").html("");
			this.Modal.attr("src", this.Args.iframeAttributes.src);
		}
	}

	this.Close = function() {
		//this.Container.hide();
		//this.Modal.hide();
		this.Container.css("visibility", "hidden");
	}

	this.Reposition = function() {
		this.Popup.css("left", (-Math.floor(this.Popup.outerWidth()/2)+jQuery(document).scrollLeft()) + "px");
		this.Popup.css("top", (-Math.floor(this.Popup.outerHeight()/2)+jQuery(document).scrollTop()) + "px");
	}
}

var StarmindModal = {
	Settings: {
		DefaultValues: {
			ForceRecreate: false
		}
	},
	Modals: Array(),
	Open: function(id) {
		if(jQuery(document).data(id) == undefined) return;

		jQuery(document).data(id).Open();
	},
	Close: function(id) {
		if(id == undefined) {
			//close all modals
			for(var i = 0; i < this.Modals.length; i++) this.Modals[i].Close();
			return;
		} else if(jQuery(document).data(id) == undefined) return;

		jQuery(document).data(id).Close();
	},
	Bind: function(id, args) {
		var m = StarmindModal.Create(id, args);
		this.bind("click", m, function(e) { e.data.Open(); return false; });

		return m;
	},
	Create: function(id, args, forceRecreate) {
		if(forceRecreate == undefined) forceRecreate = this.Settings.DefaultValues.ForceRecreate;

		var exists = (jQuery(document).data(id) != undefined);
		var m = null;

		if(!exists) {
			m = new ModalObject(args);
			jQuery(document).data(id, m);
			this.Modals.push(m);
		} else {
			m = jQuery(document).data(id);

			if(forceRecreate == true) {
				var c = m.Container;

				m.Args = this.GetArgs(args);
				m.Init();

				c.remove();
			}
		}

		return m;
	}
};

jQuery.fn.bindModal = StarmindModal.Bind;
