/**
 * jquery.jonbox.js
 *  ~ Jon ????.??.??
 *  ~ JosephL 2008.10.24
 * 
 * jQuery needs to be included on the page including this script... v 1.2.6 or higher
 * 
 * 2008.10.24
 *  - Added jonbox alert
 *  - Added jonbox form
 *  - Uses ai javascript.parallel.js now
 *  - Tested working, IE6, IE7, FireFox(OS X), Safari(OS X), Opera(OS X)
 *
 * 2008.10.26
 *  - Added re-positioning support, now finds position bassed off of viewport
 *  - Added better resize/scroll support
 *  - Added jonbox_open_div
 *
 * 2008.10.27
 *  - Added jonbox_open_img
 *
 * 2008.11.05
 *  - Add feature to hide all elements with class="jonbox_hide" when jonbox is active
 *    and show when jonbox is closed
 **/
var jonbox_close_image = "includes/plugins/jonbox/images/jonbox_close.gif";
var jonbox_close_hot_image = "includes/plugins/jonbox/images/jonbox_close_hot.gif";
var jonbox_loading_image = "includes/plugins/jonbox/images/jonbox_loading.gif";

if(typeof jQuery!='undefined') {
	$(document).ready(init_jonbox);
} else {
	alert('Error: jonbox requires jQuery to be included.');
}

/**
 * Sets up the hidden div to display the jonbox
 * Also binds the click to all "a" objects withs rel="jonbox"
 **/
function init_jonbox(e)
{
	init_links();
	
	var img1 = new Image();
	img1.src = jonbox_close_image;
	
	var img2 = new Image();
	img2.src = jonbox_close_hot_image;
	
	var img_load = new Image();
	img_load = jonbox_loading_image;
	
	$("<div />").attr("id", "jonbox_jblock").appendTo("body").hide().css({
		backgroundColor: "#000",
		opacity: 0,
		width: "100%",
		position: "absolute",
		left: 0,
		top: 0,
		zIndex: 100
	}).click(close_jonbox);
	// .click(close_jonbox) // append to above call to enable clicking outside the box to close.
	$("<div />").attr("id", "jonbox_loading").appendTo("body").hide().css({
		backgroundColor:"#656565",
		color: "#f0f0f0",
		fontFamily: "'Lucida Grande', Arial, Helvetica, sans-serif",
		fontSize: "1.5em",
		fontWeight: 700,
		position: "absolute",
		left: "-9999px",
		top: "-9999px",
		zIndex: 500,
		border: "solid 2px #3F3F3F",
		padding: "5px 10px 5px 10px"
	}).html($("<img />").attr({
		src: jonbox_loading_image,
		alt: "Loading",
		title: "Loading"
	})).click(close_jonbox); // If error occurs, they can click loading to get out of jonbox
	$("<div />").attr("id", "jonbox").appendTo("body").hide().css({
		backgroundColor: "#f0f0f0",
		opacity: 0,
		position: "absolute",
		left: 0,
		top: 0,
		zIndex: 1000
	});
	$("<div />").attr("id", "jonbox_titlebar").appendTo("#jonbox").css({
		background: "transparent url(includes/plugins/jonbox/images/title_bar_bg.png) repeat-x -15px bottom",
		textAlign: "right",
		padding: "3px"
	});
	$("<div />").attr("id", "jonbox_content").appendTo("#jonbox").css({
		background: "#ffffff",
		padding: "15px"
	});
	$("<img />").attr({
		src: jonbox_close_image,
		alt: "x",
		title: "Close"
	}).css({
		cursor: "pointer"
	}).hover(function () {
		this.src = jonbox_close_hot_image;
	}, function () {
		this.src = jonbox_close_image;
	}).appendTo("#jonbox_titlebar").click(close_jonbox);
}

function init_links()
{
	$("a").each(function(i) {
		if ( $(this).attr("rel") == "jonbox" ) {
			$(this).bind("click", {aobj: this}, open_jonbox_from_object);
		}
	});
}

/**
 * Opens a jonbox from a "a href=" object.
 * 
 * @param: e : the object
 **/
function open_jonbox_from_object(e)
{
	return open_jonbox(e.data.aobj.href);
}

/**
 * Opens a jonbox, retiving the content via. ajax.parallel and handling it properly for 
 * the jonbox system
 *
 * @param: url : the url to retive & display
 * @param: post_str OPTIONAL: post string to submit with the http call using post
 **/
