/**
 * Creates draggable windows
 * Content can either be specified, or fetched via ajax
 * Usage: 
 * new Overlay('ID', 'Title', 	'Content'); -> Creates a window with the title "Title" and the content "Content"
 * new Overlay('ID', 'Google', 	'http://google.de', 	{ ajax: true }); -> Creates a window with the title "Google" and the Google-Page as content
 * new Overlay('ID', 'Google', 	'http://google.de', 	{ ajax: true, evalScripts: true }); -> Creates a window with the title "Google" and the Google-Page as content and evals JavaScript
 * new Overlay('ID', 'Title', 	'Content', 		{ width: 200, height: 50 }); -> Creates a window with the title "Title" and the content "Content" which has got a width of 200px and a height of 50 (90, the headline and the resizebar are not counted) px
 * 
 * @author 	Tim Düsterhus
 * @copyright 	2010 - 2011 Tim Düsterhus
 * @package 	timwolla.wcf.overlayjs
 * @license 	LGPL <http://www.gnu.org/licenses/lgpl.html>
 */

var OverlayHandler = Class.create();
OverlayHandler.prototype = {
	initialize: function() {
		/**
		 * the id of the window, that is currently resized
		 * 
		 * @var integer
		 */
		this.resizing = 0;
		
		/**
		 * mouseposition when resize started
		 * 
		 * @var integer
		 */
		this.startX = 0;
		this.startY = 0;
		
		/**
		 * the dimensions of the window when resizing started
		 * 
		 * @var integer
		 */
		this.width = 0;
		this.height = 0;
		
		/**
		 * array with all overlay objects
		 * 
		 * @var	Array<Overlay>
		 */
		this.overlays = new Array();
		
		/**
		 * next z-index
		 */
		this.zindex = 50;
	},
	eventHandler: function(event) {
		// set the values if they are not
		if (OverlayHandlerObj.startX == 0) OverlayHandlerObj.startX = Event.pointerX(event);
		if (OverlayHandlerObj.startY == 0) OverlayHandlerObj.startY = Event.pointerY(event);
		if (OverlayHandlerObj.width == 0) OverlayHandlerObj.width = parseInt($('overlayContainer'+OverlayHandlerObj.resizingID).style.width.gsub('px', ''));
		if (OverlayHandlerObj.height == 0) OverlayHandlerObj.height = parseInt($('overlay'+OverlayHandlerObj.resizingID).style.height.gsub('px', ''));
		
		switch (event.type) {
			case 'mousemove': 
				// resize it
				$('overlayContainer'+OverlayHandlerObj.resizingID).style.width = OverlayHandlerObj.width + (Event.pointerX(event) - OverlayHandlerObj.startX) + 'px';
				if ($('overlay'+OverlayHandlerObj.resizingID).style.display != 'none') {
					$('overlay'+OverlayHandlerObj.resizingID).style.height = OverlayHandlerObj.height + (Event.pointerY(event) - OverlayHandlerObj.startY) + 'px';
				}
			break;
			
			case 'mouseup':
				// reset the values
				OverlayHandlerObj.resizingID = 0;
				OverlayHandlerObj.startX = 0;
				OverlayHandlerObj.startY = 0;
				OverlayHandlerObj.width = 0;
				OverlayHandlerObj.height = 0;
				
				// stop observing
				if (IS_IE) {
					document.stopObserving('mousemove', OverlayHandlerObj.eventHandler);
				}
				else {
					window.stopObserving('mousemove', OverlayHandlerObj.eventHandler);
				}
				document.stopObserving('mouseup', OverlayHandlerObj.eventHandler);
			break;
		}
	}
}

var OverlayHandlerObj = new OverlayHandler();

