/*======================================================================*\
|| #################################################################### ||
|| # vBulletin 3.7.0 Beta 2
|| # ---------------------------------------------------------------- # ||
|| # Copyright ©2000-2007 Jelsoft Enterprises Ltd. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| #################################################################### ||
\*======================================================================*/

// #############################################################################
// vB_DatePicker
// call using:
// vBulletin.register_control("vB_Lightbox_Container", lightbox_container_id, lightbox_trigger_events)
// #############################################################################

vBulletin.events.systemInit.subscribe(function()
{
	if (vBulletin.elements["vB_Lightbox_Container"])
	{
		for (var i = 0; i < vBulletin.elements["vB_Lightbox_Container"].length; i++)
		{
			var element = vBulletin.elements["vB_Lightbox_Container"][i];
			init_postbit_lightbox(element[0], element[1]);
		}
		vBulletin.elements["vB_Lightbox_Container"] = null;
	}
});

/**
* Global variables for lightbox
*
* @var	array	Collection of all vB_Lightbox objects
* @var	object	Window overlay element - created in init_postbit_lightbox()
* @var	integer	Default for the lightbox event initialisation
*/
var Lightboxes = new Array();
var Lightbox_overlay = null;
var Lightbox_event_default = null;

// =============================================================================

/**
* Activates an attachment thumbnail to have lightbox functionality
*
* @package	vBulletin
* @version	$Revision: 24798 $
* @date		$Date: 2007-11-22 13:59:49 +0000 (Thu, 22 Nov 2007) $
* @author	Kier Darby
* @copyright	Jelsoft Enterprises Ltd.
*
* @param	object	Attachmnent Link
* @param	integer	Unique ID for the page
* @param	integer	Bitfield indicating what events to add
*/
function vB_Lightbox(element, uniqueid, events)
{
	/**
	* Main class variables
	*
	* @var	integer	Minimum border in pixels between the lightbox and the viewport edges
	* @var	integer	Minimum size in pixels for the image in the lightbox to shrink
	* @var	integer	Bitmask for click event
	* @var	integer	Bitmask for hover event
	* @var	object	Link that would normally open the image, to which events are attached
	* @var	object	Timeout handler for hover countdown
	* @var	object	Javascript Image object for preloading lightbox image
	* @var	integer	Status counter - increases value as status is closer to lightbox ready for display
	* @var	boolean	True if the lightbox is complete and visible
	*
	* @var	string	Link to full-size attachment
	* @var	string	File upload date
	* @var	string	File upload time
	* @var	string	File name
	* @var	string	Lightbox HTML from template 'lightbox'
	*
	* @var	object	Container for lightbox
	* @var	object	Lightbox object
	* @var	object	Close lightbox button
	* @var	object	Image within lightbox
	* @var	object	YUI AJAX transaction
	*/
	this.minborder = 100;
	this.mindimension = 50;
	this.event_click = 0x1;
	this.event_hover = 0x2;
	this.element = element;
	this.timeout = null;
	this.imageloader = null;
	this.status = 0;
	this.active = false;
	this.ajax_req = null;
	this.cursor = null;

	this.link = null;
	this.date = null;
	this.time = null;
	this.name = null;
	this.html = null;

	this.lightbox = null;
	this.closebtn = null;
	this.img = null;

	this.uniqueid = uniqueid;

	// hover events
	if (events & this.event_hover)
	{
		YAHOO.util.Event.on(this.element, "mouseover", this.countdown, this, true);
		YAHOO.util.Event.on(this.element, "mouseout", this.halt, this, true);
	}

	// click event
	if (events & this.event_click)
	{
		YAHOO.util.Event.on(this.element, "click", this.load_lightbox, this, true);
	}
}

/**
* Sets the internal status of the object
*
* @param	integer	Status
*/
vB_Lightbox.prototype.set_status = function(status, caller)
{
	console.log("vB_Lightbox :: Set status = %d (%s)", status, caller);
	this.status = status;
}

