
var IpDialogWidgetTools = {

	viewPortSize: function()
	{
		if (typeof(window.innerWidth) == 'number')
		{
			// Non-IE
			return {
				width: window.innerWidth,
				height: window.innerHeight
			};

		}
		else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
		{
			//IE 6+ in 'standards compliant mode'
			return {
				width:  document.documentElement.clientWidth
				,height: document.documentElement.clientHeight
			};
		}
		else if( document.body && ( document.body.clientWidth || document.body.clientHeight))
		{
			//IE 4 compatible
			return {
				width: document.body.clientWidth,
				height: document.body.clientHeight
			};
		}
	}

	,scrollOffset: function()
	{
		if (! document.all)
		{
			return {
				left: window.pageXOffset
				,top: window.pageYOffset
			}
		}
		else if (document.documentElement)
		{
			return {
				left: document.documentElement.scrollLeft,
				top: document.documentElement.scrollTop
			};
		}
		else
		{
			return {
				left: document.body.scrollLeft,
				top: document.body.scrollTop
			};
		}
	}

	,documentSize: function()
	{
		var xScroll, yScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		
		var windowWidth, windowHeight;
		
		if (self.innerHeight) 
		{	// all except Explorer
			
			if(document.documentElement.clientWidth){
				windowWidth = document.documentElement.clientWidth; 
			} else {
				windowWidth = self.innerWidth;
			}
			
			windowHeight = self.innerHeight;
		}
		else if (document.documentElement && document.documentElement.clientHeight) 
		{ 
			// Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} 
		else if (document.body) 
		{ 
			// other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
		
		// for small pages with total height less then height of the viewport
		if (yScroll < windowHeight){
			pageHeight = windowHeight;
		} else { 
			pageHeight = yScroll;
		}
		
		// for small pages with total width less then width of the viewport
		if (xScroll < windowWidth) {	
			pageWidth = xScroll;		
		} else {
			pageWidth = windowWidth;
		}
		
		return { width: pageWidth, height: pageHeight };
	}
};

var IpDialogWidget = Class.create({

	defaults: {
		animate: true
		,modal: false
		,onClose: null
		,beforeClose: null
		,afterShow: Prototype.emptyFunction
	}
	
	,initialize: function(options)
	{
		this.title = options.title;
		this.contents = options.pane;
		this.width = options.width;

		this.initializeOptions(options);		
		this.initializeOverlay();
		
		this.createDialog();
	}
	
	,initializeOptions: function(options)
	{
		if (! options)
			options = {};
			
		$H(this.defaults).each(function(pair) {
			if (! this[pair.key])
				this[pair.key] = pair.value;
		}, options);
		
		this.options = options;
	}
	
	,initializeOverlay: function()
	{
		var options = {
			afterShow: this._showDialog.bind(this)
			,animate: this.options.animate
		};
		
		if (! this.options.modal)
		{
			options.onClick = this.closeHandler.bindAsEventListener(this);
		}
		
		this.overlay = new IpOverlayWidget(options);
	}
	
	,createDialog: function()
	{
		var dialog = new Element('div', { style: 'width: ' + this.width + 'px;' })
			.addClassName('ip-dialog-widget');

		var title = new Element('div', { 'className': 'title' })
			.update(this.title)
			.addClassName('title');

		var close = new Element('img', {
			src: '/media/gfx/widgets/close.gif'})
			.addClassName('close');

		close.onclick = this.closeHandler.bindAsEventListener(this);

		var header = new Element('div', { 'className': 'header' } );
		header.appendChild(close);
		header.appendChild(title);

		var contents = new Element('div', { 'className': 'contents' });
		contents.appendChild(this.contents);

		dialog.appendChild(header);
		dialog.appendChild(contents);

		this.dialog = dialog;

		$$('body').first().appendChild(this.dialog);

		Event.observe(document, 'keyup', this.keyPressed.bindAsEventListener(this));
	}

	,closeHandler: function(event)
	{
		Event.stop(event);

		if (Object.isFunction(this.options.onClose))
		{
			if (this.options.onClose(this))
				this.close();
		}
		else
		{
			this.close();
		}
	}

	,keyPressed: function(e)
	{
		if (! this.isShowing)
			return;

		var code = (window.event) ? event.keyCode : e.keyCode;

		if (code == 27)
			this.closeHandler(e);
	}

	,show: function(callback)
	{
		this.callback = callback;
		this.overlay.show();
		
	}

	,_showDialog: function()
	{
		this.positionDialog();
		this.dialog.style.visibility = 'visible';

		this.isShowing = true;

		this.options.afterShow();
		
		if (this.callback)
			this.callback();
	}
	
	,positionDialog: function()
	{
		var offset = IpDialogWidgetTools.scrollOffset();

		// position the dialog
		var left = Math.max(
			10,
			IpDialogWidgetTools.viewPortSize().width / 2 - (this.dialog.offsetWidth / 2)
		) + offset.left;

		var top = Math.max(
			10
			,(IpDialogWidgetTools.viewPortSize().height / 2) - (this.dialog.offsetHeight / 2)
			) + offset.top;

		this.dialog.style.left = left + 'px';
		this.dialog.style.top = top + 'px';
	}

	,close: function()
	{
		if (this.options.beforeClose)
			this.options.beforeClose(this);

		this.dialog.style.visibility = 'hidden';
		this.isShowing = false;

		this.overlay.hide();
		this.dialog.remove();
	}

	,getInnerWidth: function()
	{
		return this.width - 12;
	}
});

var IpOverlayWidget = Class.create({

	defaults: {
		animate: true
		,zIndex: 100
		,color: '#000000'
		,opacity: 0.4
		,duration: 0.5
		,afterShow: Prototype.emptyFunction
		,afterHide: Prototype.emptyFunction
		,onClick: Prototype.emptyFunction
	}
	
	,initialize: function(options)
	{
		this.initializeOptions(options);
		
		this.element = new Element('div', { style: 'none', 'class': 'ip-overlay-widget' });
		this.element.setStyle({
			backgroundColor: this.options.color
			,position: 'absolute'
		});
		
		this.element.observe('click', this.options.onClick);
		
		this.adjustToWindowListener = this.adjustToWindowSize.bind(this);
	}
	
	,initializeOptions: function(options)
	{
		if (! options)
			options = {};
			
		$H(this.defaults).each(function(pair) {
			if (! this[pair.key])
				this[pair.key] = pair.value;
		}, options);
		
		this.options = options;
	}

	,show: function(callback)
	{
		$$('body').first().appendChild(this.element);
		
		this.adjustToWindowSize();
		
		this.element.style.display = 'none';

		var duration = (this.options.animate) ? this.options.duration : 0;
		
		Event.observe(window, 'resize', this.adjustToWindowListener);

		Effect.Appear(this.element, {
			to: this.options.opacity
			,duration: duration
			,afterFinish: this.options.afterShow
		});
	}

	,hide: function()
	{
		
		Event.stopObserving(window, 'resize', this.adjustToWindowListener);
		
		var self = this;
		this.clicked = null;

		if (this.options.animate)
		{
			Effect.Fade(this.element, {
				duration: this.options.duration
				,afterFinish: function() {
					self.element.remove();
					self.options.afterHide();
				}}
				);
		}
		else
		{
			self.element.remove();
		}
	}

	,clicked: function()
	{
		// callback
	}
	
	,adjustToWindowSize: function()
	{
		this.element.style.height = document.viewport.getHeight() + 'px';
		var dim = this.getDocumentSize();
		this.element.style.top = '0px';
		this.element.style.left = '0px';
		this.element.style.width = dim.width + 'px';
		this.element.style.height = dim.height + 'px';
	}
	
	,getDocumentSize: function()
	{
		var xScroll, yScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}

		var windowWidth, windowHeight;
		
		if (self.innerHeight) {	// all except Explorer
			if (document.documentElement.clientWidth)
			{
				windowWidth = document.documentElement.clientWidth; 
			} else {
				windowWidth = self.innerWidth;
			}
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	

		// for small pages with total height less then height of the viewport
		var offset = document.viewport.getScrollOffsets();

		return {
			height: (yScroll < windowHeight) ? windowHeight : yScroll
			,width: (xScroll < windowWidth) ? xScroll : windowWidth
		}
	}
});