function open_jonbox(url, post_str)
{
	$("#jonbox_jblock").css({
		height: $(document).height()
	}).show(1, function() {
		$(this).animate({
			opacity: 0.50
		}, 200, null, function() {
			show_loading();
			// use AI ajax handler instead of jQuery handler
			if(post_str == undefined) {					
				ajax_get_request(url, jonbox_ajax_call_return);
			} else {
				ajax_post_request(url, post_str, jonbox_ajax_call_return);
			}
		});
	});
	return false;
}

/**
 * Handles AI standard ajax returns better
 * Displays results nicely in the jonbox
 **/
function jonbox_ajax_call_return( ajax_http )
{
	var sep_loc = ajax_http.responseText.indexOf( '|' );
	var response_name = '';
	var response_value = '';
	
	if( sep_loc > 0 ) 
	{
		response_name = ajax_trim_str( ajax_http.responseText.substr( 0, sep_loc ) );
		response_value = ajax_http.responseText.substr( 1 + sep_loc );
		
		if( response_name == 'ajax_error' )
		{
			//REPORT THE ERROR
			var err_msg = '<table><tr><td valign="top" style="padding-right:20px;"><img src="includes/plugins/jonbox/images/alert_red_48.png" style="align:left;margin-left:20x;" align="left" /></td>';
			err_msg +='<td style="width:400px;color:#FF0000;">';
			err_msg += response_value + '<br><div style="text-align:right;padding-left:10px;height:20px;"><input type="button" onclick="close_jonbox()" value="OK"></div></td>';
			$("#jonbox_content").html(err_msg);
		}
		else if( response_name == 'ajax_run_script' )
		{
			close_jonbox();
			ajax_run_script( response_value );
		}
		else
		{
			// Ingore the set location and set the response as the content.
			$("#jonbox_content").html(response_value);
		}
	}
	else
	{
		// jonbox support full page fetches, no error in this case
		$("#jonbox_content").html(ajax_http.responseText);
	}
	// Everything is ready, show the jonbox!
	show_jonbox();
}

/**
 * Hides the loading icon then animates in the the jonbox
 **/
function show_jonbox()
{
	// Set any special items with class jonbox_hide to be hidden
	// These items may interfear with the jonbox
	$('.jonbox_hide').css('visibility','hidden');
	
	// Show the jobbox with full content
	$("#jonbox_loading").fadeOut("fast", function() {
		$("#jonbox").show(1, function() {
			position("jonbox");
			var top = $(this).css('top');
			top = parseInt(top);
			$(this).css({
				top: (top - 20) + "px"
			}).animate({
				top: (top + 20) + "px",
				opacity: 1
			}, 300);
			$(window).resize(jonbox_reposition_resize).scroll(jonbox_reposition_scroll);
		});
	});
}

function show_loading()
{
	position("jonbox_loading");
	$("#jonbox_loading").fadeIn("fast");
}

function position(div_id)
{
	set_position(div_id, false);
}

/**
 * bounded to window resize event, move the jonbox
 **/
var reposition_active = false;
var scroll_x = 0;
var scroll_y = 0;
var vp_x = 0;
var vp_y = 0;
function jonbox_reposition_resize(e)
{	
	// Get active window 
	var win = get_window_sizes();
	scroll_offset_x = win.scroll_offset_x;
	scroll_offset_y = win.scroll_offset_y;
	vp_width = win.vp_width;
	vp_height = win.vp_height;
	
	// If it does not match, then the effect is still in play
	// IE only, if other browser run the event because scroll
	// and resize trigger once rather than over and over
	if(!jQuery.browser.msie || (
		win.scroll_offset_x == scroll_x 
		&& win.scroll_offset_y == scroll_y
		&& win.vp_width == vp_x
		&& win.vp_height == vp_y)) {
			// Matched, so re-position the window
			$("#jonbox_jblock").css({
				height: $(document).height()
			});
			set_position('jonbox', true);
		}
		else {
			reposition_active = true;
			scroll_x = win.scroll_offset_x;
			scroll_y = win.scroll_offset_y;
			vp_x = win.vp_width;
			vp_y = win.vp_height;
		}
}

var timer = false;
function jonbox_reposition_scroll(e)
{
	// Get active window 
	var win = get_window_sizes();
	scroll_offset_x = win.scroll_offset_x;
	scroll_offset_y = win.scroll_offset_y;
	vp_width = win.vp_width;
	vp_height = win.vp_height;
	
	// If it does not match, then the effect is still in play
	if(win.scroll_offset_x == scroll_x 
		&& win.scroll_offset_y == scroll_y
		&& win.vp_width == vp_x
		&& win.vp_height == vp_y) {
			// Matched, so re-position the window
			$("#jonbox_jblock").css({
				height: $(document).height(),
				width: $(document).width()
			});
			set_position('jonbox', true);
			timer = false;
		}
		else {
			reposition_active = true;
			scroll_x = win.scroll_offset_x;
			scroll_y = win.scroll_offset_y;
			vp_x = win.vp_width;
			vp_y = win.vp_height;
			// timeout and try again (only once)
			// some browswer act like they are trying over and over but never
			// successed in running the effect
			if(!timer) {
				setTimeout(jonbox_reposition_scroll, 400);
				timer = true;
			}
		}
}

