/**
 * Zig-Popup	
 * 
 * @author Bhe, Ntb, JMu
 * @version 1.0
 * @copyright Copyright (c) 2009, Zig Websoftware
 * @buildOn Scriptaculous, Prototype
 */

/**
 *  BUG: <<<-	IE7&8 - tonen van 2x achter elkaar img/album popup in een pagina werkt niet.
 *  BUG: <<<-	Na laden van foto popup tekst heeft hoogte van vorige image. Andersom ook.
 *  			Bij brede foto in album popup en daarna het open van een tekstpopup zie je kort de morph van breedte vorige window
 *  			naar huidige breedte tekstwindow. Hoogte komt niet mee.
 *  			Ook in album met verschillende hoogte img's komt de hoogte niet mee met morph als je next/prev img doet. Breedte morpht wel goed.
 *  			(Heeft height wel een functie? Of kan deze beter naar de css verhuizen...)
 *  BUG: <	-	IE7 bij foto's produceert een spatie oid ergens een streep/underscore zichtbaar is bovenin het witgedeelte. (ik denk in een A element) 
 *  BUG:	-	Kleine flikkering in tonen (eerste) img.
 *  
 *  Improve	-	Display van eerste img eerst window default size met "loading" en dan resizen op moment dan img goed geladen is.
 *  Improve	-	Caching van images in album. Pas cachen als eerste afbeelding getoond is.
 *  Improve	-	Bij images/album de close button het zelfde laten verschijnen/verdwijnen als next/prev buttons. Zowel bij openen als resize.
 *  Improve	-	In album img tonen die aangeklikt wordt en niet standaard eerste in album.
 *  Improve	-	Album (bijv) 1 van 6 tonen
 *  Improve	-	Popup close eerst window sluiten met snelheid van popupDuration en dan Overlay sluiten met
 *  			snelheid van overlayDuration met tussen het sluiten van window en sluiten van overlay de tijd van popupTimeout.
 *  Improve	-	Verbeterde centrering van popup. Zowel horizontaal als verticaal mooi in het midden.
 *  			Nu werkt goed. Centreert ook als je naar beneden gescrolled bent maar bij img die even groot is als je scherm heb je altijd nog zo'n 30px topspace.
 *  Improve	-	Bij tonen van Single Image een manier maken om niet via de Album manier, Popup.open({album: 'AlbumNaam'}) && <a rel="AlbumNaam"> gaat maar bijv alleen Popup.open(img);
 *  			Er zou bij 1 image geen rel in het A element nodig moeten zijn.
 *  
 *  Wish:	-	Dynamic onclick="Popup.close(); op overlay bij tonen closebutton. Als closebutton false is ook geen close op overlay.
 *
 *	Content
 * <a href="/content/page" onclick="Popup.open({content: 'Lorem ipsum doplor sit amet...'});">Show content</a>
 * <a href="/content/page" onclick="Popup.open({content: 'Lorem ipsum doplor sit amet...', title: 'Lirem opsum'});">Show content</a>
 *
 *	Single and Multiple images in Album
 * <a href="/images/picture.jpg" onclick="Popup.open({album: 'Flowers'});return false;" rel="Flowers"><img src="/images/picture.jpg" alt="Picture" />
 */

