﻿/*
Popup Manager for jQuery dialogs
Created by: Paul O'Russa
Last Modified: 1/13/2011
*/

//
//PopupData Class - Holds data for each DIV element that has a jQuery Dialog object attached to it.
//
function PopupData(id, options) {
	this.id = id;
	this.open = false;		//Is the dialog open?
	
	//Try to find an existing element with this id.
	this.div = $('#' + id);
	
	//If no element with the id was found, create a new div.
	if (this.div.length == 0) {
		this.div = $("<div />").attr("id", id);
	}
	
	this.div.dialog(options);	//make it a jQuery dialog object, setting options
	this.closeLink = null;		//reference to span tag containing the dialog close text
	this.iframe = null; 		//reference to the iframe that may be in the dialog

	//These are used when an OnIframeUrlChanged handler is in effect.
	this.iframeSrc = null;
	this.iframeHandler = null;
	this.iframeTimeout = null;
}


//
//Popup Manager Class - Static class for managing jQuery dialog popups (no need to instantiate to use).
//
//	Each method returns a reference to the Popup object, which allows for string commands together:
//		Popup.Set('myPopupID1').Modal().Open();
//
//	The "_popupID" parameters in the functions are completely optional.  They allow you to override the active
//	popup and work on another popup instead.  For example:
//		Popup.Open('myPopupID1');
//
var Popup = {
	activePopup: null, 	//the PopupData object of the active popup
	popups: {}, 		//an array of PopupData objects

	//Creates a new popup if it doesn't exist, or sets the current active one.
	//Parameters:
	//	popupID:	The ID of the popup DIV to set as active. If the ID is not associated with a popup, a new popup is also created.
	//				If the DIV associated with the ID does not exist, it is created.
	//	options:	Optional, an array of jQuery UI dialog options for the window
	Set: function (popupID, options) {
		this.activePopup = null;

		//If no options were given.
		if (typeof options == "undefined") {
			options = {};
		}

		//We need to control when the popup opens.
		options["autoOpen"] = false;

		if (popupID in this.popups) {
			//We've created this popup before, set as active.
			this.activePopup = this.popups[popupID];
			this.activePopup.div.dialog("option", options);
		}
		else {
			//Turn off resizing by default, unless it's already set.
			options["resizable"] = ("resizable" in options ? options["resizable"] : false);

			//Create a new popup from the given ID, set as active.
			this.popups[popupID] = new PopupData(popupID, options);
			this.activePopup = this.popups[popupID];
		}

		this._CheckOptions(options, popupID);

		return this;
	},

	//Returns the active popup object, or the one with the given ID.
	Get: function (_popupID) {
		return (typeof _popupID == "undefined" ? this.activePopup : this.popups[_popupID]);
	},

	//Open the popup
	Open: function (_popupID) {
		var _active = this.Get(_popupID);
		_active.div.dialog('open');
		_active.open = true;
		return this;
	},

	//Set the buttons on the popup.
	//Parameters:
	//	buttonData: A jQuery dialog buttons object or array
	Buttons: function (buttonData, _popupID) {
		this.Option("buttons", buttonData, _popupID);
		return this;
	},

	//Checks for popup options specific to this class (non-jQuery Dialog options).
	_CheckOptions: function (options, _popupID) {
		if ('content' in options) {
			this.ContentAdd(options['content'], _popupID);
			delete options['content'];
		}

		if ('contentPadding' in options) {
			this.ContentPadding(options['contentPadding'], _popupID);
			delete options['contentPadding'];
		}
	},

	//Close the popup
	Close: function (_popupID) {
		var _active = this.Get(_popupID);

		if (_active.open) {
			//Clear the iframe's url change hander, if needed.
			this.IframeChangedClear(_popupID);

			_active.div.dialog('close');
			_active.open = false;
		}

		return this;
	},

	//Closes all opened popups
	CloseAll: function () {
		for (var popupID in this.popups) {
			var popupData = this.popups[popupID];

			if (popupData.open) {
				popupData.div.dialog('close');
			}
		}

		return this;
	},

	//Hides the popup's close link in the title bar.
	CloseHide: function (_popupID) {
		var _active = this.Get(_popupID);
		$('#ui-dialog-title-' + _active.id).next().hide();
		return this;
	},

	//Add text next to the X link in the title bar.
	CloseText: function (text, _popupID) {
		var _active = this.Get(_popupID);

		if (_active.closeLink == null) {
			if (_active.div.dialog("isOpen")) {
				//Dialog already open, add the close text section now.
				this.__CloseTextAdd(text);
			}
			else {
				//Set the close text after the dialog has opened.
				_active.div.bind("dialogopen.popup", function () { Popup.__CloseTextAdd(text, _popupID); });
			}

		}
		else {
			//The close text section already exists, just set the close text.
			_active.closeLink.html(text);
		}

		return this;
	},

	//Private method to build the html necessary to add text next to the close link.
	__CloseTextAdd: function (text, _popupID) {
		var _active = this.Get(_popupID);

		//Find the close link that lives immediately after the title span tag.
		var link = $('#ui-dialog-title-' + _active.id + ' + a.ui-dialog-titlebar-close');
		link.css('width', 'auto');

		//_active.closeLink = $(".ui-dialog-titlebar-close");

		_active.closeLink = $('<span style="float:left; padding:1px 2px 2px 0">' + text + '</span>');
		link.append(_active.closeLink);
		link.find('span.ui-icon').css({ float: 'left', display: 'inline' });

		//Make sure this function is only called once.
		_active.div.unbind("dialogopen.popup");

		return this;
	},

	//Replaces the html content in the popup's div section.
	//Parameters:
	//	data: Either a string containing the html to add, or a reference to an html object
	Content: function (data, _popupID) {
		this.Get(_popupID).div.html(data);
		return this;
	},

	//Appends html content to the popup's div section.
	//Parameters:
	//	data: Either a string containing the html to add, or a reference to an html object
	ContentAdd: function (data, _popupID) {
		this.Get(_popupID).div.append(data);
		return this;
	},

	//Sets the padding on the content area of the popup.
	ContentPadding: function (padding, _popupID) {
		this.Get(_popupID).div.css('padding', padding);
		return this;
	},

	//Returns true or false depending on if the popup with the ID already exists.
	Exists: function (popupID) {
		return (popupID in this.popups);
	},

	Height: function (height, _popupID) {
		this.Option("height", height, _popupID);
		return this;
	},

	//Add an iframe to the popup DIV.
	Iframe: function (url, width, height, _popupID) {
		var _active = this.Get(_popupID);

		//Only make one iframe per popup.
		if (_active.iframe != null) {
			return this;
		}

		//Create our iframe.
		_active.iframe = $("<iframe />", {
			frameBorder: "0", scrolling: "no",
			css: { "width": width, "height": height, margin: "0", padding: "0" }
		});

		//Improves performance while dragging a popup that contains an iframe by hiding the iframe underneath a DIV.
		_active.div.bind("dialogdragstart",
			function () {
				var coverFrame = document.createElement('div');
				coverFrame.id = _active.id + '_coverFrame';
				coverFrame.style.height = '93%';
				coverFrame.style.width = '100%';
				coverFrame.style.position = 'absolute';
				coverFrame.style.left = '0px';
				coverFrame.style.top = '0px';
				_active.div.append(coverFrame);
			}
		);

		//Removes the DIV when dragging stops.
		_active.div.bind("dialogdragstop",
			function () {
				$('#' + _active.id + '_coverFrame').remove();
			}
		);

		_active.iframe.appendTo(_active.div);
		this.IframeUrl(url, _popupID);

		return this;
	},

	//Sets up a handler for when the iframe's url changes.
	//Parameters:
	//	OnIframeUrlChanged	- Reference to a function to be called.  It is passed the new url as a parameter.
	//	interval			- The interval in milliseconds to check for the changed url.
	IframeChanged: function (OnIframeUrlChanged, interval, _popupID) {
		var _active = this.Get(_popupID)
		_active.iframeSrc = _active.iframe.attr('src');
		_active.iframeHandler = OnIframeUrlChanged;
		_active.iframeTimeout = setInterval('Popup._OnIframeChanged("' + _active.id + '")', interval);

		return this;
	},

	//Clears the iframe changed handler.
	IframeChangedClear: function (_popupID) {
		var _active = this.Get(_popupID);

		if (_active.iframeTimeout == null) {
			return this;
		}

		clearInterval(_active.iframeTimeout);
		_active.iframeSrc = null;
		_active.iframeHandler = null;
		_active.iframeTimeout = null;

		return this;
	},

	_OnIframeChanged: function (_popupID) {
		var _active = this.Get(_popupID);
		var currentSrc = _active.iframe.attr('src');

		if (currentSrc != _active.iframeSrc) {
			_active.iframeSrc = currentSrc;
			_active.iframeHandler(currentSrc);
		}
	},

	//Set the url for the iframe embedded in the popup.
	IframeUrl: function (url, _popupID) {
		this.Get(_popupID).iframe.attr('src', url);
		return this;
	},

	//Set the size of the iframe.
	IframeSize: function (width, height, _popupID) {
		var _active = this.Get(_popupID)
		_active.iframe.css({ 'width': width, 'height': height });
		return this;
	},

	//Keeps the popup centered in the middle of the screen when scrolling.
	KeepCentered: function (_popupID) {
		$(window).scroll(function () {
			this.Option("position", "center", _popupID);
		});

		return this;
	},

	//Make the popup "modal", fading out the background and making it impossible to select anything else.
	Modal: function (_popupID) {
		this.Option("modal", true, _popupID);
		return this;
	},

	//Set an option on the popup.  Expects a jQuery dialog option.
	Option: function (option, value, _popupID) {
		this.Get(_popupID).div.dialog("option", option, value);
		this._CheckOptions({ option:value }, _popupID);
		return this;
	},

	//Set popup options.  Expects a jQuery dialog options object.
	Options: function (options, _popupID) {
		this.Get(_popupID).div.dialog("option", options);
		this._CheckOptions(options, _popupID);
		return this;
	},

	//Set the popup position.
	//Parameters:
	//	position: A jQuery position object
	Pos: function (position, _popupID) {
		this.Option("position", position, _popupID);
		return this;
	},

	Size: function (width, height, _popupID) {
		this.Width(width, _popupID);
		this.Height(height, _popupID);
		return this;
	},

	Title: function (title, _popupID) {
		this.Option("title", title, _popupID);
		return this;
	},

	TitleHide: function (_popupID) {
		var _active = this.Get(_popupID);
		$('#ui-dialog-title-' + _active.id).parent().hide();
		return this;
	},

	TitleShow: function (_popupID) {
		var _active = this.Get(_popupID);
		$('#ui-dialog-title-' + _active.id).parent().show();
		return this;
	},

	Width: function (width, _popupID) {
		this.Option("width", width, _popupID);
		return this;
	}
}