/**
 * Positions the jonbox (1/3 centering vertically, absolute centering horizontally)
 * param string div_id  the id of the jonblock
 * 2008.01.08 - If box height is greater than 1/3 center viewing space, simplay display 25 pixles down ~JosephL
 * 2008.10.26 - Taken from jonbox 1.0, added animation effects ~ JosephL
 * returns void
 */
function set_position(div_id, animate)
{
	var jonbox = document.getElementById(div_id);

	var scroll_offset_x, scroll_offset_y, vp_width, vp_height, jonbox_height, jonbox_width;

	var win = get_window_sizes();
	scroll_offset_x = win.scroll_offset_x;
	scroll_offset_y = win.scroll_offset_y;
	vp_width = win.vp_width;
	vp_height = win.vp_height;
	
	// Computer jonbox dimensions
	jonbox_height = jonbox.offsetHeight;
	jonbox_width = jonbox.offsetWidth;
	
	// Set the CSS to position the jonbox - x axis
	var jonbox_x = parseInt((vp_width - jonbox.offsetWidth) / 2 + scroll_offset_x);
	
	// Set the CSS to position the jonbox - y axis
	var jonbox_y = 0;
	var static_pos = false;
	
	if(jonbox_height+25 > vp_height)
	{
		// display 25 from top of viewport
		if(jonbox.style.top == "0pt" || jonbox.style.top == "0" ||jonbox.style.top == "0px")
		{
			jonbox_y = parseInt(25 + scroll_offset_y);
		}
		else
		{
			static_pos = true;
		}
	}
	else if(jonbox_height > (vp_height - ( vp_height * (1/3) )))
	{
		// this box is bigger than 1/3 the viewport!  Simply 25 pixles down from screen
		jonbox_y = parseInt(25 + scroll_offset_y);
	}
	else
	{
		// display 1/3 centering vertically
		jonbox_y = parseInt((2 * vp_height - 3 * jonbox_height) / 6 + scroll_offset_y);
	}
	
	if (jonbox_y < 25) { jonbox_y = 25; }
	
	if(!static_pos)
	{
		// both X and Y
		if(animate) {
			$("#" + div_id).animate({
				top: jonbox_y + "px",
				left: jonbox_x + "px"
			}, 200, "swing");
		} else {
			jonbox.style.top = jonbox_y + "px";
			jonbox.style.left = jonbox_x + "px";
		}		
	}
	else {
		// only X
		if(animate) {
			$("#" + div_id).animate({
				left: jonbox_x + "px"
			}, 200, "swing");
		}
		else {
			jonbox.style.left = jonbox_x + "px";
		}
	}
};

/**
 * return JSON literal contating scroll offsets & viewport information
 * multi-browser support
 **/
function get_window_sizes()
{
	// Compute scroll offsets for different browsers
	if (self.pageYOffset)
	{
		scroll_offset_x = self.pageXOffset;
		scroll_offset_y = self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop)
	{
		scroll_offset_x = document.documentElement.scrollLeft;
		scroll_offset_y = document.documentElement.scrollTop;
	}
	else if (document.body)
	{
		scroll_offset_x = document.body.scrollLeft;
		scroll_offset_y = document.body.scrollTop;
	}
	
	// Computer viewport dimensions of different browsers
	if (self.innerHeight)
	{
		vp_width = self.innerWidth;
		vp_height = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight)
	{
		vp_width = document.documentElement.clientWidth;
		vp_height = document.documentElement.clientHeight;
	}
	else if (document.body)
	{
		vp_width = document.body.clientWidth;
		vp_height = document.body.clientHeight;
	}
	
	
	return {'scroll_offset_y':scroll_offset_y, 'scroll_offset_x':scroll_offset_x, 'vp_width':vp_width, 'vp_height':vp_height};
}
/**
 * Prompts the user with a message in a pretty fashion.
 * @param: msg : html or plain txt message to display
 **/
