/**
 * Janela inline;
 * @constructor
 */
compono.window = new compono.Object("window");

/** Propriedade que identifica a janela corrente; */
compono.window.currentActive={};
/** Evento de abertura, se o retorno for false a janela nao abre; */
compono.window.onShow=null;
/** Evento de fechamento, se o retorno for false a janela nao fecha; */
compono.window.onHide=null;
/** Evento de minimizar, se o retorno for false a janela nao miniza; */
compono.window.onMinimize=null;
/** Evento de maximizar, se o retorno for false a janela nao maximiza; */
compono.window.onMaximize=null;
/** Evento inicial do drag, se o retorno for false a janela nao inicia o drag; */
compono.window.onStartDrag=null;
/** Evento de stop do drag, se o retorno for false o drag nao pa'ra; */
compono.window.onStopDrag=null;
/** Evento de modal, se o retorno for false o estado 'modal' nao e' a aplicado; */
compono.window.onSetModal=null;

/**
 * Metodo de show da janela
 * @param {String, Node} id ID do elemento ou o pro'prio elemento
 * @param {Boolean} isModal Indica se o elemento sera' modal
 * @param {Event} e Evento gerado na hora do evento que executara' o me'todo
 * @return {Boolean} 
 */
compono.window.show = function(id, isModal, e) {
	var base = this.getByID(id);

	/** Evento */
	if (this.onShow &&
		typeof (this.onShow) == "function" &&
		this.onShow(base, isModal, e) == false) {
		return false;
	};

	this.appendClassName("window-openup", base);

	var button = this.getByClassName("input", "action default", base)
	if (button) {
		if (button.getAttribute("type") == "submit") {
			button.focus();
		}
	}

	function pageWidth() {
		return window.innerWidth != null ? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;
	}
	function pageHeight() {
		return window.innerHeight != null ? window.innerHeight : document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body != null ? document.body.clientHeight : null;
	}

	var width = base.offsetWidth;
	var height = base.offsetHeight;
	var left = (pageWidth() - width) / 2;

	var browserName = navigator.appName;
	if (browserName == "Netscape") {
		var top = ((pageHeight() - height) / 2);
	} else {
		var top = ((pageHeight() - height) / 2) + document.body.scrollTop;
	}

	base.style.left = left;
	base.style.top = top;

	this.setStorage(base);
	if (isModal) {
		base.modal = this.setModal(null, null, base);
	}
	this.Event.preventDefault(e);
	return true;

}

/**
 * Me'todo que fecha a window;
 * @param {String, Node} id ID do elemento ou o pro'prio elemento
 * @param {Event} e Objeto evento;
 */
compono.window.hide = function(id, e){
	var base = this.getByID(id);
	
	/** Evento */
	if(	this.onHide && 
		typeof(this.onHide) == "function" && 
		this.onHide(base) == false){
			return false;
	};
	
	this.removeClassName("window-openup", base);
	this.setStorage(base);
	this.removeStorage(base);
	base.modal = base.modal || this.getByID("ComponoWindowModal");
	if(base.modal){
		this.setModal(false, base.modal, base);
	}
	return true;
}
/** @ignore */
compono.window.elementHide = function(node, e){
	//a head content window;
	this.hide(node.parentNode.parentNode.parentNode);
	this.Event.stopPropagation(e);
}

/**
 * Metodo para minimizar a janela
 * @param {String, Node} id ID do elemento ou o pro'prio elemento
 * @param {Event} e
 */
compono.window.minimize = function(id){
	var base = this.getByID(id);
	
	/** Evento */
	if(	this.onMinimize && 
		typeof(this.onMinimize) == "function" && 
		this.onMinimize(base) == false){
			return false;
	};
	
	this.toggleClassName("window-minimized", base);
	this.setStorage(base);
	return true;
}
compono.window.elementMinimize = function(node, e){
	this.appendClassName("minimized", node, 0);
	this.minimize(node.parentNode.parentNode.parentNode,e);
	this.Event.stopPropagation(e);
}

/**
 * Metodo para maximizar a janela
 * @param {String, Node} id ID do elemento ou o pro'prio elemento
 * @param {Event} e
 */
compono.window.maximize = function(id, e){
	var base = this.getByID(id);
	
	/** Evento */
	if(	this.onMaximize && 
		typeof(this.onMaximize) == "function" && 
		this.onMaximize(base) == false){
			return false;
	};
	
	this.removeClassName("window-minimized", base);
	this.setStorage(base);
	this.Event.stopPropagation(e);
	return true;
}
compono.window.elementMaximize = function(node, e){
	this.appendClassName("maximized", node, 0);
	this.maximize(node.parentNode.parentNode.parentNode);
}