/**
* Checks the internal status of the object
*
* @param	integer	Status (checks for >= status)
*
* @return	boolean
*/
vB_Lightbox.prototype.check_status = function(status)
{
	if (this.status >= status)
	{
		return true;
	}
	else
	{
		console.warn("Checked status for %d, found %d", status, this.status);
		return false;
	}
}

/**
* Starts a count-down to image loading
*/
vB_Lightbox.prototype.countdown = function(e)
{
	if (!this.active)
	{
		this.set_status(1, "countdown");
		this.cursor = YAHOO.util.Dom.getStyle(this.element, 'cursor');
		this.element.style.cursor = "wait";
		this.timeout = setTimeout("Lightboxes['" + this.uniqueid + "'].load_lightbox();", 1500);
	}
}

/**
* Aborts any count-downs that have been started
*/
vB_Lightbox.prototype.halt = function(e)
{
	if (this.status < 2)
	{
		this.set_status(0, "halt");
	}
	clearTimeout(this.timeout);
	this.element.style.cursor = this.cursor;
}

/**
* Loads the lightbox AJAX request to get info about the attachment
*/
vB_Lightbox.prototype.load_lightbox = function(e)
{
	if (this.check_status(0)  && !YAHOO.util.Connect.isCallInProgress(this.ajax_req))
	{
		this.set_status(2, "load_lightbox 1");

		if (e)
		{
			YAHOO.util.Event.stopEvent(e);
		}

		if (this.timeout)
		{
			clearTimeout(this.timeout);
			this.element.style.cursor = this.cursor;
		}

		if (this.html == null)
		{
			var imagelink = this.element.getAttribute("href");

			this.ajax_req = YAHOO.util.Connect.asyncRequest("POST", imagelink, {
				success: this.handle_ajax_response,
				failure: this.handle_ajax_error,
				scope: this,
				timeout: 15000
			}, imagelink.substr(imagelink.indexOf("?") + 1) + "&ajax=1&uniqueid=" + this.uniqueid);
		}
		else
		{
			this.set_status(3, "load_lightbox 2");
			this.show_lightbox();
		}
	}
}

/**
* Handle AJAX Error
*
* @param	object	YUI AJAX
*/
vB_Lightbox.prototype.handle_ajax_error = function(ajax)
{
	//TODO: If we could detect that this was the result of a CLICK we could redirect
	// to the image page, but with the possibility of a hover, this is not desirable
	vBulletin_AJAX_Error_Handler(ajax);
}

/**
* Handles the AJAX request with info about the attachment and builds the lightbox HTML
*
* @param	object	YUI AJAX
*/
vB_Lightbox.prototype.handle_ajax_response  = function(ajax)
{
	if (ajax.responseXML && this.check_status(2))
	{
		var errors = ajax.responseXML.getElementsByTagName("error");
		if (errors.length)
		{
			this.set_status(0, "handle_ajax_response - error");

			if (errors[0].firstChild.nodeValue == "notimage")
			{
				console.warn("Attempted to load non-image (.%s) into lightbox. Aborted.", ajax.responseXML.getElementsByTagName("extension")[0].firstChild.nodeValue);
			}
			else
			{
				// TODO: not the prettiest error handler
				alert(errors[0].firstChild.nodeValue.replace(/<(\/|[a-z]+)[^>]+>/g, ""));
			}

			return false;
		}

		var link = ajax.responseXML.getElementsByTagName("link");
		if (link.length)
		{
			this.set_status(3, "handle_ajax_response - success");

			this.show_overlay();

			this.link = link[0].firstChild.nodeValue;

			this.imageloader = new Image();
			YAHOO.util.Event.on(this.imageloader, "load", this.show_lightbox, this, true);

			var xmlvars = new Array("date", "time", "name", "html");
			for (var i = 0; i < xmlvars.length; i++)
			{
				this[xmlvars[i]] = ajax.responseXML.getElementsByTagName(xmlvars[i])[0].firstChild.nodeValue;
			}

			this.lightbox = document.body.appendChild(string_to_node(this.html));

			this.closebtn = YAHOO.util.Dom.get("lightboxbutton" + this.uniqueid);
			YAHOO.util.Dom.setStyle(this.closebtn, "display", "none");
			YAHOO.util.Event.on(this.closebtn, "click",  this.hide_lightbox, this, true);
			YAHOO.util.Event.on(this.closebtn, "mouseover", this.highlight_closebtn, this, true);
			YAHOO.util.Event.on(this.closebtn, "mouseout", this.highlight_closebtn, this, true);

			YAHOO.util.Event.on(YAHOO.util.Dom.get("lightboxlink" + this.uniqueid), "click",  this.hide_lightbox, this, true);

			this.img = YAHOO.util.Dom.get("lightboximg" + this.uniqueid);

			this.center_lightbox();

			this.imageloader.src = this.link;
		}
	}
}

