var Popup=Class.create({
	_no_report:new Element('div').update('No results were supplied.'),
	_throbber:'http://cdn.lafango.net/images/structural/v4/throbber.gif',
	_results:new Hash({}),
	_div:'div',
	_footer:'div',
	_grouping:'div',
	_header:'div',
	_item:'p',
	_cover:false,
	_holder:false,
	_scrolling:false,
	_scrolling:'popup_scrolling',
	_holder:'popup_holder',
	_cover:'popup_cover',
	initialize:function(method,callback){
		if(!$('popup_holder'))
		$$('body')[0]
		.insert(new Element(this._div,{id:'popup_cover'}))
		.insert(
			new Element(this._div,{id:'popup_scrolling'})
			.insert(new Element(this._div,{id:'popup_holder'}))
		);
		this.method=method;
		this.callback=callback?callback:false;
		this.result={
			id:false,
			title:false,
			content:false,
			form:false,
			legacy:false,
			header:false,
			footer:false,
			attributes:{'class':'popup_container'} ,
			method:method,
			width:300
		};
		this._results.set(method,this.result);
		if(this._results.size()==1)this._loading();
	},
	_close:{
		on:function(e){ this._kill(1); },
		off:function(e){ this._kill(); },
		toggle:function(e){ this._kill(this.method.match(/confirm_|form_/i||this.result.closer)); }
	},
	_kill:function(disable_callback){
		this._results.unset(this.method);
		if(!disable_callback&&this.callback){
			if(Object.isString(this.callback))eval(this.callback);
			else this.callback();
		}
		if(this._results.size()>1)this._results.each(function(pair){
			if(x++==0)this._render(pair.key);
			$break;
		}.bind(this));
		else{
			$(this._scrolling).hide();
			$(this._cover).hide();
			$(this._holder).update().hide();
			Event.stopObserving(document.onresize?document:window,'resize');
		}
	},
	_loading:function(){
		try {
			Container.hide_popup();
			$('popups').update().hide();
		} catch(e) {};
		var offset = document.viewport.getScrollOffsets()[1]+'px';
//		$$('html')[0].setStyle({overflow:'hidden'});
		$(this._scrolling).show();
		$(this._holder).update(
			new Element(this._div,{'class':'popup_container',id:'popup_loading'}).setStyle({width:'300px'})
			.insert(
				new Element(this._header,{'class':'popup_header',id:'popup_'+this.method+'_header'})
				.insert(new Element('h2').update('Loading'))
				.insert(new Element('a',{'class':'close',href:'javascript:void(0);',title:'Close'}).update('&nbsp;').observe('click',this._close.toggle.bind(this)))
			)
			.insert(
				new Element(this._div,{'class':'popup_content',id:'popup_loading_content'}).update(
					new Element('p').update(
						new Element('img',{alt:'Loading...',src:this._throbber,title:'Loading...'})
					)
				)
			)
			.insert(new Element(this._footer,{'class':'popup_footer',id:'popup_'+this.method+'_footer'}).insert(new Element('button',{'class':'cancel'}).update('Cancel').observe('click',this._close.off.bind(this))))
		).show();
		$(this._cover).show();
		this._position();
	},
	_parse:function(content,attributes){
		if(!content)return '';
		else if(Object.isString(content)||Object.isElement(content))return content;
		else if(Object.isArray(content)){
			var container=new Element(this.result.grouping?this.result.grouping:this._grouping,attributes);
			for(var i=0,count=content.length;i<count;++i)container.insert(this._parse(content[i]));
		}
		else{
			if(!content.content)var inner='';
			else if(Object.isString(content.content))var inner=content.content;
			else if(Object.isArray(content.content)){
				var inner=new Element(this.result.grouping?this.result.grouping:this._grouping);
				for(var i=0,count=content.content.length;i<count;++i)inner.insert(this._parse(content.content[i]));
			}
			else {
				var inner=new Element(this.result.grouping?this.result.grouping:this._grouping);
				for(var i in content.content)if(i!=='tag'&&i!=='attributes')inner.insert(this._parse(content[i]));
			}
			if(content.tag)var container=new Element(content.tag,content.attributes).update(inner);
		}
		return container?container:'';
	},
	_position:function(){
		var area=document.viewport.getHeight();
		var element=$(this._holder).childElements()[0].getHeight();
		if(element>area)$(this._holder).setStyle({top:(25+document.viewport.getScrollOffsets().top)+'px'});
		else $(this._holder).setStyle({top:(((area-element)/2)+document.viewport.getScrollOffsets().top)+'px'});
		Event.observe(document.onresize?document:window,'resize',this._resize.bind(this));
	},
	_resize:function(e){
		if($(this._holder).innerHTML=='')return;
		var area=document.viewport.getHeight();
		var element=$(this._holder).childElements()[0].getHeight();
		if(element>area)$(this._holder).setStyle({top:(25+document.viewport.getScrollOffsets().top)+'px'});
		else $(this._holder).setStyle({top:(((area-element)/2)+document.viewport.getScrollOffsets().top)+'px'});
	},
	_render:function(method){
		if(method)this.method=method;
		else{
			this._results.set(this.method,this.result);
			if(this._results.size()>1)return;
		}
		var result=this._results.get(this.method);
		if(!result.container)result.container=this._div;
		if(Object.isString(result.content))result.content={tag:'p',content:result.content,attributes:{'class':'popup_content'}};
		else if(result.content){
			if(!result.content.attributes)result.content.attributes={'class':'popup_content',id:'popup_'+this.method+'_content'};
			if(!result.content.attributes['class'])result.content.attributes['class']='popup_content';
			else if(!result.content.attributes['class'].match('popup_content'))result.content.attributes['class']='popup_content '+result.content.attributes['class'];
			if(!result.content.attributes['id'])result.content.attributes['id']='popup_'+this.method+'_content';
		}
		else result.content={tag:'p',content:this._no_report,attributes:{'class':'popup_content',id:'popup_'+this.method+'_content'}};
		if(!result.attributes['class'])result.attributes['class']='popup_container';
		else if(!result.attributes['class'].match('popup_container'))result.attributes['class']='popup_container '+result.attributes['class'];
		$(this._holder).update(
			result.legacy
			?result.legacy
			:new Element(result.container,result.attributes).setStyle({width:result.width+'px'})
			.insert(
				new Element(this._header,{'class':'popup_header',id:'popup_'+this.method+'_header'})
				.insert(result.title?Object.isString(result.title)?new Element('h2').update(result.title):this._parse(result.title):'')
				.insert(result.header?this._parse(result.header):'')
				.insert(new Element('a',{'class':'close',href:'javascript:void(0);',title:'Close'}).update('&nbsp;').observe('click',this._close.toggle.bind(this)))
			)
			.insert(this._parse(result.content,result.content.attributes))
			.insert(this._parse(result.footer))
		);
		this._position();
	}
});
Popup.Alert=Class.create(Popup,{
	initialize:function($super,message,values){
		if(!message)return;
		if(!values)values={};
		if(!values.title)values.title='Alert';
		if(!values.ok)values.ok='Ok';
		if(!values.id)values.id=values.title.replace(/[^a-zA-Z0-9 -_]/,'').replace(' ','_').toLowerCase();
		if(!values.callback)values.callback=false;
		$super('alert_'+values.id,values.callback);
		for(var i in values)if(values[i])this.result[i]=values[i];
		this.result.content=message;
		this.result.footer=new Element(this._footer,{'class':'popup_footer',id:'popup_'+this.method+'_header'}).insert(new Element('input',{'class':'submit',type:'submit',value:values.ok}).observe('click',this._close.off.bind(this)));
		this._render();
	}
});
Popup.Container=Class.create(Popup,{
	initialize:function($super,method,values,callback){
		$super(method,callback);
		this.result.width=600;
		this.result.content=[];
		if(method==='ajax'){
			if(values)var parameters=values.merge({control:'popup_container',method:this.result.method});
			else var parameters=$H({control:'popup_container',method:this.result.method});
			new Ajax.Request('/ajax.php',{
				method:'get',parameters:parameters,onSuccess:function(transport){
					var values=transport.responseJSON;
					for(var i in values)if(values[i])this.result[i]=values[i];
				}.bind(this)
			});
		}
		else{ for(var i in values)if(values[i])this.result[i]=values[i]; }
	},
	append:function(content) { this.result.content.push(content); },
	attributes:function(attributes) { this.result.attributes=attributes; },
	closer:function() { this.result.closer=1; },
	container:function(container) { this.result.container=container; },
	footer:function(footer) { this.result.footer=new Element(this._footer,{'class':'popup_footer',id:'popup_'+this.method+'_footer'}).insert(this._parse(footer)); },
	header:function(header) { this.result.header=new Element('p').insert(this._parse(header)); },
	prepend:function(content) { this.result.content.unshift(content); },
	render:function() { this._render(); },
	title:function(title) { this.result.title=title; },
	type:function(type) {
		switch(type) {
			case 'form':
				this.result.grouping='form';
			break;
			case 'list':
				this.result.grouping='ul';
			break;
			default:
				this.result.grouping=this._div;
		}
	},
	width:function(width) { this.result.width=parseInt(width); }
});
Popup.Confirm=Class.create(Popup,{
	initialize:function($super,callback,message,values){
		if(!callback)return;
		if(!values)values={};
		if(!values.title)values.title='Confirm';
		if(!values.id)values.id=values.title.replace(/[^a-zA-Z0-9 -_]/,'').replace(' ','_').toLowerCase();
		if(!message)message='Please confirm.';
		if(!values.ok)values.ok='Ok';
		if(!values.cancel)values.cancel='Cancel';
		$super('confirm_'+values.id,callback);
		for(var i in values)if(values[i])this.result[i]=values[i];
		this.result.title=values.title;
		this.result.content=message;
		this.result.footer=new Element(this._div,{'class':'popup_footer',id:'popup_'+this.method+'_header'})
			.insert(new Element('input',{'class':'submit',type:'submit',value:values.ok}).observe('click',this._close.off.bind(this)))
			.insert(new Element('input',{'class':'cancel',type:'button',value:values.cancel}).observe('click',this._close.on.bind(this)));
		this._render();
	}
});
Popup.Form=Class.create(Popup,{
	initialize:function($super,method,values){
		var callback=values.callback&&values.callback!=='submit'?values.callback:false;
		$super(method+'_form',callback);
		this.result.container='form';
		this.result.grouping='fieldset';
		this.result.width=values.width?values.width:600;
		var ok=new Element('input',{'class':'submit',type:'submit',value:values.ok?values.ok:'Ok'});
		if(values.callback!=='submit')ok.observe('click',this._close.off.bind(this));
		var cancel=values.cancel?values.cancel:'Cancel';
		if(method==='raw'){
			if(values.content.tag!=='fieldset')values.content={tag:'fieldset',content:values.content,attributes:{'class':'popup_content'}};
			for(var i in values)if(values[i])this.result[i]=values[i];
			this.result.footer=new Element(this._footer,{'class':'popup_footer',id:'popup_'+this.method+'_footer'})
				.insert(ok)
				.insert(new Element('input',{'class':'cancel',type:'button',value:cancel}).observe('click',this._close.on.bind(this)));
			this._render();
		}
		else{
			if(values)var parameters=values.merge({control:'popup_container',method:this.result.method,type:'form'});
			else var parameters=$H({control:'popup_container',method:this.result.method,type:'form'});
			new Ajax.Request('/ajax.php',{
				method:'get',parameters:parameters,onSuccess:function(transport){
					var values=transport.responseJSON;
					if(values.content.tag!=='fieldset')values.content={tag:'fieldset',content:values.content,attributes:{'class':'popup_content'}};
					for(var i in values)if(values[i])this.result[i]=values[i];
					this.result.footer=new Element(this._footer,{'class':'popup_footer',id:'popup_'+this.method+'_footer'})
						.insert(new Element('input',{'class':'submit',type:'submit',value:ok}))
						.insert(new Element('input',{'class':'cancel',type:'button',value:cancel}).observe('click',this._close.on.bind(this)));
					this._render();
				}.bind(this)
			});
		}
	}
});