var Overlay = Class.create();
Overlay.prototype = {
	/**
	 * Creates a new Window
	 * 
	 * @param	mixed	overlayID	one individual ID for this overlay
	 * @param	string	title 		title of the window
	 * @param	string	content		either url or html
	 * @param 	json	options		The options
	 * -> 	ajax				= should the content be defined or fetched via ajax 			(default: false)
	 *		evalScripts		= if ajax == true: eval javascript? 					(default: false)
	 *		width			= start width of the window 						(default: 300)
	 *		height			= start height of the window 						(default: 200)
	 *		left			= absolute position in px of the left side 				(default: 300)
	 * 		top			= absolute position in px of the top side 				(default: 20)
	 *		zindex			= css z-index 								(default: auto increment)
	 *		resizable		= should the window can be resized?					(default: true)
	 * 		draggable 		= should the window can be dragged?					(default: true)
	 * 		minimizable		= should the window can be minimized?					(default: true)
	 * 		closeable 		= should the window can be closed?					(default: true)
	 */
	initialize: function(overlayID, title, content, options) {
		if (typeof OverlayHandlerObj.overlays[overlayID] != 'undefined') return;
		
		OverlayHandlerObj.overlays[overlayID] = this;
		this.overlayID = overlayID;
		this.title = title;
		this.content = content;
		if (!options.zindex) {
			options.givenZindex = false;
		}
		else {
			options.givenZindex = true;
		}
		
		this.options = {
			ajax: false, 
			evalScripts: false, 
			width: 300, 
			height: 200, 
			left: 300, 
			top: 30, 
			zindex: ++OverlayHandlerObj.zindex,
			resizable: true,
			draggable: true,
			minimizable: true,
			closable: true
		};
		Object.extend(this.options, options || {});
		
		var container = Builder.node("div", { className: "border titleBarPanel", id: 'overlayContainer'+this.overlayID, style: "width: "+this.options.width+"px; position: absolute; left: "+ this.options.left +"px; top: "+ this.options.top +"px; z-index: "+this.options.zindex+";" }, [
			// headline
			Builder.node("div", { className: "containerHead", id: 'overlayTitle'+this.overlayID }, [
				// icons
				Builder.node("div", { className: "containerIcon", style: "width: 46px" }, [
					// close
					Builder.node("a", { id: 'overlayCloser'+this.overlayID }, [
						Builder.node("img", { src: RELATIVE_WCF_DIR + 'icon/delete'+((this.options.closable) ? '' : 'Disabled')+'S.png' }, [])
					]),
					
					// minimize
					Builder.node("a", { id: 'overlayMinimizer'+this.overlayID }, [
						Builder.node("img", { src: RELATIVE_WCF_DIR + 'icon/'+((this.options.minimizable) ? 'minus' : 'userBanDisabled')+'S.png', id: 'overlay'+this.overlayID+'Image' }, [])
					])
				]),
				
				// title
				Builder.node("div", { className: "containerContent" }, [
					Builder.node("h3", { }, this.title)
				])
			]),
			
			// content
			Builder.node("div", { className: 'container-1', id: 'overlay'+this.overlayID, style: "overflow: auto; height: "+this.options.height+"px;" }, [ ]),
			
			// resizer
			Builder.node("div", { id: 'overlayResizer'+this.overlayID, className: 'mceResizeIconRow' }, [ 
				Builder.node("div", { className: 'container-1' }, [ 
					Builder.node("div", { className: 'mceResizeIcon' }, []) 
				])
			])
		]);
		
		// append the overlay to the mainContainer
		$('mainContainer').insert(container);
		
		$('overlayCloser'+this.overlayID).observe('click', this.close.bind(this));
		$('overlayMinimizer'+this.overlayID).observe('click', this.toggle.bind(this));
		$$('#overlayResizer'+this.overlayID+' div div')[0].observe('mousedown', this.resize.bind(this));
		
		if (!this.options.resizable) $('overlayResizer'+this.overlayID).remove();
					
		if (!this.options.givenZindex) {
			$('overlayTitle'+this.overlayID).observe('mousedown', function () {
				$('overlayContainer'+this.overlayID).setStyle({ zIndex: ++OverlayHandlerObj.zindex });
			}.bind(this));
		}
		
		if (this.options.draggable) {
			new Draggable('overlayContainer'+this.overlayID, { handle: 'overlayTitle'+this.overlayID });
		}
		
		if (this.options.ajax) {
			new Ajax.Updater('overlay'+this.overlayID, this.content+'&overlayID='+this.overlayID, { evalScripts: this.options.evalScripts });
		}
		else {
			$('overlay'+this.overlayID).update(this.content);
		}
	},
	
	/**
	 * closes the overlay
	 * 
	 * @return void
	 */
	close: function () {
		if (this.options.closable) {
			$('overlayContainer'+this.overlayID).fade({ 
				afterFinish: function (obj) {
					obj.element.remove();
					OverlayHandlerObj.overlays[this.overlayID] = undefined;
				}.bind(this)
			});
		}
	},
	
	/**
	 * toggle the size
	 * 
	 * @return void
	 */
	toggle: function () {
		if (this.options.minimizable) {
			openList('overlay'+this.overlayID, { 
				afterOpen: function () { 
					$('overlay'+this.overlayID).setStyle({overflow: 'auto'}); 
				}.bind(this) 
			});
		}
	},
	
	/**
	 * starts resizing
	 * 
	 * @return void
	 */
	resize: function () {
		if (OverlayHandlerObj.resizingID > 0) return;
		OverlayHandlerObj.resizingID = this.overlayID;
		if (IS_IE) {
			Event.observe(document, 'mousemove', OverlayHandlerObj.eventHandler);
		}
		else {
			Event.observe(window, 'mousemove', OverlayHandlerObj.eventHandler);
		}
		Event.observe(document, 'mouseup', OverlayHandlerObj.eventHandler);
	}
}