/**
* Shows, sizes and positions the window overlay/shade
*/
vB_Lightbox.prototype.show_overlay = function()
{
	if (this.check_status(2))
	{
		var vpi = fetch_viewport_info();

		YAHOO.util.Dom.setStyle(Lightbox_overlay, "display", "");
		YAHOO.util.Dom.setStyle(Lightbox_overlay, "width", vpi['w'] + "px");
		YAHOO.util.Dom.setStyle(Lightbox_overlay, "height", vpi['h'] + "px");
		YAHOO.util.Dom.setXY(Lightbox_overlay, [vpi['x'], vpi['y']]);
	}
}

/**
* Shows, sizes and positions the lightbox
*/
vB_Lightbox.prototype.show_lightbox = function()
{
	if (this.check_status(3))
	{
		this.show_overlay();

		this.img.src = this.link;
		this.resize_image();

		YAHOO.util.Dom.setStyle(this.closebtn, "display", "");
		YAHOO.util.Dom.setStyle(this.lightbox, "display", "");

		this.center_lightbox();
		this.active = true;
		this.enable_events();
	}
}

/**
* Hides the lightbox and the window overlay
*/
vB_Lightbox.prototype.hide_lightbox = function(e)
{
	this.set_status(0, "hide_lightbox");
	this.disable_events();
	this.active = false;

	YAHOO.util.Dom.setStyle(this.lightbox, "display", "none");
	YAHOO.util.Dom.setStyle(Lightbox_overlay, "display", "none");
}

vB_Lightbox.prototype.highlight_closebtn = function()
{
	var color = YAHOO.util.Dom.getStyle(this.closebtn, 'color');
	var bgcolor = YAHOO.util.Dom.getStyle(this.closebtn, 'background-color');
	var inverted_color, inverted_bgcolor;

	inverted_color = (color == "white" ? "black" : "white");
	inverted_bgcolor = (bgcolor == "white" ? "black" : "white");

	YAHOO.util.Dom.setStyle(this.closebtn, "color", inverted_color);
	YAHOO.util.Dom.setStyle(this.closebtn, "background-color", inverted_bgcolor);
}

/**
* Centers the lightbox within the browser viewport
*/
vB_Lightbox.prototype.center_lightbox = function()
{
	center_element(this.lightbox);
}

/**
* Resizes and repositions the lightbox and the window overlay after the browser viewport has altered
*/
vB_Lightbox.prototype.handle_viewport_change = function()
{
	this.resize_image();
	this.center_lightbox();
	this.show_overlay();
}
/**
* Special case for IE - starts handle_viewport_change after a short delay
*/
vB_Lightbox.prototype.handle_viewport_change_ie = function()
{
	setTimeout("Lightboxes['" + this.uniqueid + "'].handle_viewport_change();", 100);
}


