/* Greybox Redux (Click Commerce)
 * Required: http://jquery.com/
 * Rewritten by: Matt Baker (Click Commerce)
 * Written by: John Resig
 * Based on code by: 4mir Salihefendic (http://amix.dk)
 * Original License: LGPL (read more in LGPL.txt)
 */

/*
* jQuery.greybox is an object that must be instantiated to use.
* Because we allow multiple greybox instances onscreen at once each greybox must have it's own instance.
* Ex. var myGreyBox = new jQuery.greybox({id:'myBox', height:200, width:200, caption:'Welcome to greybox'});
* The contents of your greybox are passed to greybox.show(). If you're going to use an iframe
* be sure to use generate_iframe();
*/
jQuery.greybox = function(options) {
	/*
	* Settings
	* 	id (string): Appended to your greybox elements' id tags. Should be unique to your instance.
	*	height (int): Height of the window.
	*	width (int): Width of the window.
	*	animation (bool): whether the window should be animated. Frankly, I've never seen it work.
	*	overlay_clickable (bool): Controls whether or not clicking the overlay will close the window.
	*	callback (function): The callback function is called when the greybox window is exited.
	*	caption (string): Title at the top of the greybox window.
	*/
	this.settings = jQuery.extend({
		id: null,
		height: 400,
		width: 400,
		animation: false,
		overlay_clickable: true,
		callback: null,
		caption: ""  
		}, options || {});
    
    /*
    * ID tags are unique to a greybox instance, and allow greybox instances
    * to distinguish themselves from other greybox dialogues that are on screen
    * at the same time
    */
    this.overlay_id = 		'GB_overlay_'+this.settings.id; 
    this.window_id = 		'GB_window_'+this.settings.id;  
    this.caption_id = 		'GB_caption_'+this.settings.id;  
    this.frame_id = 		'GB_frame_'+this.settings.id;  
    this.closebutton_id = 	'GB_closebutton_'+this.settings.id;
    
    /*
    * Method: generate_iframe(url, [overflow, align]);
    *
    * Description: Iframes in greybox have specific requirements, use this helper method to construct your
    * iframe html before passing it to greybox.show();
    *
    * Example; display google.com in an iframe and set the overflow to hidden
   	* 	var html = myGreyBox.generate_iframe('http://www.google.com', 'hidden');
   	*	myGreyBox.show(html);
    */
    this.generate_iframe = function(url, overflow, align) {
    	if(overflow) overflow = " style='overflow:"+overflow+";' "; else overflow = "";
    	if(align)	 align	  = " align='"+align+"'"; else align = "";
    	return "<iframe"+overflow+align+" name='"+this.frame_id+"' id='"+this.frame_id+"' class='GB_frame' src='"+url+"'></iframe>";
    }
    /*
    * IMPORTANT
    * A note on functions being passed to event handlers;
    *  When we pass a function to a jQuery event handler the function *itself* passes 
    *  but the object it's attached to does not.  Any function that might be called
    *  by an event handler has to be prepared to execute in a static context.
    *  The event bindings you'll see in show() pass their object with the event data.
    *  Any function that might be called statically can use this event data to reconstitute the object.
    *
    * 
    */
    
    /*
	* Method: overlay_size(jquery.Event)
	*
	* Description: Configures semi-transparent overlay.
	* overlay_size() is attached to the window.resize event handler.
	* As noted above, this function can be called statically or not. Event is an optional parameter
	* provided by the event handler only. If called on the object it will perform as expected.
	*/
	this.overlay_size = function(event) {
		var that;
		if(!this.settings && event) {
			that = event.data.greyboxObject;
		} else {
			that = this;
		}
		
		try {
			var de = document.documentElement;
			w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
			h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
		} catch(err) {
			w = jQuery(document.body).width();
			h = jQuery(document.body).height();
		}
		jQuery("#"+that.overlay_id).css({"height":h+"px", "width":w +"px"});
	}
	
	 /*
	* Method: position(jquery.Event)
	*
	* Description: Positions display elements of the greybox based on this.settings.
	* position() is attached to the window.resize event handler.
	* As noted above, this function can be called statically or not. Event is an optional parameter
	* provided by the event handler only. If called on the object it will perform as expected.
	*/
	this.position = function(event) {
		var that;
		if(!this.settings && event) {
			that = event.data.greyboxObject;
		} else {
			that = this;
		}
		
		var de = document.documentElement;
		var w = jQuery(document.body).width();
		var h = jQuery(document.body).height();
		jQuery("#"+that.window_id).css({
		width: that.settings.width+"px",
		height: that.settings.height+"px",
		left: ((w - that.settings.width)/2)+ "px",
		top:  ((h - that.settings.height)/2)+"px"});
		jQuery("#"+that.frame_id).css("height",that.settings.height - 32 +"px");
	}
	
	/*
	* Method: resize(width, height)
	*
	* Description: resize() will resize the window and repaint instantaneously.
	*/
	this.resize = function(width, height) {
		this.settings.width = width;
		this.settings.height = height;
		this.position();
	}
	
	/*
	* Method: close(jquery.Event)
	*
	* Description: close() is attached to the click event handler for the close button in Greybox
	* as noted above, this function can be called statically or not. Event is an optional parameter
	* provided by the event handler only. If called on the object it will perform as expected.
	*/
	this.close = function(event) {
		var that;
		if(!this.settings && event) {
			that = event.data.greyboxObject;
		} else {
			that = this;
		}
		
		jQuery("#"+that.window_id+","+"#"+that.overlay_id).remove();
		if(that.settings.callback && typeof(that.settings.callback) == 'function') {
			that.settings.callback.apply();
		}
	}
	
	/* MB 12/18/07: Obsolete
	* Method: hide();
	*
	* Description:This is the hide() function available to the user. 
	* Users should use this to close the greybox, Ex. myGreyBox.hide();	
	*/
	/*
	this.hide = function() {
		jQuery("#"+this.closebutton_id).trigger("click");
	}
	*/
	
	/*
	* Method: show();
	*
	* Description: show() displays the actual greybox on the screen. Note that if you're planning on passing an html string
	* with an iframe you need to use greybox.generate_iframe() to ensure your iframe has the correct parameters.
	*/
	this.show = function(html) {
		jQuery(document.body).append(
			"<div id='"+this.overlay_id+"' class='GB_overlay'></div>" +
			"<div id='"+this.window_id+"' class='GB_window'>" +
				"<div id='"+this.caption_id+"' class='GB_caption'></div>" +
				"<div id='"+this.closebutton_id+"' class='GB_closebutton'>&nbsp;</div>" +
			"</div>");		
		jQuery("#"+this.closebutton_id).bind('click', {greyboxObject:this}, this.close);
		
		if(this.settings.overlay_clickable) {
			jQuery("#"+this.overlay_id).bind('click', {greyboxObject:this}, this.close);
		}
		
		jQuery(window).bind('resize', {greyboxObject:this}, this.position);
		jQuery(window).bind('resize', {greyboxObject:this}, this.overlay_size);
		this.overlay_size();
		
		jQuery("#"+this.window_id).append(html);	
		jQuery("#"+this.caption_id).html(this.settings.caption);
		jQuery("#"+this.overlay_id).show();
		
		this.position();
		
		if(this.settings.animation) {
			jQuery("#"+this.window_id).slideDown("slow");
		} else {
			jQuery("#"+this.window_id).show();
		}
	}
};