// $Id: window-utils.js 5072 2006-11-13 15:16:11Z slip $
/**
 *
 * Copyright (c) 2006 by SouthProjects
 * http://www.southprojects.com
 * Santiago, Chile,
 * Version 1.2 Dec 2006.
 * All rights reserved.
 */

/**
 * Parses given DOM element to save references into objects properties.
 * All the elements to be saved as a reference had to have a word starting
 * with 'area' in there class name. So for example an element with class name
 * areaTitle will be parsed into this.title property and those className will 
 * be removed.
 * @param el [HTML element] - element to parse;
 * @return - true if success, otherwise false;
 */
southprojects.Window.prototype.parseDom = function(el) {
	//the el needs to be a DOM HTML element
	if (!el || typeof el != "object" || !el.nodeType) {
		return false;
	}
	//seeks the elements with the className starting with word 'area',
	//extracts the rest part of this class name, creates the reference 
	//(a property of the object) with such name, removes this class.
	//I didn't knew which way to mark the elements which needed to have reference
	//in our object, and decided (by advise) to use className starting with 'area'.
	//Example: 'areaContent', 'areaTitle', etc. will create this.content, this.title, etc.
	if (el.className) {
		var classes = el.className.match(/area(\w+)/);
		//this way we mark all the elements which belong to the widget with a reference to it.
		el.win = true;
		if (classes) {
			el.id = "spWin" + this.id + classes[1];
			classes[1] = classes[1].charAt(0).toLowerCase() + classes[1].substring(1);
			southprojects.Utils.createProperty(this, classes[1], el);
			southprojects.Utils.removeClass(el, classes[0]);
		}
	}
	//to go through all the childs we use recursive calls of this function for every child.
	var child = el.firstChild;
	while(child) {
		this.parseDom(child);
		child = child.nextSibling;
	}
	
	return true;
};

/*
 * \internal
 * For internal use only. Calculates some sizes needed to implement title and status 
 * text cutting and content scrolling.
 */
southprojects.Window.prototype.calculateSizes = function () {
	if (this.titleArea) {
		this.state.titleWidth = this.state.width - (this.container.offsetWidth - this.titleText.offsetWidth);
	}
	
	if (this.content) {
		this.state.contentWidth = this.state.width - (this.container.offsetWidth - this.content.offsetWidth);
	}
	
	if (this.config.showStatus) {
		this.state.statusWidth = this.state.width - (this.container.offsetWidth - this.statusText.offsetWidth);
	}

	this.state.heightDiff = this.container.offsetHeight - this.content.offsetHeight;
}

/**
 * Updates the window "WCH" (windowed controls hider).  A WCH is an
 * "invention" (read: "miserable hack") that works around one of the most
 * common and old bug in Internet Explorer: the SELECT boxes or IFRAMES show on
 * top of any other HTML element.  This function makes sure that the WCH covers
 * correctly the window element and another element if passed.
 */
southprojects.Window.prototype.updateWCH = function() {
	var pos = southprojects.Utils.getElementPos(this.container, document.body);
	southprojects.Utils.setupWCH(this.WCH, pos.x, pos.y, this.container.offsetWidth, this.container.offsetHeight);
	return true;
}

/**
 * Reconfigurating the object due to the config options.
 */
southprojects.Window.prototype.reconfig = function() {
	var self = this;
	if (!this.fireOnState("ready", function() {self.reconfig();})) return;
	//Hiding title if needed
	if (!this.config.showTitle) {
		this.restorer.saveProp("titleArea.style.display");
		this.titleArea.style.display = "none";
	} else {
		this.restorer.restoreProp("titleArea.style.display");
		//hiding buttons if needed
		if (!this.config.showMinButton || this.state.state == "min") {
			this.restorer.saveProp("minButton.getContainer().style.display");
			this.minButton.getContainer().style.display = "none";
		} else {
			this.restorer.restoreProp("minButton.getContainer().style.display");
		}
		if (!this.config.showMaxButton || this.state.state == "max") {
			this.restorer.saveProp("maxButton.getContainer().style.display");
			this.maxButton.getContainer().style.display = "none";
		} else {
			this.restorer.restoreProp("maxButton.getContainer().style.display");
		}
		if (this.state.state != "max" && this.state.state != "min") {
			this.restorer.saveProp("restoreButton.getContainer().style.display");
			this.restoreButton.getContainer().style.display = "none";
		} else {
			this.restorer.restoreProp("restoreButton.getContainer().style.display");
		}
		if (!this.config.showCloseButton) {
			this.restorer.saveProp("closeButton.getContainer().style.display");
			this.closeButton.getContainer().style.display = "none";
		} else {
			this.restorer.restoreProp("closeButton.getContainer().style.display");
		}
	}
	//Hiding status if needed
	if (!this.config.showStatus) {
		this.restorer.saveProp("statusText.style.display");
		this.statusText.style.display = "none";
	} else {
		this.restorer.restoreProp("statusText.style.display");
	}
	//making element draggable if needed
	var self = this;
	if (this.config.canDrag) {
		var oldPos = null;
		this.draggable = new southprojects.Utils.Draggable(this.container, {
			handler : this.titleText, 
			//top : 0 - document.body.offsetTop, 
			//left : 0 - document.body.offsetLeft,
			stopEv : false,
			eventCapture : true,
			beforeDragInit : function(el) {
				if (el.dragObj.dragging) {
					self.activate();
				}
				self.setStatus("Deslizar la pantalla", "tmp");
				oldPos = southprojects.Utils.getAbsolutePos(el);
			},
			onDragMove : function(el) {
				var pos = southprojects.Utils.getAbsolutePos(el);
				self.state.left += pos.x - oldPos.x;
				self.state.top += pos.y - oldPos.y;
				oldPos.x = pos.x;
				oldPos.y = pos.y;
				self.updateWCH();
			},
			onDragEnd : function(el) {
				self.setStatus("", "restore");
			}
		});
		southprojects.Utils.addDestroyOnUnload(this, "draggable");
	}
	//making the modal cover
	if (this.config.modal && !this.modal) {
		var zIndex = 0;
		if (this.WCH) {
			zIndex = this.WCH.style.zIndex;
		} else {
			zIndex = this.container.style.zIndex;
		}
		this.modal = new southprojects.Modal({
			zIndex : zIndex,
			theme : null
		});
		this.modal.create();
	}
};