/**
* Resizes the lightbox image if it is too big for the viewport
*/
vB_Lightbox.prototype.resize_image = function()
{
	var vpi = fetch_viewport_info();
	var w = this.imageloader.width;
	var h = this.imageloader.height;

	if (w > vpi['w'] - this.minborder)
	{
		w = vpi['w'] - this.minborder;
		w = (w < this.mindimension ? this.mindimension : w);
		h = Math.ceil(this.imageloader.height * (w / this.imageloader.width));
	}

	if (h > vpi['h'] - this.minborder)
	{
		h = vpi['h'] - this.minborder;
		h = (h < this.mindimension ? this.mindimension : h);
		w = Math.ceil(this.imageloader.width * (h / this.imageloader.height));
	}

	this.img.setAttribute("width", w);
	this.img.setAttribute("height", h);

	this.img.setAttribute("title", this.name + "; \n" + this.imageloader.width + " x " + this.imageloader.height + " (@" + Math.ceil(w / this.imageloader.width * 100) + "%)");

	if (w < this.imageloader.width || h < this.imageloader.height)
	{
		console.info("vB_Lightbox :: Image original size: %dx%d, resizing to %dx%d", this.imageloader.width, this.imageloader.height, w, h);
	}
}

/**
* Enables various event handlers - onresize: re-do overlay and lightbox; onscroll: hide lightbox; onclick(overlay): hide lightbox
*/
vB_Lightbox.prototype.enable_events = function()
{
	YAHOO.util.Event.on(window, "resize", (is_ie ? this.handle_viewport_change_ie : this.handle_viewport_change), this, true);
	YAHOO.util.Event.on(window, "scroll", this.hide_lightbox, this, true);
	YAHOO.util.Event.on(Lightbox_overlay, "click", this.hide_lightbox, this, true);
}

/**
* Disables the events set up by enable_events()
*/
vB_Lightbox.prototype.disable_events = function()
{
	YAHOO.util.Event.removeListener(window, "resize", (is_ie ? this.handle_viewport_change_ie : this.handle_viewport_change));
	YAHOO.util.Event.removeListener(window, "scroll", this.hide_lightbox);
	YAHOO.util.Event.removeListener(Lightbox_overlay, "click", this.hide_lightbox);
}

/**
* Checks that the <a> element passed is an attachment link
*
* @param	object	Attachment <a> link
*/
function is_lightbox_element(element)
{
	return (element.getAttribute("rel") == "Lightbox");
}

/**
* Creates the window overlay and hunts for attachment links to turn into lightboxes
*
* @param	mixed	Element/elementid containing attachment links
*/
function init_postbit_lightbox(element, events)
{
	if (Lightbox_overlay == null)
	{
		Lightbox_overlay = document.createElement("div");
		Lightbox_overlay.id = "Lightbox_overlay";

		var Lightbox_properties = {
			display: "none",
			position: "absolute",
			left: "0px",
			top: "0px",
			backgroundColor: "#000000",
			opacity: 0.85
		};
		for (var property in Lightbox_properties)
		{
			YAHOO.util.Dom.setStyle(Lightbox_overlay, property, Lightbox_properties[property]);
		}
		YAHOO.util.Dom.set

		Lightbox_overlay = document.body.appendChild(Lightbox_overlay);
	}

	// set a global default in case the value isn't present in a subsequent call (like quickedit)
	if (Lightbox_event_default === null)
	{
		Lightbox_event_default = events;
	}

	if (typeof(events) == "undefined")
	{
		// click event + hover event is the default
		events = (Lightbox_event_default ? Lightbox_event_default : 0x1 + 0x2);
	}

	var elements = YAHOO.util.Dom.getElementsBy(is_lightbox_element, "a", element);
	for (var i = 0; i < elements.length; i++)
	{
		Lightboxes[Lightboxes.length] = new vB_Lightbox(elements[i], Lightboxes.length, events);
	}
}

/*======================================================================*\
|| ####################################################################
|| # Downloaded: 13:20, Mon Dec 17th 2007
|| # CVS: $RCSfile$ - $Revision: 24191 $
|| ####################################################################
\*======================================================================*/