function jonbox_alert(msg)
{
	var full_msg = '<table><tr><td valign="top" style="padding-right:20px;"><img src="includes/plugins/jonbox/images/alert_red_48.png" style="align:left;margin-left:20x;" align="left" /></td>';
	full_msg +='<td style="width:400px">';
	full_msg += msg + '<br><div style="text-align:right;padding-left:10px;height:20px;"><input type="button" onclick="close_jonbox()" value="OK"></div></td>';
	$("#jonbox_jblock").css({
		height: $(document).height()
	}).show(1, function() {
		$(this).animate({
			opacity: 0.60
		}, 100, null, function() {
			$("#jonbox_content").html(full_msg);
			show_jonbox();
		});
	});
	return false;
}


/**
 * Given form elements, and a callback funtions.  Create a pop-up that wants users input
 *
 * @param: form_id : string, the id of an element where the inner contents are the form elements to display
 * @param: passed_callback : function, the function to call once the user submits the form, returns true/false
 *          if return is true, closes the jonbox, if false, keep it open
 * @example:
 *  <div id="test_form_contents"><input type="text" name="test_input"/></div>
 *  <script> function callback_test(frm){...} </script>
 *  TO CALL: jonbox_form('test_corm_contents', callback_test);
 **/
var callback = '';
function jonbox_form(form_id, passed_callback)
{
	var form = $('#'+form_id).html();
	callback = passed_callback;
	
	var full_form = '';
	full_form += '<form name="jonbox_form" action="#" method="GET" onSubmit="if(callback(this)){close_jonbox();}return false;">';
	full_form += '<p id="jonbox_form_error" style="color:#FF0000;font-weight:bold;"></p>';
	full_form += form;
	full_form += '<br><div style="text-align:right;padding-top:10px;"><input type="button" onclick="close_jonbox()" value="Cancel">';
	full_form += '&nbsp;<input type="submit" value="Submit"></div></td>';
	full_form += '</form>';
	$("#jonbox_jblock").css({
		height: $(document).height()
	}).show(1, function() {
		$(this).animate({
			opacity: 0.60
		}, 100, null, function() {
			$("#jonbox_content").html(full_form);
			show_jonbox();
		});
	});
	return false;
}

/**	
 * Display the contents of a div in a jonbox (more jonbox 1.0 style)
 * 
 * @param: div_id : the id of the div whos content will be displayed
 **/
function jonbox_open_div(div_id)
{
	var div_contents = $("#"+div_id).html();
	
	$("#jonbox_jblock").css({
		height: $(document).height()
	}).show(1, function() {
		$(this).animate({
			opacity: 0.60
		}, 100, null, function() {
			$("#jonbox_content").html(div_contents);
			show_jonbox();
		});
	});
}

/**
 * Starts loading an image, once loaded displays the jonbox
 *
 * @param: img_src : the source of the image
 **/
var image = null;
function jonbox_open_img(img_src)
{
	$("#jonbox_jblock").css({
		height: $(document).height()
	}).show(1, function() {
		$(this).animate({
			opacity: 0.50
		}, 200, null, function() {
			show_loading();
			image = new Image();
			image.src = img_src;
			
			// Show the loading until pre-loading is complete
			setTimeout(jonbox_img_delay, '300');
		});
	});
	return false;
}
/**	
 * Checks to see if the image is done loading, if it is then 
 *  create the jonbox and display, otherwise timeout and check again
 * 
 * uses global image object
 **/
function jonbox_img_delay()
{
	if(!image.complete) {
		setTimeout(jonbox_img_delay, '300');
	} else {
		// Have the image only show as the source
		$("<img />").attr({
			src: image.src
		}).appendTo("#jonbox_content");
		
		show_jonbox();
	}
}
/**	
 * Display an error in the active form (assumes the submit callback return false, avoiding the jonbox being closed)
 * @param: msg : error message to display
 **/
function jonbox_form_error(msg)
{
	$('#jonbox_form_error').html(msg);
}

/**
 * Animate out the visiable jonbox and background.
 **/
function close_jonbox(e)
{
	$(window).unbind("resize").unbind("scroll");
	
	$("#jonbox_loading").fadeOut("Fast", function() {
		var top = $("#jonbox").css('top');
		top = parseInt(top);
	
		$("#jonbox").animate({
			top: (top + 20) + "px",
			opacity: 0
		}, 200, null, function() {
			$(this).hide();
			$("#jonbox_jblock").animate({
				opacity: 0
			}, 200, null, function() {
				$(this).hide();
				$("#jonbox_content").html('');
				// Show any of those hidden items
				$('.jonbox_hide').css('visibility','visible');
			})
		});
	});
	return false;
}