var Popup = 
{
	iMarginTop	 : null,
	
	oActiveAlbumPicture : null,
	
	aAlbumPictures : new Array(),
	
	iActiveAlbumKey : null,
	
	/**
	 * Config Options
	 */
	setOptions: function(aOptions)
	{
		this.aOptions = {

			//Popup options
	    	id				: 'popup',		// id of popup
			popupTimeout	: 500,			// Timeout for time between fade-in Overlay and appearing Window
			popupDuration	: 0.6,			// Window fade in/out duration
			width			: 300,			// width of popup in px
			height			: 100,			// height of popup in px
			containerPadding : 24, 		// padding of popup window (space between window en content)
			

	    	//Overlay options
	    	overlayId		: 'overlay',	// id of overlay element
	    	showOverlay		: true,			// show overlay
			overlayDuration	: 0.3,			// Overlay fade in/out duration
			overlayFadeFrom	: 0.0,			// From where must the fade-in start? 0.0 = transparent
			overlayFadeTo	: 0.6,			// From where must the fade-in end? 1.0 = solid


	    	//FotoAlbum options
			album			: '',			// Name of album images belong to if any
	    	albumKey		: 0,			// key of album image to show (default is first one)
	    	prevContent		: 'Vorige',		// prev text
	    	nextContent		: 'Volgende',	// next text


			//Content options
	    	title			: '',			// title of content
	    	content			: '',			// content in popup
	    	showClose		: true,			// show close button
	    	showConfirm		: true,		// show confirm buttons	  
	    	showConfirmSuccess: true, // show OK button
	    	showConfirmCancel: true, 		// show cancel button
	    	textConfirmSucces: 'OK',	// text OK button
	    	textConfirmCancel: 'Annuleer', // text Cancel button
	      	onConfirmSuccess: null,			// callback function onConfirmSuccess
	      	onConfirmCancel	: null			// callback function onConfirmCancel
		}

	    Object.extend(this.aOptions, aOptions || {});
		
	    //empty the content
		$(this.aOptions.id+'_content').innerHTML = '';

		//create title
		if(this.aOptions.title)
		{
			var oTitle = document.createElement('h3');
			oTitle.innerHTML = this.aOptions.title;
			$(this.aOptions.id+'_content').appendChild(oTitle);
		}

		//add content
		$(this.aOptions.id+'_content').innerHTML  += this.aOptions.content;

		//create album
		if(this.aOptions.album)
		{
			var oPopup = this;
			var aLinks = $$('a[rel="'+this.aOptions.album+'"]');
			
			
			aLinks.each(function(oEl,iKey)
			{
				//clone, hide, save in popup and add it to the content
				oImage = new Image();
				oImage.src = oEl.href;
				oImage.style.display = 'none';
				oImage.id = oPopup.aOptions.album + '_image_' + iKey;
				oPopup.aAlbumPictures[iKey] = oImage;	
				$(oPopup.aOptions.id+'_content').appendChild(oImage);
			});
			
			//show first picture...
			this.showAlbumPicture(this.aOptions.albumKey);
		}

		//show/hide confirm buttons
		if(this.aOptions.showConfirm)
		{
			$(this.aOptions.id+'_confirm').style.display = 'block';
			
			$(this.aOptions.id+'_confirmSuccess').innerHTML = this.aOptions.textConfirmSucces;
			$(this.aOptions.id+'_confirmCancel').innerHTML = this.aOptions.textConfirmCancel;

			// JMu: Visibility OK/Cancel buttons
			if(this.aOptions.showConfirmSuccess)
			{
				$(this.aOptions.id+'_confirmSuccess').style.display = 'block';
			}
			else
			{
				$(this.aOptions.id+'_confirmSuccess').style.display = 'none';				
			}
			
			if(this.aOptions.showConfirmCancel)
			{
				$(this.aOptions.id+'_confirmCancel').style.display = 'block';
			}
			else
			{
				$(this.aOptions.id+'_confirmCancel').style.display = 'none';				
			}
			
			if(this.aOptions.onConfirmSuccess)
			{
				var sOnConfirmSuccess = this.aOptions.onConfirmSuccess;
				$(this.aOptions.id+'_confirmSuccess').onclick = sOnConfirmSuccess;
			}
			else
			{
				$(this.aOptions.id+'_confirmSuccess').onclick = function(){ Popup.close();return false; }
			}
			
			if(this.aOptions.onConfirmCancel)
			{
				var sOnConfirmCancel = this.aOptions.onConfirmCancel;
				$(this.aOptions.id+'_confirmCancel').onclick = sOnConfirmCancel;
			}
			else
			{
				$(this.aOptions.id+'_confirmCancel').onclick = function(){ Popup.close();return false;  }
			}
		}
		else
		{
			$(this.aOptions.id+'_confirm').style.display = 'none';
		}
		
		//show/hide closebutton
		if(this.aOptions.showClose)
		{
			$(this.aOptions.id+'_close').style.display = 'block';
		}
		else
		{
			$(this.aOptions.id+'_close').style.display = 'none';
		}
	},

	/**
	 * Open popup
	 */
	open: function(aOptions)
	{
	
		this.setOptions(aOptions);
		this.adjustSize();
		this.adjustPosition();
		this.showOverlay();

		var sId = this.aOptions.id;
		
		setTimeout("Effect.Appear('"+sId+"')", this.aOptions.popupTimeout);

		// Workaround voor de bug. Moet nog even netjes opgeost worden dmv Prototype Observers
		setTimeout(function() { this.adjustSize();this.adjustPosition(); }.bind(this), 50);
	},

	/**
	 * Close popup
	 */
	close: function(aOptions)
	{
		var oPopup = this;
		
		new Effect.Fade(this.aOptions.id, {	
											duration: oPopup.aOptions.popupDuration,
											afterFinish: function(){oPopup.setOptions(aOptions);}
											}
						);
		
		this.hideOverlay();
	},

								/*** POPUP CORE ***/

	/**
	 * Show overlay
	 */
	showOverlay: function()
	{
		if(this.aOptions.overlayId && $(this.aOptions.overlayId) && this.aOptions.showOverlay)
		{
			var aPageSize = this.getPageSize();
			$(this.aOptions.overlayId).style.height = aPageSize[1]+'px';

			new Effect.Appear(this.aOptions.overlayId, {duration: this.aOptions.overlayDuration, from: this.aOptions.overlayFadeFrom, to: this.aOptions.overlayFadeTo});
		}
	},

	/**
	 * Hide overlay
	 */
	hideOverlay: function()
	{
		if(this.aOptions.overlayId && $(this.aOptions.overlayId))
		{
			new Effect.Fade(this.aOptions.overlayId, {duration: this.aOptions.overlayDuration});
		}
	},

	/**
	 * adjust popup size
	 */
	adjustSize: function()
	{
		var oPopup = this;
		var iHeight = this.aOptions.height;
		
		if(this.aOptions.album)
		{
			var iWidth = this.oActiveAlbumPicture.width;
			var iHeight = this.oActiveAlbumPicture.height;
		}
		else
		{
			var iWidth 	= this.aOptions.width;
			
		}
		
		if(iWidth < this.aOptions.width)
		{
			iWidth = this.aOptions.width;
		}

		var sStyleWidth = 'width:'+iWidth+'px;';
		var sStyleWidthContainer = 'width:'+ (iWidth +  2 * this.aOptions.containerPadding) +'px;';	
		var sStyleHeight = '';

		if(iHeight > this.aOptions.height)
		{
			sStyleHeight = 'height:'+ iHeight +'px;';
		}


		new Effect.Morph(this.aOptions.id+'_content',{
			style: sStyleHeight + sStyleWidth,
			duration: 0.5
		});
		
		new Effect.Morph(this.aOptions.id+'_window',{
			style: sStyleWidthContainer,
			duration: 0.5,
			afterFinish: function(){oPopup.adjustSizeCallBack();}
		});
	},
	/**
	 * called when popup size is adjusted
	 */
	adjustSizeCallBack: function()
	{
		var oContentWindow = $(this.aOptions.id+'_content');
		var oWindow = $(this.aOptions.id+'_window');
		oWindow.style.marginLeft =  oWindow.getWidth() * -.5+ 'px';
		
		$('t').style.width = oContentWindow.getWidth() + 'px';
		$('r').style.height = oContentWindow.getHeight() + 'px';
		$('b').style.width = oContentWindow.getWidth() + 'px';
		$('l').style.height = oContentWindow.getHeight() + 'px';
		
		
		if(this.aOptions.album)
		{
			this.showPicture();
		}
	},
	/**
	 * adjust popup window to show him correct vertically
	 */
	adjustPosition: function()
	{
		if(!this.iMarginTop && this.iMarginTop != 0)
		{	
			this.iMarginTop = parseInt($(this.aOptions.id+'_window').getStyle('margin-top').replace('px',''));
		}
		aScroll = this.getScrollSize();

		$(this.aOptions.id+'_window').style.marginTop = this.iMarginTop + aScroll[1] + 'px';
	},

	/**
	 * get scroll size
	 * @return array
	 */
	getScrollSize: function () 
	{
		
		  var iScrollX = 0, iScrollY = 0;
		  if( typeof( window.pageYOffset ) == 'number' ) 
		  {
			  iScrollY = window.pageYOffset;
			  iScrollX = window.pageXOffset;
		  } 
		  else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) 
		  {
			  iScrollY = document.body.scrollTop;
			  iScrollX = document.body.scrollLeft;
		  } 
		  else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) 
		  {
			  iScrollY = document.documentElement.scrollTop;
			  iScrollX = document.documentElement.scrollLeft;
		  }
		  
		  return [ iScrollX, iScrollY ];
	},
	/**
	 * get page size
	 * @return array
	 */
	getPageSize: function()
	{
		var xScroll, yScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = document.body.scrollWidth;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		
		var windowWidth, windowHeight;
		if (self.innerHeight) {	// all except Explorer
			windowWidth = self.innerWidth;
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
		
		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){
			pageHeight = windowHeight;
		} else { 
			pageHeight = yScroll;
		}

		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){	
			pageWidth = windowWidth;
		} else {
			pageWidth = xScroll;
		}


		aArrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
		return aArrayPageSize;
	},
	
	/**
	 * build album navigation
	 * 
	 */
	initAlbumNavigation: function()
	{
		var oPopup = this;

		if(!$(this.aOptions.id+'_prev'))
		{
			var oPrevious = document.createElement('a');
			oPrevious.innerHTML = this.aOptions.prevContent;
			oPrevious.id = this.aOptions.id+'_prev';
			oPrevious.style.display ='none';
			oPrevious.onclick = function(){oPopup.showAlbumPicture(oPopup.iActiveAlbumKey - 1);};
			$(this.aOptions.id+'_content').appendChild(oPrevious);
		}

		if(this.iActiveAlbumKey != 0)
		{
			new Effect.Appear(this.aOptions.id+'_prev',{duration: 0.2});
		}

		if(!$(this.aOptions.id+'_next'))
		{
			var oNext = document.createElement('a');
			oNext.innerHTML = this.aOptions.nextContent;
			oNext.id = this.aOptions.id+'_next';
			oNext.style.display ='none';
			oNext.onclick = function(){oPopup.showAlbumPicture(oPopup.iActiveAlbumKey + 1);};
			$(this.aOptions.id+'_content').appendChild(oNext);
		}
	
		if(this.iActiveAlbumKey != (this.aAlbumPictures.length - 1))
		{	
			new Effect.Appear(this.aOptions.id+'_next',{duration: 0.2});
		}
	},
	/**
	 * hide album navigation
	 */
	hideAlbumNavigation: function()
	{
		if($(this.aOptions.id+'_next'))
		{
			$(this.aOptions.id+'_next').style.display = 'none';
		}
		if($(this.aOptions.id+'_prev'))
		{
			$(this.aOptions.id+'_prev').style.display = 'none';
		}
	},
	/**
	 * show picture of a album
	 * 
	 * @param integer iKey
	 */
	showAlbumPicture: function(iKey)
	{	
		this.hideAlbumNavigation();

		if(this.oActiveAlbumPicture)
		{
			new Effect.Fade(this.oActiveAlbumPicture.id,{duration: 0.3});
		}
		
		this.oActiveAlbumPicture = this.aAlbumPictures[iKey];
		this.iActiveAlbumKey = iKey;
		this.adjustSize();
	},
	/**
	 * show a picture
	 * 
	 * @access private
	 */
	showPicture : function()
	{
		var oPopup = this;
		new Effect.Appear(oPopup.oActiveAlbumPicture,{afterFinish: function(){oPopup.initAlbumNavigation();}});
	}

}
