 //--Revolutionary popup machine --------------------------------------------------------v
//Co-designed by Cliff Lui and Ocean Kwok (© Raven Talon Studios) October 2008
//A javascript class dependent on the Prototype and Scriptaculous javascript libraries.
//You may use and change this code however you want. We just want you to include our names on it, unless you substantially change it.
/* README
	This code is used to show / hide / customise a popup window that has 1 or 2 buttons with customiseable functions and contents. The popup window will be shown and the entire screen will be darkened. No interaction with anything else apart from the popup (or other popups) is generally possible until the popup(s) is/are closed. 
	
	INSTALLATION/SETUP
	Put the css file and images folder somewhere in your web directory.
	Put this class somewhere in your web directory.
	Include the Prototype and Scriptaculous libraries in the page where you will be using this class. See: 
		<script src="/path-to/prototype.js" type="text/javascript"></script>
		<script src="/path-to/scriptaculous.js" type="text/javascript"></script>
	Include this class in the page where you will be using this class.
		<script src="/path-to/RTSpopup_class.js" type="text/javascript"></script>
	Search for this text: "edit the variables under this comment only" and edit those variables.
		Mainly, you need to change the path to the images that this class uses.
	
	QUICKSTART
	Initialise a popup window in javascript like this: var popup1 = new RTSpopup("Popup Title", "<p>Popup contents</p>", "plain");
		The first parameter (title) is going to be encapsulated in a <h1> tag. 
		The second parameter is going in a <div> tag. You might want to use HTML in the second parameter. 
		The third parameter takes in the following case insensitive options: plain, warning, info, dialog, delete, check, lock, down. You can add more to the class, but options outside those provided in the class will result in a default 'plain' popup.
	And then you can display the popout by: <a href="javascript:void(0);" onclick="popup1.popout();">show popup</a>
	After initialisation, you can further customise the popup (before popout or on the fly), e.g.:
		popup1.setPopupImage('warning');
			This function sets the 'type' of popup. 
			Parameter 1: see options above.
		popup1.setDimensions(400, 'auto') or popup1.setDimensions('', 600);
			Parameter 1: width, numeric integer or blank string. Not 'auto'.
			Parameter 2: height, numeric integer, blank string or 'auto'.
		popup1.setButtons(1);
			Determines how many buttons to show on the popup.
			Parameter 1: numeric integer of 0, 1 or 2 only.
		popup1.setButtonsText("close window", "do something");
			Determines what text the 2 buttons show. 2nd parameter only shows if setButtons(2) was done.
			Parameter 1: HTML string: text to show on the lower left corner button or default single button.
			Parameter 2: HTML string: text to show on the lower right corner button, if set.
		popup1.setButtonPassiveFunctions(function(){ someJavascriptFunction(); anotherJavascriptFunction(); });
			Determines what else the lower left / center button does when clicked. Replaces previous actions. Set to 'javascript:void(0)' if you want to disable it permanently. Leaving it to blank will make the button inert ONLY UNTIL the popup is opened again.
			The lower left / center button will always close the window when clicked. You can override this behaviour if you are an expert.
		popup1.setButtonActionFunctions(function(){ someJavascriptFunction(); anotherJavascriptFunction(); });
			Determines what the lower right button does when clicked. Replaces previous actions. You must contain functions you want to call in this format: function(){ … … }. You may leave blank to remove previously assigned functions.
		popup1.setTitle('HTML string') and »
		popup1.setContent('HTML string') :: self explanatory.
		popup1.setEscapeCloses(true);
			Determines whether pressing [ESC] will close the window. Defaults to False. You may want to set to True for one-off popups like info boxes and warnings.
		
	To close the popup with a third party button, use the following code: popup1.closePopup();
	
	You can drag each popup by dragging the header.
	
	TECHNICAL DETAILS
		This class creates and removes DOM elements on the fly. That means a web user’s memory is conserved and your pages will load and scroll faster.
		You can chain most configuration functions, eg.: 
		                            popup1.setTitle('HTML string').setContent('HTML string')
*/