/**
 * Funcao que inicializa do drag'n drop na janela;
 * @param {Node} node "window-head" da janela
 * @param {Event} e Objeto evento;
 */
compono.window.startDrag = function(node, e){
	//head content window;
	var base = node.parentNode.parentNode;
	base.content = node.parentNode;
	
	/** Evento */
	if(	this.onStartDrag && 
		typeof(this.onStartDrag) == "function" && 
		this.onStartDrag(base) == false){
			return false;
	};

	base.startLeft = (e.clientX) - base.offsetLeft;
	base.startTop = (e.clientY) - base.offsetTop;
	
	this.appendClassName("window-grabbing", base);
	this.appendClassName("window-grabbing", document.body);
	this.appendClassName("window-active", base);

	this.currentActive = base;
	this.updateDragGhost(base);
	
	this.Event.add("mousemove", this.documentDragMovement, document);
	this.Event.add("mouseup", this.documentStopDrag, document);
	
	/*([IE]*/document.onselectstart = new Function("return false");/*)*/
	/* Em outros browsers e feito pelo css */
	return true;
}

/**
 * Funcao executada no mousemove do document;
 * Variaveis locais na funcao diminuiem a velocidade;
 * @param {Event} e Objeto evento;
 */
compono.window.documentDragMovement = function(e){
	if(compono.window.currentActive){
		compono.window.currentActive.ghost.style.left = ((e.clientX || e.pageX) - compono.window.currentActive.startLeft) + "px";
		compono.window.currentActive.ghost.style.top = ((e.clientY || e.pageY) - compono.window.currentActive.startTop) + "px";
	} 
}

/**
 * Funcao executada no mouseup do document e para o drag;
 * @param {Node} node
 * @param {Event} e
 */
compono.window.documentStopDrag = function(node, e){
	var w = compono.window;
	var c = w.currentActive;
	
	/** Evento */
	if(	w.onStopDrag && 
		typeof(w.onStopDrag) == "function" && 
		w.onStopDrag(c) == false){
			return false;
	};
	
	c.style.left = (c.ghost.offsetLeft)+ "px";
	c.style.top = (c.ghost.offsetTop)+ "px";
	
	w.setStorage(c);
	
	w.removeClassName("window-grabbing", c);
	w.removeClassName("window-grabbing", document.body);
	w.removeClassName("window-active", c);
	w.removeClassName("window-ghost-openup", c.ghost);
	w.Event.remove("mousemove", compono.window.documentDragMovement, document);
	w.Event.remove("mouseup", compono.window.documentStopDrag, document);
	return true;
}

/**
 * Cria/Atualiza uma div para ser arrastada enquanto a janela fica estatica, isso para que nao haja um overload no render;
 * @param {Node} base Base da window;
 * @return {Node} Item criado;
 */
compono.window.updateDragGhost = function(base){
	if(!base.ghost){
		var div = document.createElement("div");
		div.className = "window-ghost";
		base.ghost = document.body.appendChild(div);
	}
	this.appendClassName("window-ghost-openup", base.ghost);

	base.ghost.style.top = base.offsetTop + "px";
	base.ghost.style.left = base.offsetLeft + "px";
	base.ghost.style.width = base.content.offsetWidth + "px";
	base.ghost.style.height = base.content.offsetHeight + "px";
}

/**
 * Seta informacoes basicas da janela no storage
 * @param {Node} base Objeto window
 */
compono.window.setStorage = function(base){
	if(!base.storage){
		if(base.getAttribute("persist") == "true"){
			base.storage = compono.Storage.Cookie.ID(base.id);
		}else{
			base.storage = compono.Storage.Hidden.ID(base.id + "_storage");
		}
	}
	base.storage.set("x", base.offsetLeft);
	base.storage.set("y", base.offsetTop);
	base.storage.set("m",(this.hasClassName("window-minimized", base) ? 1 : 0));
	base.storage.set("o",(this.hasClassName("window-openup", base) ? 1 : 0));
}

/**
 * Remove informacoes do storage da janela
 * @param {Node} base Objeto window;
 */
compono.window.removeStorage = function(base){
	if(!base.storage){
		if(base.getAttribute("persist") == "true"){
			base.storage = compono.Storage.Cookie.ID(base.id);
		}else{
			base.storage = compono.Storage.Hidden.ID(base.id + "_storage");
		}
	}
	base.storage.remove("x");
	base.storage.remove("y");
	base.storage.remove("m");
}

