BBX.namespace('dialog');
BBX.dialog = function() {

	var o, formdata, hasjs, utils, aniDuration;

	aniDuration = BBX.configdata.getVal('animation_duration');

	formdata = {};
	hasjs = {};
	
	/*
	These utils will be attached to individual dialog boxes, then we can call setTitle, setContent, and others directly on the
	without having to pass the boxes around so much as variables.
	*/
	
	utils = {
	
		/* Sets the title on the dialog box. */
		setTitle:function(title) {
			var t = $(this).cssSelect('.dialog-title h5').first();
			t.replaceContent(title);
		},
		
		/* Sets the content of the dialog box  */
		setContent:function(content) {
			var t = $(this).cssSelect('.dialog-content').first();
			t.replaceContent(content);
		},
		
		/* sets ths size class on the dialog box  */
		setSize:function(size) {
			var sizes = ['small','medium','large'];
			for(var i=0;i<sizes.length;i++) {
				$(this).removeClass('dialog-' + sizes[i]);
			}
			
			$(this).addClass('dialog-'+size);
		},
		
		/* Does all of the loading for a dialog box  */
		setup:function(data) {
			BBX.log('setting up');
			BBX.log(data);
		
			if(data.dialogsize !== undefined) {
				this.setSize(data.dialogsize);
			}
			
			BBX.log('sizeset');
			
			if(data.initfunc !== undefined) {
				BBX.log('going to initfunc');
				data.initfunc(this,data);
			} else {
				BBX.log('no initfunc');
				if(data.title !== undefined) {
					this.setTitle(decodeURIComponent(data.title));
				}
				
				if(data.ftext !== undefined) {
					this.setContent(decodeURIComponent(data.ftext));
				}
			}
			BBX.log('done setup');
		},
		
		/* Actually shows the box.  */
		showDialog:function() {
			var t,b,coords,cb, cbfunc = false;
			t = $(this);
			t.setStyle('visibility','hidden');
			
			if(!this.parentNode || !this.parentNode.nodeName || this.parentNode.nodeName.toLowerCase() != 'body') {
				b = $('body').first();
				b.addContent(this);
			}
			
			cb = function() {};
			
			if(t.retrieve('focusfield') != undefined) {
				BBX.log('callback');
				var ffid = t.retrieve('focusfield');
				BBX.log('ffid: ' + ffid);
				if(ffid.length > 0) {
					cb = function() {
						if(document.getElementById(ffid)) {
							document.getElementById(ffid).focus();
						}
					}
				}
			}

			
			
			
			
			t.setStyle({'opacity':'0','visibility':'visible'});
			t.setPosition();
			t.show({'duration':aniDuration,'callback':function() {t.setStyle('filter','none');cb()}});

//			t.setPosition();
			
					
			
		},

		close:function(e) {
		    if(e) {
			e.preventDefault();
		    }

		    var d = $(this);
		    
		    if(d.hasClass('dialog-single')) {
			    delightbox();
		    }
		    d.hide({"duration":aniDuration,"remove":true});

		},
		
		/* centers this dialog on the page.  */
		center:function() {
			
			var t, coords, top;
			t = $(this);
			coords = BBX.measure.dist4center(t);
			top = coords[1];
			top = Math.round(top * 0.75);
			if(top < 30) {
				top = 30;
			}
			
			
			t.setStyle({'top':top+'px','left':coords[0]+'px'});
		
		},
		
		/* sets the appropriate position of the dialog.  Useful for when its dimensions have changed because of added content.  */
		setPosition:function() {
			BBX.log('setposition');
			var evt = this.retrieve('originalEvent');
		
			if(evt !== undefined) {
				BBX.log('got my event');
				BBX.log(evt);

				var pagesize, windowsize, dialogsize, pos = [], t;
				// get the document's size
				pagesize = BBX.measure.pagesize();
				windowsize = BBX.measure.viewport();


				dialogsize = [this.offsetWidth, this.offsetHeight];
				
				// set the position of the dialod so that its center is at the location of the click
				pos[0] = Math.round(evt.pageX - (dialogsize[0]/2));
				pos[1] = Math.round(evt.pageY - (dialogsize[1]/2));
				
				
				// make sure that the dialog isn't off the bottom or right of the page.
				if((pos[0] + dialogsize[0] + 50) > windowsize[0]) {
					pos[0] = windowsize[0] - dialogsize[0] - 50;
				}
				
				if((pos[1] + dialogsize[1] ) > pagesize[1]) {
					pos[1] = pagesize[1] - dialogsize[1] - 20;
				}
				
				
				// then make sure the dialog isn't off of the top or left of the page.
				if(pos[0] < 0) {
					pos[0] = 10;
				}
				
				if(pos[1] < 0) {
					pos[1] = 10;
				}



				BBX.log('setting pos left: ' + pos[0] + ' top: ' + pos[1] + ' with dialog size: ' + dialogsize[0] + ' by ' + dialogsize[1] + ' and pagesize ' + pagesize[0] + ' by ' + pagesize[1]);


				$(this).setStyle({"left":pos[0]+'px',"top":pos[1]+'px'});
				
				
			
			} else {
				this.center();
			}
		},

		execCallback:function() {
		    var t = $(this), cd;
		    if(t.retrieve('customdata')) {
			cd = this.retrieve('customdata');
			if(cd.callback) {
			    cd.callback();
			}
		    }

		}
	
		
	
	}
	
	
	
	/**
	function lightbox gives us the lightboxed effect on the page.
	
	*/
	function lightbox() {
		if($("#lightboxbg").length == 0) {
			var b,s, lb;
			b = $('body').first();
			s = BBX.measure.pagesize();
			lb = b.create('div',{'id':'lightboxbg'},true).setStyle({'visibility':'visible','width':s[0]+'px','height':s[1]+'px','opacity':'0'});
			
			lb.animate({'opacity':{'value':0.2,'unit':''}},{'duration':aniDuration});
			
		}
	}
	
	/**
	function delightbox removes the lightboxed effect on the page
	
	*/
	function delightbox() {
		$('#lightboxbg').hide({'duration':aniDuration,'remove':true});
	}
	
	
	/**
	function createDialog
	
	Creates a dialog box, with "loading" as the title, and returns it as a DOM node.
	
	*/
	function createDialog() {
		
		var b,d, html;
		b = $('body').first();
		
		// create the innerHTML string to go in the box.
		html = '<div class="dialog-title">';
		html += '<h5>' + BBX.langdata.getData('loading') + '</h5>';
		html += '<a>' + BBX.langdata.getData('close') + '</a></div>';
		html += '<div class="dialog-content"></div>';
		
		// create the dialog box as a DOM node.
		d = b.create('section',{className:'dialog'}, false, html );
		
		d.cssSelect('.dialog-title a').addEvent('click',o.close);
		
		// binds the utilities in util (above) to this dialog as methods.
		for(util in utils) {
			if(utils.hasOwnProperty(util)) {
				d[util] = BBX.bind(utils[util],d);
			}
		}
		
		
		return d;
		
	}
	
	/**
	function isLightboxed() 
	
	Tells us if we're in a lightboxed state right now.
	
	*/
	function isLightboxed() {
		if($("#lightboxbg").length > 0) {
			return true;
		}
		return false;
	}

	/*
	 *

	




	/*
	
	/**
	function loadFormDataResponse(resp)
	param (string) resp
	
	Handles the XHR response to a formdata load.
	
	*/
	function formDataResponse(resp) {
		BBX.log('start fdr');
		var r, item;
//		BBX.log(resp);
		r = eval(resp);
//		BBX.log('have r');
		if(r) {
			for(var i=0;i<r.length;i++) {
				item = r[i];

				BBX.log(item);
				if(!item.nocache) {
				    o.setFormData(item.key,item.data);
				}

				if(BBX[item.jsobj] === undefined && item.js) {
					BBX.log('setting formjs');
					var js = decodeURIComponent(item.js);
					eval(js);
					hasjs[item.key] = true;
					BBX.log('set formjs');
				}
				
				if(item.data.initfunc !== undefined) {
					BBX.log('setting initfunc');
					BBX.log(item.data.initfunc);
					item.data.initfunc = eval(item.data.initfunc);
					BBX.log('initfunc set');
				}
				
				if(item.phrases !== undefined) {
					BBX.langdata.setData(item.phrases);
				}

				BBX.log('got response, going to setup');
				this.setup(item.data);

				if(!$(this).retrieve('do_not_position')) {
				    BBX.log('going to setposition');
				    this.setPosition();
				}
			}
		}
	}


	o = {
	
	
		//  Start with the functions that we'll be calling.
		show:function(e,key,dialog) {
			if(e !== null) {
				e.preventDefault();
			}
			
			var d, url;
			if(dialog && $(dialog).hasClass('dialog')) {
				d = dialog;
			} else {
				d = createDialog();
				d.store('customdata', dialog);
			}
			
			if(isLightboxed()) {
				d.addClass('dialog-single');
			} else {
				d.store('originalEvent',e);
/*				d.setAttribute('draggable','true');	*/
			}

			/*
			 * If we're getting the signup form make sure the Recaptcha JS
			 * is added to the top of the page before we request the form.
			 * This way it should be ready by the time the form comes in.
			 */
			if(key == 'signup') {
			  var h = document.getElementsByTagName('head')[0], script;
			  script = document.createElement('script');
			  script.type = 'text/javascript';
			  script.onload=function() { BBX.register('recaptcha'); };
			  script.src = 'http://www.google.com/recaptcha/api/js/recaptcha_ajax.js';
			  h.appendChild(script);

			}
			
			
			// if we don't have any data to show, (based on key), then show "loading..." and send off an XHR request to get the data
			if(formdata[key] === undefined) {
				d.setContent('<div class="loader">' + BBX.langdata.getData('loading') + '</div>');
				d.setTitle(BBX.langdata.getData('loading'));
				d.setSize('tiny');
				url = '/cscript/getformdata.js.php?o=json&f=' + key;
				if(hasjs[key]) {
				    BBX.log('nojs true for' + key);
				    url += '&nojs=' + key;
				}

				d.ajax({'method':'GET','url':url,'callback':formDataResponse});
				// attach the dialog box to the document
				d.showDialog();
				
			} else {
			// otherwise load the stuff into the dialog box frmo formdata[key]
				d.showDialog();
				d.setup(formdata[key]);	
				d.setPosition();		
			}
			
			
			
			
		
		
		},
		
		
		showlightboxed:function(e,key, dialog) {
			if($("#lightboxbg").length === 0) {
				lightbox();
			}
			
			lightboxed = true;
			
			if(dialog !== undefined) {
				o.show(e,key, dialog);
			} else {
				o.show(e,key);
			}
		
		},
		
		
		/* 
		function showmessagebox(e, title, text)
		param (event) e : An event.
		param (string) title : The title to show in the box.
		param (string) text : An HTML string or DOM element to put into the messagebox
		
		Used for showing a simple message box.
		
		*/
		showmessagebox:function(e,title,text) {
		
			var d = createDialog();
			d.setTitle(title);
			d.setContent(text);
			d.addClass('dialog-small');
			d.addClass('dialog-single');
			
			lightbox();
			d.center();
			d.showDialog();
			
			
		
		},
		
		test:function() {
		
			o.showmessagebox(null,'Test','<p>This is a test dialog box.</p>');
		
		},
	
	
	
	
	
		/*
		function BBX.dialog.setFormData(key, data)
		param (string) key : The name of the form that we are saving
		param (object) data : The data used to create the form.
		
		Puts some data into the formdata array for use later on.
		
		*/
		setFormData:function(key, data) {
			BBX.log('setting form data for ' + key);
			formdata[key] = data;
			BBX.log('data set');
		},
		
		
		
				
		/**
		function close(e)
		param (event) e : The event, if any, that was used to call this function.
		
		Closes the dialog that this is called from within.
		*/
		
		close:function(e) {
		
			var t,d;
			t = $(this);
			d = $(BBX.traverse.getAncestorByClass(t,'dialog'));
			d.close();
			
		},
		
		
		/**
		function remove(key)
		param (string) key : The form that we want to delete the data from.
		
		Deletes the data from the formdata object for this form.  Doesn't affect any JS objects that have been loaded.
		
		*/
		remove:function(key) {
			delete formdata[key];
		}
	
	
	
	
	}

	return o;






}();