/**
 * This function assigns event handlers and implements "pushed" element finding.
 *
 * "Pushed" element finding is implemented the following way: all the event handlers see one
 * global variable target. When mouse is down on some element we try to get its buttonType property
 * or seek this property in elements parents. If the element with the buttonType is found it is put
 * into target variable. 
 */
southprojects.Window.prototype.addEvents = function () {
	var self = this, target = null;
	southprojects.Utils.addEvent(this.container, "mousedown", function (ev) {
		ev = ev || window.event; 
		target = southprojects.Utils.getTargetElement(ev);
		while(!target.buttonType && (target != self.container)) {
			target = target.parentNode;
		}
		if (!target.buttonType) target = null;
		southprojects.Window.mouseDown(ev, self, target);
		target = null;
	});
	//This event imitates the appearing of resizing cursor,
	//while you are moving the mouse over the window
	southprojects.Utils.addEvent(this.container, "mousemove", function (ev) {
		ev = ev || window.event; 
		if (self.container && self.container.style.display != "none" && self.config.canResize == true) {	
			//determining the position of the mouse
			var posX = ev.clientX + southprojects.Utils.getPageScrollX() || 0;
			var posY = ev.clientY + southprojects.Utils.getPageScrollY() || 0;
			//calculating the rectangle of our window
			var pos = southprojects.Utils.getElementPos(self.getContainer());
			var left = pos.x;
			var right = pos.x + self.container.offsetWidth;
			var top = pos.y;
			var bottom = pos.y + self.container.offsetHeight;
			//this is the thickness of the resizing border in pixels
			var rangeWidth = 8;
			var cornerWidth = 15;
			//a switch, which determines which cursor type should be shown
			if ((self.state.state == "simple") && !self.resizing) {
				switch (true) {
					case ((posX > left) && (posX < left + rangeWidth) && (posY > top) && (posY < top + rangeWidth)) : {
						self.container.style.cursor = "nw-resize"; 
						self.draggable.disabled = true;
						break;
					}
					
					case ((posX < right) && (posX > right - cornerWidth) && (posY < bottom) && (posY > bottom -cornerWidth)) : {
						self.container.style.cursor = "se-resize"; 
						self.draggable.disabled = true;
						break;
					}
				
					case ((posY > top) && (posY < top + rangeWidth) && (posX < right) && (posX > right - rangeWidth)) : {
						self.container.style.cursor = "ne-resize"; 
						self.draggable.disabled = true;
						break;
					}
					
					case ((posY < bottom) && (posY > bottom - cornerWidth) && (posX > left) && (posX < left + cornerWidth)) : {
						self.container.style.cursor = "sw-resize"; 
						self.draggable.disabled = true;
						break;
					}
				
					case ((posX > left) && (posX < left + rangeWidth)) : {
						self.container.style.cursor = "w-resize"; 
						self.draggable.disabled = true;
						break;
					}
					
					case ((posX < right) && (posX > right - rangeWidth)) : {
						self.container.style.cursor = "e-resize"; 
						self.draggable.disabled = true;
						break;
					}
				
					case ((posY > top) && (posY < top + rangeWidth)) : {
						self.container.style.cursor = "n-resize"; 
						self.draggable.disabled = true;
						break;
					}
					
					case ((posY < bottom) && (posY > bottom - rangeWidth)) : {
						self.container.style.cursor = "s-resize"; 
						self.draggable.disabled = true;
						break;
					}
				
					default : {
						self.container.style.cursor = "";
						self.draggable.disabled = false;
						break;
					}
				}
			}
		}
	});
	if (southprojects.is_gecko) {
		southprojects.Utils.addEvent(this.container, "click", function (ev) {
			ev = ev || window.event; 
			if (ev.detail > 1) {
				target = southprojects.Utils.getTargetElement(ev);
				while(!target.buttonType && (target != self.container)) {
					target = target.parentNode;
				}
				if (!target.buttonType) target = null;
				southprojects.Window.dblClick(ev, self, target);
			}
			target = null;
		});
	} else {
		southprojects.Utils.addEvent(this.container, "dblclick", function (ev) {
			ev = ev || window.event; 
			target = southprojects.Utils.getTargetElement(ev);
			while(!target.buttonType && (target != self.container)) {
				target = target.parentNode;
			}
			if (!target.buttonType) target = null;
			southprojects.Window.dblClick(ev, self, target);
			target = null;
		});
	}
}