/**
 * Me'todo de modal de janela
 * @param {Boolean} open Indica se o modal sera' ou nao aplicado
 * @param {String} id Id do objeto que sera' a base para o modal 
 * @param {Node} base Elemento janela
 */
compono.window.setModal = function(open, id, base){
	
	if(typeof(base)=="string")base=this.getByID(base);
	var o = this.getByID("ComponoWindowModal") || this.getByID(id);
	var b = document.forms[0] || document.body;
	
	if(!o){
		o = document.createElement("div");
		b.insertBefore(o, b.firstChild);
		o.id = "ComponoWindowModal";
		o.className = "window-modal";
	}
	
	/** Evento */
	if(	this.onSetModal && 
		typeof(this.onSetModal) == "function" && 
		this.onSetModal(o) == false){
			return false;
	};
	
	if(open != false){
		this.appendClassName("window-modal-openup",o)
		this.appendClassName("window-modal", document.body);
		this.appendClassName("window-modal", document.body.parentNode);

		document.body.WindowModalElement = o;
		this.setModalSize();
		
		this.Event.add("keydown",this.documentModalKeyPress,document);
		if(base){
			this.Event.add("keydown",this.windowModalKeyPress,base);
		}
		return o;
	}else{
		this.removeClassName("window-modal-openup",o)
		this.removeClassName("window-modal", document.body);
		this.removeClassName("window-modal", document.body.parentNode);
		
		this.Event.remove("keydown",this.documentModalKeyPress,document);
		
		if(base){
			this.Event.remove("keydown",this.windowModalKeyPress,base);
		}
		
		return false;
	}
}

/** 
 * Metodo usado pela janela para parar a bolha de evento.
 * @param {Object} e
 * @ignore
 */
compono.window.windowModalKeyPress = function(e){
	if(!e)e=window.event;
	compono.Event.stopPropagation(e);
}

/**
 * Metodo usado para parar o evento no window(DOM)
 * @param {Object} e
 * @ignore
 */
compono.window.documentModalKeyPress = function(e){
	if(!e)e=window.event;
	compono.Event.stopPropagation(e);
	compono.Event.preventDefault(e);
}



/**
 * seta o tamanho do element modal para o tamanho do body;
 * @ignore
 */
compono.window.setModalSize = function(){
	var a = document.documentElement;
	if(document.body.WindowModalElement){
		document.body.WindowModalElement.style.width = (a.scrollWidth)+"px";
		document.body.WindowModalElement.style.height = (a.scrollHeight)+"px";		
	}
}



/*
 RESIZE MODE
 <div class="window-resize" onmousedown="compono.window.startResize(this,event);">Resize</div>
*/
/**
 * Me'todo que inicializa o resize do elemento janela 
 * @param {Node} anchor Elemento inicilizador
 * @param {Event} e Evento q inializa o metodo 
 */
compono.window.startResize = function(anchor, e){
	var base = anchor.parentNode.parentNode;
	base.content = anchor.parentNode;
	base.resize = anchor;

	anchor.startLeft = (e.clientX) - anchor.offsetLeft;
	anchor.startTop = (e.clientY) - anchor.offsetTop;

	this.currentActive = base;
	
	compono.window.updateDragGhost(base);
	
	this.Event.add("mousemove", this.documentResizeMovement, document);
	this.Event.add("mouseup", this.documentStopResize, document);
}

/** @ignore */
compono.window.documentResizeMovement = function(e){
	if(compono.window.currentActive){
		var c = compono.window.currentActive;
		
		c.resize.style.left = ((e.clientX) - c.offsetLeft ) + "px";
		c.resize.style.top = ((e.clientY) - c.offsetTop ) + "px";
		
		c.ghost.style.width = (c.resize.offsetLeft + c.resize.offsetWidth) + "px";
		c.ghost.style.height = (c.resize.offsetTop + c.resize.offsetHeight) + "px";
		
	} 
}

/** @ignore */
compono.window.documentStopResize = function(e){
	var w = compono.window;
	var c = compono.window.currentActive;
	
	c.content.style.width = (c.ghost.offsetWidth)+ "px";
	c.content.style.height = (c.ghost.offsetHeight)+ "px";
	
	w.removeClassName("window-ghost-openup", c.ghost);
	
	w.Event.remove("mousemove", compono.window.documentResizeMovement, document);
	w.Event.remove("mouseup", compono.window.documentStopResize, document);
}