/**
 * Window class.
 * 
 * ----
 * 
 * LICENCE
 * 
 * This work is licensed under Creative Commons Attribution-Share Alike 3.0 (Germany).
 * For details on this licence visit http://creativecommons.org/licenses/by-sa/3.0/de/
 * 
 * All rights reserved
 * 
 * @author Jakob Hohlfeld | http://www.netronaut.de
 * @copyright 2010 by Jakob Hohlfeld
 * 
 */
var NetronautUI_Window = new Class
({
	Extends: NetronautUI_Widget,
	
	options: {
		visible: false,
		overlayOpacity: 0.8,
		autoClose: false,
		addOverlay: false,
		positionOnTarget: false,
		position: 'fixed',
		alwaysInView: false
	},
	
	visible: false,
	
	fxFrame: null, fxOverlay: null, 
	
	/**
	 * The constructor.
	 * 	
	 * @param Element el
	 * @param object options
	 */
	initialize: function ( el, options ) {
		
		// initialize
		this.parent(el, options);
		
		this.dom.hitarea = [this.dom.container];
		
		// ie7 size fix
		if(this.ie7 || this.ie6) {
			this.setInnerSize({x:this.dom.el.measure(function(){return this.getSize().x})});
		}
		
		// autoclose
		if(this.options.autoClose == true) {
			
			// close on ESC
			var closeOnEsc = function(event){ if(event.key == 'esc') this.close(); }.bind(this);
			
			// add events
			var autoclose = this.closeOnClick.bind(this);
			this.addEvent('open', function () {
				document.addEvent('mousedown', autoclose);
				document.addEvent('keyup', closeOnEsc);
			});
			this.addEvent('close', function () {
				document.removeEvent('mousedown', autoclose);
				document.removeEvent('keyup', closeOnEsc);
			});
		}
		
		// overlay
		if(this.options.addOverlay == true && this.ie6) {
			var windowChange = this.ieOverlayFix.bind(this);
			this.addEvent('beforeOpen', function(){
				windowChange();
				window.addEvent('scroll', windowChange).addEvent('resize', windowChange);
			});
			this.addEvent('close', function(){
				window.removeEvent('scroll', windowChange).removeEvent('resize', windowChange);
			});
		}
		
		// initially visible?
		if(this.options.visible == true) {
			this.open();
		}
	},
	
	/**
	 * Render the component.
	 * 
	 */
	render: function () {
		if(this.options.addOverlay == true) {
			var o = this.dom.overlay = new Element('div').setStyles({
				opacity:this.options.overlayOpacity, backgroundColor: '#000000', position:'fixed', width:'100%', height:'100%', 'z-index': 9998
			}).setStyle('display', 'none').inject(document.getElement('body')).setPosition({x:0, y:0});
			if(this.ie6) o.setStyle('position', 'absolute');
		}
		var c = this.dom.container = new Element('div', {'class': 'netronaut-ui-window'}).setStyle('display', 'none').inject(document.getElement('body')).adopt(
			new Element('div', {'class': 'skin-topleft'}).adopt(new Element('div', {'class': 'skin-topright'}).adopt(new Element('div', {'class': 'skin-top'}))),
			new Element('div', {'class': 'skin-left'}).adopt(new Element('div', {'class': 'skin-right'}).adopt(new Element('div', {'class': 'skin-center'}).adopt(this.dom.el))),
			new Element('div', {'class': 'skin-bottomleft'}).adopt(new Element('div', {'class': 'skin-bottomright'}).adopt(new Element('div', {'class': 'skin-bottom'})))
		).setStyle('z-index', 9999);
		c.setStyle('position', this.options.position);
		if(this.ie6) c.setStyle('position', 'absolute');
		this.dom.el.setStyles({'display':'', 'visibility': 'visible'});
	},
	
	/**
	 * Open widget.
	 * 
	 * @param Event event Optional
	 */
	open: function ( event ) {
		if(this.visible) return;
		this.fireEvent('beforeOpen', event);
		if(event && this.options.positionOnTarget) {
			this.position({
				'relativeTo':event.target, 
				'position':(this.options.positionOnTarget.position ?this.options.positionOnTarget.position :'center'),
				'edge':(this.options.positionOnTarget.edge ?this.options.positionOnTarget.edge :'center')
			});
			if(this.options.alwaysInView) {
				var size = this.getSize();
				var winSize = window.getSize();
				var winScroll = window.getScroll();
				this.positionAdjustMinMax(
					{x:winScroll.x, y:winScroll.y},
					{x:winScroll.x+winSize.x-size.x, y:winScroll.y+winSize.y-size.y}
				);
			}
		}
		this.dom.container.style.display = '';
		this.fxFrame = new Fx.Tween(this.dom.container, { property:'opacity', duration:200 }).set(0).start(1);
		if(this.options.addOverlay == true) {
			this.dom.overlay.style.display = '';
			this.fxOverlay = new Fx.Tween(this.dom.overlay, { property:'opacity', duration:200 }).set(0).start(this.options.overlayOpacity);
		}
		this.visible = true;
		this.fireEvent('open', event);
		return this;
	},
	
	/**
	 * Close the widget.
	 * 
	 */
	close: function () {
		this.fireEvent('beforeClose');
		if(this.dom.container.getStyle('display') == 'none') return;
		this.fxFrame.cancel();
		this.dom.container.style.display = 'none';
		if(this.options.addOverlay == true) {
			this.fxOverlay.cancel();
			this.dom.overlay.style.display = 'none';
		}
		this.visible = false;
		this.fireEvent('close')
		return this;
	},
	
	positionAdjustMinMax: function ( minimum, maximum ) {
		var pos = this.getPosition();
		if(pos.x < minimum.x) pos.x = minimum.x;
		if(pos.x > maximum.x) pos.x = maximum.x;
		if(pos.y < minimum.y) pos.y = minimum.y;
		if(pos.y > maximum.y) pos.y = maximum.y;
		this.setPosition(pos);
	},
	
	/**
	 * Override for some ie fixes.
	 * 
	 * @param object size Properties x/y
	 */
	setSize: function ( size ) {
		var center = this.dom.container.getElement('.skin-center');
		this.setInnerSize({
			x: !$type(size.x) ?null :size.x-parseInt(center.getStyle('margin-left'))-parseInt(center.getStyle('margin-right')),
			y: !$type(size.y) ?null :size.y-this.dom.container.getElement('.skin-top').getSize().y-this.dom.container.getElement('.skin-bottom').getSize().y
		});
		return this;
	},
	
	/**
	 * Set the inner size of critical frame elements.
	 * 
	 * @param object size x/y for width/height
	 */
	setInnerSize: function ( size ) {
		var center = this.dom.container.getElement('.skin-center');
		if($type(size.x)) center.setStyle('width', size.x);
		if($type(size.y)) center.setStyle('height', size.y);
		if(this.ie6 || this.ie7) this.ieSizeFix();
		this.fireEvent('resize', size);
		return this;
	},
	
	increaseZIndex: function ( increase ) {
		var increase = increase | 1;
		this.dom.container.setStyle('z-index', parseInt(this.dom.container.getStyle('z-index')) + increase);
	},
	
	ieSizeFix: function () {
		var center = this.dom.container.getElement('.skin-center');
		var size = center.measure(function(){return this.getSize()});
		this.dom.container.setStyle('width', size.x+parseInt(center.getStyle('margin-left'))+parseInt(center.getStyle('margin-right')));
		this.dom.container.getElement('.skin-top').setStyle('width', size.x);
		this.dom.container.getElement('.skin-bottom').setStyle('width', size.x);
	},
	
	ieOverlayFix: function () {
		this.dom.overlay.setStyle('height', window.getSize().y);
		this.dom.overlay.position();
	}
});

