/**
 * HelpBalloon
 * Prototype/Scriptaculous based help balloons
 * @copyright 2006 Beau D. Scott
 */
var Popup = Class.create();
Popup.prototype = {

	/**
	 * Instantiates the object
	 * @param {Object} options
	 */
	initialize: function(options)
	{
		/**
		 * Establish default options and apply specified values
		 */
		this.options = DOMHelper.setOptions({			
			showCloser: true,
			icon: 'images/icon_info.gif',						//url to the icon to use
			altText: 'Click here for help with this topic',		//Alt text of the help icon
			href: null,										//URL to pull the title/content XML
			content: 'Content',									//Static content of the help balloon
			duration: .5,										//Duration of fade/appear affect
			useEvent: ['click'],								//Events to trigger the balloon
			imagePath: root + '/images/',
			method:	'get',										//Method to retrieve the AJAX content
			usingJSON: false,									//Using JSON
			width: 0,
			height: 0
		}, options||{});

		/**
		 * collection of object elements
		 */
		this._elements = {
			outer: null,
			container: null,									//Containing element of the balloon
			inner: null,										//Inner content container
			content: null,										//Body Content container
			button: null,										//Closing 'X' button
			title: null,										//Title Content Container
			bgContainer: null,									//For IE, renders the alpha-transparent PNG
			titleContainer: null,								//Title Container
			contentContainer: null,								//Content Container
			resizer: null,										//Resizer
			iframe: null,										//for fixing IE select
			closer: null,										//closer
			topHead: null,										//top head div
			head: null,											//head div
			body: null,											//body
			bottom: null,										//bottom
			masker: null										//masker			
		};
		
		this.updateSize = true;
		this.transaction = null;
		/**
		 * Properties and Attributes
		 */
		this._properties = {
			id: "popup",				//ID for object and Icon, Requires prototype.improvements.jss			
			popupStyle: {										//Balloon styling
				position: 'absolute',
				//border: 'none',
				//background: 'white',
				//width: '300px',
				//height: '240px',				
				//display: 'none',
				opacity: 0
			},
			button: this.options.imagePath + 'button.png',		//Closing 'X' image
			visible: false,										//Status of Balloon's visibility
			popupCoords: null,								//Stores the balloon coordinates
			drawn: false,										//Rendering status
			renderXY: [0,0],									//X/Y coordinate of icon at time of render
			currentFontSize: 16,									//normal font size
			baseFontSize: 16,
			bodyHeight: 0,
			lastYPosition: 0,
			marginTop: 40,
			visiblePart: 100,
			loading: "<span class=\"loading\">Loading ... </span>"
		};
		

		this._elements.outer = document.createElement('div');
		this._elements.outer.id = "popup_outer";	
		this._elements.outer.className = "popupBox";

		this._elements.content = document.createElement('div');
		this._elements.content.id = "popup_content";
		this._elements.content.className = "popupBox_content";
		this._elements.content.innerHTML = this._properties.loading;
	},
	
	_showMasker: function()
	{
		if (this._elements.masker)
		{				
			this._elements.masker.className = "cssbox_masker";						
			this._elements.masker.style.width = DOMHelper.getDocumentWidth() + "px";
			this._elements.masker.style.height = DOMHelper.getDocumentHeight() + "px";				
			this._elements.masker.style.zIndex = "200";
		}
	},	
	_remask: function(height)
	{
		if (this._elements.masker)
		{
			this._elements.masker.style.height = height + "px";
		}
	},
	show: function()
	{
		if(!this._properties.drawn) this._draw();				
		this._reposition();
		this._showMasker();		
		Frucall.Effects.Appear(this._elements.outer, this.options.duration);
		this._properties.visible = true;				
	},	
	resize: function(width, height) {
		//this._elements.content.style.opacity = "0";
		var ww = DOMHelper.getClientWidth();
		var wh = DOMHelper.getClientHeight();
				
		var scrollx = window.pageXOffset || document.body.scrollLeft || 0;
		var scrolly = window.pageYOffset || document.body.scrollTop || 0; 
		
		var centerLeft = Math.round((ww - width)/2);
		var centerTop = Math.round((wh - height)/3) + scrolly;
		
		if (centerTop < 0) centerTop=0;
		if (centerLeft < 0) centerLeft = 0;
		
		this.options.width = width;
		this.options.height = height;

		Frucall.Effects.Scale(this._elements.outer, width, height, centerTop, centerLeft, 0.5, (function(){
			//this._elements.content.style.opacity = "0";
		}).bind(this));		
	},
	goNext: function(params)
	{
		this._elements.content.innerHTML = this._properties.loading;
		var ww = DOMHelper.getClientWidth();
		var wh = DOMHelper.getClientHeight();
				
		var scrollx = window.pageXOffset || document.body.scrollLeft || 0;
		var scrolly = window.pageYOffset || document.body.scrollTop || 0; 
		
		var centerLeft = Math.round((ww - params.width)/2);
		var centerTop = Math.round((wh - params.height)/3) + scrolly;
		
		if (centerTop < 0) centerTop=0;
		if (centerLeft < 0) centerLeft = 0;
		
		this.options.href = params.href;
		this.options.width = params.width;
		this.options.height = params.height;

		Frucall.Effects.Scale(this._elements.outer, params.width, params.height, centerTop, centerLeft, 0.5, (function(){
			
			this.transaction = new AjaxHelper.Request(this.options.href, {asynchronous: true, method: this.options.method, onComplete: (function(obj){								
				var content = new String(obj.responseText);
				this._elements.content.innerHTML = content;
				StringHelper.extractScripts(content).map(function(script) { 										
					return eval(script.replace("<!--", "").replace("// -->", ""));
				});
		 }).bind(this)});		
		 
		 this.transaction.getResponse();

		}).bind(this));
		
		
	},
	/**
	 * Hides the balloon
	 */
	hide: function()
	{
		this._elements.outer.style.display = "none";	
		this._properties.visible = false;		
		this.event("afterClose");
		this.removePopup();
		return;
	},

	
	/**
	 * Redraws the balloon based on the current coordinates of the icon.
	 */
	_reposition: function()
	{		
		var ww = DOMHelper.getClientWidth();
		var wh = DOMHelper.getClientHeight();
		
		//var scrollx = EventHelper.isIE() ? document.body.scrollLeft : window.pageXOffset;
		//var scrolly = EventHelper.isIE() ? document.body.scrollTop : window.pageYOffset;
				
		var scrollx = window.pageXOffset || document.body.scrollLeft || 0;
		var scrolly = window.pageYOffset || document.body.scrollTop || 0; 
		
		var centerLeft = Math.round((ww - this.options.width)/2);
		var centerTop = Math.round((wh - this.options.height)/3) + scrolly;

		this._elements.outer.style.left = centerLeft + "px";
		this._elements.outer.style.top = centerTop + "px";
		
	},
	
	_draw: function()
	{
		if(this.options.href)
		{			
			(new AjaxHelper.Request(this.options.href, {asynchronous: true, method: this.options.method, onComplete: (function(obj){								
				var content = new String(obj.responseText);
				this._elements.content.innerHTML = content;
				StringHelper.extractScripts(content).map(function(script) { 										
					return eval(script.replace("<!--", "").replace("// -->", ""));
				});
			}).bind(this)})).getResponse();											
		}		
		this._drawBox();		
	},
	/**
	 * Render's the Balloon
	 */
	_drawBox: function()
	{		
		DOMHelper.setStyles(this._elements.outer, this._properties.popupStyle);
		
		var topCap = document.createElement('div');		
		topCap.className = "popupBox_topCap";		
		this._elements.outer.appendChild(topCap);

		var topCapRight = document.createElement('div');
		topCapRight.className = "popupBox_topCapRight";
		topCap.appendChild(topCapRight);

		var topCapMiddle = document.createElement('div');
		topCapMiddle.className = "popupBox_topCapMiddle";
		topCapRight.appendChild(topCapMiddle);
		
		if (this.options.showCloser == true)
		{
			
			var closerBar = document.createElement('div');
			closerBar.className = "popupBox_closerBar";
			
			closer = new Image(14,13);
			closer.id = "closeImage";
			closer.src = this.options.imagePath + "close.gif";
			EventHelper.addListener(closer, 'click', this.hide, this, true);
			closer.style.cursor = 'pointer';
			closer.title = 'Click to close this popup';			
			closerBar.appendChild(closer);

			this._elements.outer.appendChild(closerBar);
		}

		this._elements.outer.appendChild(this._elements.content);

		var bottomCap = document.createElement('div');		
		bottomCap.className = "popupBox_bottomCap";				
		this._elements.outer.appendChild(bottomCap);

		var bottomCapRight = document.createElement('div');
		bottomCapRight.className = "popupBox_bottomCapRight";
		bottomCap.appendChild(bottomCapRight);

		var bottomCapMiddle = document.createElement('div');
		bottomCapMiddle.className = "popupBox_bottomCapMiddle";
		bottomCapRight.appendChild(bottomCapMiddle);

		this._elements.masker = document.createElement("div");
		
		this._elements.outer.style.width = this.options.width + "px";
		this._elements.outer.style.height = this.options.height + "px";
		
		this._elements.content.style.width = "100%";
		this._elements.content.style.height = "100%";

		document.getElementsByTagName('body')[0].appendChild(this._elements.masker);
		document.getElementsByTagName('body')[0].appendChild(this._elements.outer);
			
		EventHelper.addListener(window, 'scroll', this._onScrolling, this, true);

		this._properties.drawn = true;	
				
	},	
	_onScrolling: function(e)
	{		
		var scrolly = window.pageYOffset || document.documentElement.scrollTop || 0; 
		var wh = DOMHelper.getClientHeight();			
		var elHeight = DOMHelper.getHeight(this._elements.outer);

		var currentTop = parseInt(this._elements.outer.style.top);
		var currentBottom = currentTop + elHeight;
		
		var currentScreenTop = scrolly;
		var currentScreenBottom = currentScreenTop + wh;

		var bdHeight = DOMHelper.getDocumentHeight();
		
		var newTop = Math.round((wh - this.options.height)/2) + scrolly;			
		var underCover = elHeight - wh - this._properties.marginTop;			

		var isDown = (scrolly - this._properties.lastYPosition > 0) ? 1 : 0; // 1: true, 0: false			
		
		if (isDown == 1) // scroll down
		{					
			newTop = currentTop + this._properties.visiblePart - currentBottom + scrolly;
			if (currentBottom - scrolly < this._properties.visiblePart)
			{
				//alert(this._properties.visiblePart - (currentBottom - scrolly));
				//alert(currentTop + " " + newTop);
				this._elements.outer.style.top = newTop + "px";
			}
		}
		else // scroll up
		{
			newTop = currentTop - (this._properties.visiblePart - (currentScreenBottom - currentTop));
			if (currentScreenBottom - currentTop < this._properties.visiblePart)
			{
				this._elements.outer.style.top = newTop + "px";
			}					
		}
		
		this._remask(parseInt(this._elements.outer.style.top) + elHeight > bdHeight ? parseInt(this._elements.outer.style.top) + elHeight : bdHeight);
		this._properties.lastYPosition = scrolly;			
	},
	
	event: function(eventName) {
		if(this.options[eventName]) {
			var returnValue = this.options[eventName](); // Executing callback
			//this.options[eventName] = null; // Removing callback after execution
			if(returnValue != undefined) 
				return returnValue;
			else 
				return true;
		}
		return true;
	},

	setContent: function(content) {		
		if (this._elements.contentContainer) this._elements.contentContainer.innerHTML = content;
	},
	
	setMouseOver: function(handler) {
		this._elements.container.onmouseover = handler;
	},
	setMouseOut: function(handler) {
		this._elements.container.onmouseout = handler;
	},
	clearMouseOut: function() {
		this._elements.container.onmouseout = function() {};
	},
	removePopup: function() {
		parentNode = this._elements.outer.parentNode;
		if (parentNode) 
		{	
			parentNode.removeChild(this._elements.outer);
			if (this._elements.masker) 				
			{
				parentNode.removeChild(this._elements.masker);
				this._elements.masker = null;
			}
		}
	},
	updateContent: function(dataURL) {
		var transaction = (new AjaxHelper.Request(dataURL, {asynchronous:false, method: this.options.method})).getResponse();
		if (transaction.conn.responseText)
		{
			content = new String(transaction.conn.responseText);
			this.setContent(content);
			StringHelper.extractScripts(content).map(function(script) { 
				return eval(script.replace("<!--", "").replace("// -->", ""));
			});
		}
	},
	fontChanged: function(newFontSize) {
		
		if (this._properties.currentFontSize > newFontSize) // smaller font - change it
		{			
			diff = this._properties.currentFontSize - newFontSize;
			this._elements.outer.style.top = (parseInt(this._elements.outer.style.top) + (diff * 6)) + "px";			
			this._elements.outer.style.left = (parseInt(this._elements.outer.style.left) + (diff * 0.5)) + "px";
			this._elements.pointer.style.top = (parseInt(this._elements.pointer.style.top) - (diff * 7)) + "px";
			this._properties.currentFontSize = newFontSize;
		}
	},
	setBaseFontSize: function(fontSize) {
		this._properties.baseFontSize = fontSize;
	}
};