RTSpopup = Class.create({
	initialize: function(title, contents, type){
					//edit the variables under this comment only v
					
					this.popupGraphicsDir = GLOBAL_root.replace(/ /g,'%20')+'media/UI_graphics/'; //absolute dir to class images, eg. /web/images/
					this.defaultPopupWidth = 400;		//cannot be auto, do not add px suffix.
					this.defaultPopupHeight= 'auto';	//can be auto, do not add px suffix.
					
					//edit the variables above this comment only ^
					
					//DO NOT EDIT ANYTHING ELSE UNLESS YOU KNOW WHAT YOU ARE DOING.
					this.setTitle(title);
					this.setContent(contents);
					//this.buttons = buttons;
					//this.clickOutsideToClose = clickOutsideToClose;
					this.setPopupImage(type);
					
					//set defaults
					this.setDimensions(this.defaultPopupWidth, this.defaultPopupHeight);				// width, height
					this.setButtons(1);							// 1 | 2
					this.setEscapeCloses(false);				// true | false
					this.setButtonsText('Close <b>×</b>', 'do something');	//close, function()
					this.setButtonPassiveFunctions('');			//stuff to do on pressing the close button
					this.setButtonActionFunctions('');			//stuff to do on pressing the do something button
					this.prevActionFunctions = '';
					this.prevPassiveFunctions = '';
					
					//set some object variables
					this.getScreenDimensions();
					
					//setup the modal (dark) background if none exists.
					if (!$('rts-popupModal')){
						window.onload=function() {
							var modalBG = new Element('div', { 'id':'rts-popupModal', 'class': 'popupdiv_BG'} ).setStyle({
								'width': 	(this.screenWidth)+ "px",
								'height': (this.screenHeight)+"px",
								display:'none'
							});
							$$('body')[0].insert(modalBG);
							Event.observe(window, "resize", function(){
								this.getScreenDimensions();
								$(modalBG).setStyle({
									'width': 	(this.screenWidth)+ "px",
									'height': (this.screenHeight)+"px"
								});
							}.bindAsEventListener(this) )
						}.bindAsEventListener(this);	
					}
					return this;				
	},
	setPopupImage: function(type){	//set the background image according to requirements. You can change them or add more if you want.
					this.popupType = type;
					switch (type.toLowerCase()){
						case 'plain':
							var popupImage = 'none';
							break;
						case 'warning':
							var popupImage = 'exclamation.png'
							break;
						case 'info':
							var popupImage = 'info.png'
							break;
						case 'dialog':
							var popupImage = 'speechbubble.png'
							break;
						case 'question':
							var popupImage = 'questionmark.png';
							break;
						case 'delete':
							var popupImage = 'trash.png'
							break;
						case 'lock':
							var popupImage = 'lock.png'
							break;
						case 'down':
							var popupImage = 'down_arrow.png'
							break;
						case 'check':
							var popupImage = 'check.png'
							break;
						case 'cross':
							var popupImage = 'cross.png'
							break;
						default:
							var popupImage = 'none';
							break;
					}
					if (popupImage != 'none'){
						this.popupImageDir = this.popupGraphicsDir+popupImage;
					} else 
						this.popupImageDir = false;
					this.popupImageSettled = false;
					this.update();
					return this;
	}, 
	setDimensions: function(popupWidth, popupHeight){	//WIDTH:  do not set less than 400, default css is 400-500, can be '', cannot be 'auto'.
														//HEIGHT: do not set less than 300, default is 'auto'.
					this.getScreenDimensions();
					
					if ( popupWidth.toString().toLowerCase() == 'auto' ) popupWidth = '';	//ignore auto width, which is invalid.
					if  (popupWidth!=''){			//if width is given, use it
						this.width = popupWidth;
					} else if (popupWidth==''){		//if width is not given, use previous value, if any, else use default
						if (!(this.width))
							this.width = this.defaultPopupWidth;
					}
					if  (popupHeight!='')			//if height is given, use it
						this.height = popupHeight;
					else if (popupHeight==''){		//if height is not given, use previous value, if any, else use default
						if (!(this.height))
							this.height = this.defaultPopupHeight;
					}
					this.dimensionsSettled = false;
					this.update();
					return this;
	},
	setButtons: function(numButtons){		//0, 1 or 2
					this.numButtons = numButtons;
					this.buttonsSettled = false;
					this.update();
					return this;
	},
	setButtonsText: function(passiveButtonText, actionButtonText){
					// You can pass blank parameters, which will retain previous (default) values.
					// Second parameter is optional.
					if (typeof actionButtonText == 'undefined' ) actionButtonText = '';
					if (passiveButtonText == '') passiveButtonText = this.passiveButtonText;
					if (actionButtonText == '') actionButtonText = this.actionButtonText;
					this.passiveButtonText = passiveButtonText;
					this.actionButtonText = actionButtonText;
					this.buttonsSettled = false;
					this.update();
					return this;
	},
	setButtonPassiveFunctions: function(passivefunctions){	//sets functions for the lower-left side button
					this.passiveFunctions = passivefunctions;
					if (passivefunctions != ''){
						this.prevPassiveFunctions = passivefunctions;
					}
					this.buttonsSettled = false;
					this.update();
					return this;
	},
	setButtonActionFunctions: function(actionfunctions){	//sets functions for the lower-right side button
					this.actionFunctions = actionfunctions;
					if (actionfunctions != ''){
						this.prevActionFunctions = actionfunctions;
					}
					this.buttonsSettled = false;
					this.update();
					return this;
	},
	setTitle: function(title){
					this.title = title;
					this.titleSettled = false;
					this.update();
					return this;
	},
	setContent: function(contents){
					this.contents = contents;
					this.contentsSettled = false;
					this.update();
					return this;
	},
	setEscapeCloses: function(option) {
						this.closeByEscape = option;	// true | false
						//option automatically updates.
						return this;
	},
	popout: 	function(){		//this function pops out the window.
					//destroy previous instances of itself, if any.
					if (this.unique){
						this.closePopup();
					}

					this.unique = new Date();														//generate a unique ID
					this.unique = "popup_"+this.unique.getTime() + Math.round(Math.random()*100); 	//popup_471901938							
					
					var puw_headerdiv = new Element('h1', { 'class': 'popupdiv_header' });
					
					if (this.popupImageDir){	//create space for background image if the popup type is set.
						var temp = "background-image:url("+this.popupImageDir+"); background-repeat:no-repeat; background-position: 0px 7px; padding-left:140px; min-height:130px;";
					}
					var puw_contentdiv = new Element('div', { 'id':this.unique+'_contentsContainer', 'class': 'popupdiv_content' });
					var puw_footerholder = new Element ('div', { 'id':this.unique+'_footerbar' }).hide();
					var puw = new Element('div', { 'id':this.unique, 'class': 'popupdiv' }).insert(puw_headerdiv).insert(puw_contentdiv).insert( puw_footerholder ); 

					$$('body')[0].insert(puw);	//insert the new DOM element
					//style and position the popup element.
					$(puw).setStyle({
						display:'none',
						backgroundImage: "url("+this.popupGraphicsDir+"windowBG.png)",
						opacity:0
					});
					this.setTitle(this.title);
					this.setContent(this.contents);
					this.setButtons(this.numButtons);
					this.setDimensions(this.width, this.height);
					this.setPopupImage(this.popupType);
					
					//listen for the escape key
					this.closePopupByKeyObserver = this.keyClosePopup.bindAsEventListener(this);
					Event.observe(document, "keydown", this.closePopupByKeyObserver );
					
					//make popup draggable
					this.dragObject = new Draggable(this.unique, {handle:puw_headerdiv});
					
					//hide all <select> tags for IE
					$$("select").each(function(s){
						s.addClassName('rt_popup_hide_hack');
					});
					
					$('rts-popupModal').show();		//show the dark background
					puw.appear({duration: 0.4});	//fade the popup div in
					return this;
	},
	
	//FUNCTIONS TO CLOSE THE POPUP WINDOW
	closePopup:	function(){ 
					var identifier = this.unique;
					if (!identifier) return false;		//prevent random Opera and IE errors if setbuttonpassiveFunctions is set.
										
					//remove listeners for this event.
					this.dragObject.destroy;
					if ( $(identifier+'_footer') ){
						$(identifier+'_footer').stopObserving();
					}
					if ( $(identifier+'_footer2') ){
						$(identifier+'_footer2').stopObserving();
					}
					
					//if (!$(identifier)) this.miscAlert('All popups closed already','');
					if ( !$$('div.popupdiv')[1] ){ 	//if there is only 1 popup window on the screen
						$('rts-popupModal').hide(); 	//	hide the rts-popupModal div
						Event.stopObserving(document, "keydown", this.closePopupByKeyObserver );
					}
					
					//fade out and destroy popup window
					var fadeoutTime = 500;
					$(identifier).fade( { duration: (fadeoutTime/1000) } );
					setTimeout( function () { 
						$(identifier).remove();
					}.bind(this),fadeoutTime );
					
					//reveal all <select> tags for IE
					$$("select").each(function(s){
						s.removeClassName('rt_popup_hide_hack');
					});
					
					this.unique = false;
	},
	keyClosePopup: function(e){
					if ( e.keyCode == Event.KEY_ESC && this.closeByEscape ){
						this.closePopup();
					}
	},
	shake: function(){
					if ($(this.unique)){
						new Effect.Shake(this.unique, { distance:5 });
					}
					
					return this;
	},
	
	//MISCELLANEOUS HELPER/INTERNAL FUNCTIONS
	update: function(){
					if (this.unique){
						//update title and contents
						var writediv = ($(this.unique).getElementsBySelector('[class="popupdiv_header"]'))[0];
						if (!this.titleSettled){
							if ( (this.title).strip() == ''){
								this.title = ' ';
								writediv.setStyle({
									fontSize:'7px'
								});
							}
							if (writediv.innerHTML == ' ' || writediv.innerHTML.strip() == '') 
								writediv.update(this.title);
							else if (writediv.innerHTML != this.title){
								writediv.fade({duration:0.3, from:1, to:0.1});
								setTimeout(function(){
									var writediv = ($(this.unique).getElementsBySelector('[class="popupdiv_header"]'))[0];
									writediv.update(this.title);
									writediv.appear({duration:0.3, from:0.1, to:1});
								}.bindAsEventListener(this), 300 );						
							}
							this.titleSettled = true;
						}
						
						writediv = ($(this.unique).getElementsBySelector('[class="popupdiv_content"]'))[0];
						if (!this.contentsSettled){			//to avoid popup refreshing everytime a form value changes.
							writediv.update(this.contents);
							this.contentsSettled = true;
						}
						
						//write dimensions and other styles
						if (!isNaN(this.width)) //if isnumeric
							var computedWidth = this.width+'px';
						if (!isNaN(this.height)) //if isnumeric
							var computedHeight = this.height+'px';
						else
							var computedHeight = this.height;		//'auto'

						if (!this.dimensionsSettled){
							if ( $(this.unique).getStyle('opacity')<1 ){	//if the window is popping out, set dimensions immediately
								$(this.unique).setStyle({
									top:  (this.screenHeight/2) - ($(this.unique).getHeight()/2)-(this.screenHeight/7)+(window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop)+"px",
									left: (this.screenWidth/2)  - ($(this.unique).getWidth()/2) +"px",
									width:	computedWidth,
									height:	computedHeight
								});
							} else {
								new Effect.Morph(this.unique, {
									style: {
										top:  (this.screenHeight/2) - ($(this.unique).getHeight()/2)-(this.screenHeight/7)+(window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop)+"px",
										left: (this.screenWidth/2)  - ($(this.unique).getWidth()/2) +"px",
										width:	computedWidth,
										height:	computedHeight
									},
									duration: 0.5
								});
							}
							this.dimensionsSettled = true;
						}

						if (!this.popupImageSettled){
							writediv = ($(this.unique).getElementsBySelector('[class="popupdiv_content"]'))[0];
							if (this.popupImageDir){	//create space for background image if the popup type is set.
								var temp = "background-image:url("+this.popupImageDir+"); background-repeat:no-repeat; background-position: 0px 7px; padding-left:140px; min-height:130px;";
								
								writediv.setStyle({
									backgroundImage:"url("+this.popupImageDir+")",
									backgroundRepeat:"no-repeat",
									backgroundPosition: "0px 7px",
									paddingLeft: "140px",
									height: computedHeight,
									minHeight: "130px"
								});
								//IE checks and fixes
								var version = parseFloat(navigator.appVersion.split('MSIE')[1]);
								if ((version >= 5.5) && (version < 7) && (document.body.filters)) {
									writediv.setStyle({
										filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.popupImageDir + "', sizingMethod='crop')",
										backgroundImage: 'none'
									});
									writediv.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.popupImageDir + "', sizingMethod='crop')";
								}
							}
							else {
								writediv.setStyle({
									backgroundImage:"none",
									paddingLeft: "",
									minHeight: "",
									height: computedHeight,
									filter: 'none'
								});
							}
							this.popupImageSettled = true;
						}
						
						if (this.popupImageDir){
							writediv = ($(this.unique).getElementsBySelector('[class="popupdiv_content"]'))[0];
							var version = parseFloat(navigator.appVersion.split('MSIE')[1]);
							if ((version >= 5.5) && (version < 7) && (document.body.filters)) {
								writediv.setStyle({
									height: ($(this.unique).getHeight()-91)+'px'
								});
								
								if (writediv.getHeight() < 130){	//IE has no minHeight, so force height.
									writediv.setStyle({
										height: "130px"
									});
								}
							}
						}
						
						//set the buttons for the popup
						if (!this.buttonsSettled){
							var puw_footerbutton1 = new Element('a', { 'id':this.unique+'_footer', 'class':'popupdiv_closebutton leftside', 'href':'javascript:void(0);' }).update(this.passiveButtonText);
							var puw_footerbutton2 = new Element('a', { 'id':this.unique+'_footer2', 'class':'popupdiv_closebutton rightside', 'href':'javascript:void(0);' }).update(this.actionButtonText);
							var puw_footerdiv = new Element('div', { 'id':this.unique+'_footerbar', 'class': 'popupdiv_footer' }).insert(puw_footerbutton1).insert(puw_footerbutton2).hide();
							
							$(this.unique+'_footerbar').replace(puw_footerdiv);
							$(this.unique).setStyle({
								height:	computedHeight		//reset height to normal first. 
							});
							//alert( $(this.unique).getHeight() );
							switch (this.numButtons){
								case 0:
									$(this.unique+'_footerbar').show();
									$(this.unique+'_footer').fade({duration: 0.4});
									$(this.unique+'_footer2').fade({duration: 0.2});
									if ( $(this.unique).getStyle('opacity')<1 ){	//if the window is popping out, set dimensions immediately
										new Effect.Morph( this.unique, {
											style: {
												height:	$(this.unique).getHeight()-24+'px'
											},
											duration: 0.01
										});
									} else {	//if the window already exists, set dimensions gradually
										new Effect.Morph( this.unique, {
											style: {
												height:	$(this.unique).getHeight()-24+'px'
											},
											duration: 0.4
										});
									}
									break;
								case 1:
									$(this.unique+'_footerbar').show();
									$(this.unique+'_footer2').hide().absolutize().fade({duration: 0.2});
									$(this.unique+'_footer').hide().removeClassName('leftside').appear({duration: 0.3});
									break;
								case 2:
									$(this.unique+'_footerbar').show();
									$(this.unique+'_footer').addClassName('leftside').hide().appear({duration: 0.2});
									$(this.unique+'_footer2').hide().appear({duration: 0.4});
									break;
							}
							this.buttonsSettled = true;
						}
						//END setButtons
						
						//write actions
						if ($(this.unique+'_footer') ){
							if (this.passiveFunctions){
								$(this.unique+'_footer').observe('click', this.passiveFunctions);
							} else { //clear the passive functions
								$(this.unique+'_footer').stopObserving('click', this.passiveFunctions );
							}
							//listen for click on the close button
							this.closePopupObserver = (this.closePopup).bindAsEventListener(this);
							$(this.unique+'_footer').observe("click", this.closePopupObserver );
						}
						if ($(this.unique+'_footer2') ){
							if (this.actionFunctions) {
								$(this.unique+'_footer2').observe('click', this.actionFunctions);
							} else { //clear the action functions
								$(this.unique+'_footer2').stopObserving('click', this.actionFunctions );
							}
						}
					}
	},
	getScreenDimensions: function(){
					this.screenWidth  = document.documentElement.clientWidth;
					this.screenHeight = document.documentElement.clientHeight;
	},
	miscAlert: function(showString){
					alert(showString);
	}
}); //end revolutionary popup class