// Identifies if the busy responder should be used
useBusyResponder = false;
// Identifies if the responders should be used
useAjaxResponders = true;

// Creates the attributes to control de lightboxes sequence
openedLightboxes = 0;
lightboxIncrement = 100;
overlayIncrement = 99;
defaultIncrement = 100;
shownLightboxes = new Array();
lightboxesCallers = [];
lightboxFocusForm = null;
lightboxFocusElement = null;
lightboxesToClear = [];
lightboxesToClearStr = '';
clearLightboxesOnShow = false;
callFunctionsAfterInit = new Array();
dynamicLightboxesRel = new Array(
	'validationContainerLightboxContainer', 
	'generalConfirmLightboxContainer', 
	'customConfirmLightboxContainer',
	'generalMessageLightboxContainer',
	'customMessageLightboxContainer',
	'generalSuccessLightboxContainer',
	'generalCommentsLightboxContainer'
);
dynamicLightboxesElement = new Array(
	'validationErrorMessagesDiv', 
	'generalConfirmMessage',
	'customConfirmMessage',
	'generalMessageText',
	'customMessageText',
	'generalSuccessText',
	'generalCommentsText'
);

/* Additional methods added to Element to control elements size */
Object.extend(Element, {
	getWidth: function(element) {
	   	obj = $(element)
	   	return obj.style.width
	},
	setWidth: function(element,w) {
	   	obj = $(element)
    	obj.style.width = w +"px"
	},
	getHeight: function(element) {
	   	obj = $(element)
	   	return obj.style.height
	},
	setHeight: function(element,h) {
   		obj = $(element)
    	obj.style.height = h +"px"
	},
	getTop: function(element) {
	   	obj = $(element)
	   	return obj.style.top
	},
	setTop: function(element,t) {
	   	obj = $(element)
    	obj.style.top = t +"px"
	},
	getLeft: function(element) {
	   	obj = $(element)
	   	return obj.style.left
	},
	setLeft: function(element,l) {
	   	obj = $(element)
    	obj.style.left = l +"px"
	}
})

/* Creation of Lightbox class */
var Lightbox = Class.create()

/**
 * Defining Lightbox prototype
 */
Lightbox.prototype = {
	initialize : function() {
		if (!document.getElementsByTagName){ return }

		// loop through all anchor tags with class lightboxOn
		var lightboxOnAnchors = $$('a.lightboxOn')
		lightboxOnAnchors.each(function(element) {
			element.onclick = function () {
				objLightbox.show(this)
				return false
			}
		})

		// loop through all input tags (preferably buttons) with class lightboxOn
		var lightboxOnAnchors = $$('input.lightboxOn')
		lightboxOnAnchors.each(function(element) {
			element.onclick = function () {
				objLightbox.show(this)
				return false
			}
		})

		// loop through all anchor tags with class lightboxOff
		var lightboxOffAnchors = $$('a.lightboxOff')
		lightboxOffAnchors.each(function(element) {
			element.onclick = function () {
				objLightbox.hide(element)
				return false
			}
		})

		// loop through all input tags (preferably buttons) with class lightboxOff
		var lightboxOffButtons = $$('input.lightboxOff')
		lightboxOffButtons.each(function(element) {
			element.onclick = function () {
				objLightbox.hide(element)
				return false
			}
		})

		/* Create overlay that will fade in */
		createOverlay(false);
	},

	show : function(element) {

		// This is necessary to block double click on the lightboxes callers
		for (var i = 0; i < lightboxesCallers.length; i++)
			if (lightboxesCallers[i].getAttribute('rel') == element.getAttribute('rel'))
				return false;

		/* Pushes the element */
		lightboxesCallers.push(element);
		/* Hide select boxes outside de lightbox */
		hideSelectBoxes(element.getAttribute('rel'))

		// Lightbox drag and drop
		var handleElement = getLightboxTitleElement($(element.getAttribute('rel')));
		if (handleElement != null) {
			// Changes the light box title id
			handleElement.id = element.getAttribute('rel') + 'Title';
			// Creates the drag and drop for the light box title element
			if ($(handleElement.id) != null)
				jQuery('#' + element.getAttribute('rel')).draggable({handle: '#' + handleElement.id});
		}

		// Controls the dynamic light boxes
		updateDynamicLightboxesOnShow(element);
		
		// Sets the overlay zIndex
		$('overlay').style.zIndex = openedLightboxes * defaultIncrement + overlayIncrement;
		// Shows the overlay
		showOverlay();
		// Shows the lightbox
		showLightbox(element.getAttribute('rel'));

		// Increments the number of opened lightboxes
		openedLightboxes++;

		// Clears the closed lightboxes content
		if (clearLightboxesOnShow)
			clearClosedLightboxes(element);
	},

	hide : function(element)
	{
		// If this lightbox is present in the string of lightboxes to clear, adds to the array
		if (clearLightboxesOnShow && lightboxesToClearStr.indexOf(element.getAttribute('rel') + ',') != -1)
			lightboxesToClear.push(element.getAttribute('rel'));

		// Removes the element
		lightboxesCallers.pop();
		// Removes the last index of the array shownLightboxes
		shownLightboxes = shownLightboxes.slice(0, openedLightboxes - 1);
		// It's necessary to check if the object is an array because if there is only one lightbox left,
		// the slice method returns the object itself, not an array, and as the method showSelects checks
		// the array length it would cause an error
		if (!isArray(shownLightboxes))
			shownLightboxes = new Array(shownLightboxes);

		// Hides the lightbox
		Element.hide(element.getAttribute('rel'))

		// Decrements the number of opened lightboxes
		openedLightboxes--;
		// The number of opened lightboxes cannot be smaller than 0
		if (openedLightboxes < 0)
			openedLightboxes = 0;

		// Show the select boxes
		showSelectBoxes();

		// Hides the last overlay
		if (openedLightboxes == 0)
		{
			// Hides the element
			Effect.Fade('overlay', { duration: 0.1});
		}
		else
		{
			// Removes the old overlay and creates the new one
			createOverlay(true);
			// Sets the overlay zIndex property
			$('overlay').style.zIndex = (openedLightboxes - 1) * defaultIncrement + overlayIncrement;
		}
		
		// Controls the dynamic light boxes
		updateDynamicLightboxesOnHide(element);
	}
}

/**
 * Method to show centralized lightbox
 */
function showLightbox(lightbox) {
	/* get window dimensions */
	var arrayWindowSize = getWindowSize();
	/* get page dimensions */
	var arrayPageSize = getPageSize();
	/* get scroll dimensions */
	var arrayPageScroll = getPageScroll();

	/* get lightbox width and height */
	var width = Element.getWidth(lightbox).toString(); // lightbox width accept only px size
	var height = Element.getHeight(lightbox).toString(); // lightbox height accept only px size

	/* if width or height is empty or in % default to width = 600 and height = 400 */
	if(width == '' || width.substring(width.length - 1) == '%') {
		width = 600
	} else if(width.substring(width.length - 2) == 'px'){
		width = width.substring(0, width.length - 2)
	}
	if(height == '' || height.substring(height.length - 1) == '%') {
		height = 400
	} else if(height.substring(height.length - 2) == 'px'){
		height = height.substring(0, height.length - 2)
	}
	
	/* Centralize lightbox */
	var left = ((arrayWindowSize[0] - width) / 2) + arrayPageScroll[0];
	var top = ((arrayWindowSize[1] - height) / 2) + arrayPageScroll[1];

	if (left < arrayPageScroll[0])
		left = arrayPageScroll[0];
	if (top < arrayPageScroll[1])
		top = arrayPageScroll[1];

	Element.setTop(lightbox,top);
	Element.setLeft(lightbox,left);

	/* Show lightbox */
	Effect.Appear(lightbox, { duration: 0.2, from: 0.0, to: 1 })
	
	// Sets the focus on a lightbox element
	if (lightboxFocusElement != null)
		setTimeout('setLightboxFocus()', 250);

	// Puts the current lightbox in the array of shown lightboxes
	shownLightboxes[openedLightboxes] = $(lightbox);
	// Sets the lightbox zIndex property
	shownLightboxes[openedLightboxes].style.zIndex = openedLightboxes * defaultIncrement + lightboxIncrement;
}

/**
 * Method to hide select box outside the lightbox otherwise selects would be on top overlay in IE
 */
function hideSelectBoxes(lightbox) {
	// TODO: Refactor - See if prototype has any function to help with it
	/* hide all select boxes */
	selects = document.getElementsByTagName("select")
	$A(selects).each(function(element) {
		element.style.visibility = "hidden"
	})

	/* show only select boxes inside lightbox */
	lightboxSelects = $$('div#' + lightbox + ' select')
	lightboxSelects.each(function(element) {
		element.style.visibility = "visible"
	});
	
	// Hides the flash objects
	jQuery('object').each(function() {
		this.style.visibility = 'hidden';
	});
}

/**
 * Method to show hided select box
 */
function showSelectBoxes() {
	// If there are any lightboxes opened, gets only the selects of the last one
	// This is necessary because if this function show always all the selects, there might be any
	// lightbox still opened, and the select will appear in front of the overlay (browser IE)
	if (shownLightboxes.length > 0)
		selects = shownLightboxes[shownLightboxes.length - 1].getElementsByTagName("select");
	// Else, gets all the selects
	else
		selects = document.getElementsByTagName("select");

	// Show the selects
	$A(selects).each(function(element){
		element.style.visibility = "visible"
	});
	
	// Shows the flash objects
	setTimeout(function() {
		jQuery('object').each(function() {
			this.style.visibility = 'visible';
		});
	}, 200);
}

// Returns an array containing window width and window height (visible portion)
function getWindowSize(){
	
	// Variables to store the window size
	var windowSizeX, windowSizeY;
	// Firefox
	if (self.innerHeight != undefined && self.innerWidth != undefined && window.scrollMaxX != undefined && window.scrollMaxY != undefined) {
		windowSizeX = self.innerWidth;
		windowSizeY = self.innerHeight;
		if (jQuery('html').css('overflowY') == 'scroll' || (window.scrollMaxY && window.scrollMaxY > 0)) {
			windowSizeX -= 16;
		}
		if (jQuery('html').css('overflowX') == 'scroll' || (window.scrollMaxX && window.scrollMaxX > 0)) {
			windowSizeY -= 16;
		}
	}
	// Other browsers
	else {
		windowSizeX = document.documentElement.clientWidth;
		windowSizeY = document.documentElement.clientHeight;
	}
	
	// Returns the array
	return new Array(windowSizeX, windowSizeY);
}

// Returns an array containing page width and page height
function getPageSize() {
	
	// Variables to store the page size
	var pageSizeX, pageSizeY;
	// Firefox
	if (self.innerHeight != undefined && self.innerWidth != undefined && window.scrollMaxX != undefined && window.scrollMaxY != undefined) {
		pageSizeX = self.innerWidth + window.scrollMaxX;
		pageSizeY = self.innerHeight + window.scrollMaxY;
		if (jQuery('html').css('overflowY') == 'scroll' || (window.scrollMaxY && window.scrollMaxY > 0)) {
			pageSizeX -= 16;
		}
		if (jQuery('html').css('overflowX') == 'scroll' || (window.scrollMaxX && window.scrollMaxX > 0)) {
			pageSizeY -= 16;
		}
	}
	// Other browsers
	else {
		pageSizeX = document.body.scrollWidth;
		pageSizeY = document.body.scrollHeight;
	}
	
	// Returns the array
	return new Array(pageSizeX, pageSizeY);
}

// Returns an array containing page scroll (Thanks to http://www.quirksmode.org/viewport/compatibility.html)
function getPageScroll(){
	
	// Variables to store the scroll X and Y
	var scrollX, scrollY;
	// All except explorer
	if (self.pageYOffset || self.pageXOffset) { 
		scrollX = self.pageXOffset;
		scrollY = self.pageYOffset;
	}
	// Explorer 6 Strict
	else if (document.documentElement && document.documentElement.scrollTop) { 
		scrollX = document.documentElement.scrollLeft;
		scrollY = document.documentElement.scrollTop;
	} 
	// All other explorers
	else if (document.body) { 
		scrollX = document.body.scrollLeft;
		scrollY = document.body.scrollTop;
	}

	// Returns the array
	return new Array(scrollX, scrollY);
}

// Creates the overlay object
function createOverlay(showOverlayNow)
{
	/* Create overlay that will fade in */
	var objBody = document.getElementsByTagName("body").item(0);

	// If the overlay aux exists, removes it
	if ($('overlayAux') != null)
		objBody.removeChild($('overlayAux'));

	// Checks if the object overlay exists. If it does, removes it
	if ($('overlay') != null)
		$('overlay').id = 'overlayAux';

	// Creates the overlay element
	var objOverlay = document.createElement("div");
	objOverlay.setAttribute('id', 'overlay');
	objOverlay.style.display = 'none';
	objBody.appendChild(objOverlay);

	// Show the overlay
	if (showOverlayNow)
		showOverlay();
}

// Shows the overlay
function showOverlay() {
	
	// Gets the body object
	var objBody = document.getElementsByTagName("body").item(0);

	// Retrieves the page size
	var arrayPageSize = getPageSize();
	// Stretch overlay to fill page and fade in
	Element.setWidth('overlay', arrayPageSize[0]);
	Element.setHeight('overlay', arrayPageSize[1]);
	
	// Shows the overlay
	Effect.Appear('overlay', { duration: 0, from: 0.1, to: 0.6 })

	// Removes the element overlay aux
	if ($('overlayAux') != null)
		Effect.Fade('overlayAux', { duration: 0.1});
}

// Checks if an element is an array
function isArray(element)
{
	// If the element is not an array, returns false
	if (element.constructor.toString().indexOf("Array") == -1)
		return false;

	// Else, returns true
	return true;
}

// Sets the focus on a lightbox field.
function setLightboxFocus()
{
	if (document.forms[lightboxFocusForm] && document.forms[lightboxFocusForm].elements[lightboxFocusElement])
		document.forms[lightboxFocusForm].elements[lightboxFocusElement].focus();
	lightboxFocusElement = null;
	lightboxFocusForm = null;
}

// Clears the closed lightboxes.
function clearClosedLightboxes(element)
{
	// Iterates the lightboxes to clear
	while (lightboxesToClear.length > 0)
	{
		// Gets the current element
		var currentLightbox = lightboxesToClear.pop();
		// Clears the innerHTML of the first child node (div)
		if (currentLightbox != element.getAttribute('rel') && $(currentLightbox) && $(currentLightbox).childNodes)
		{
			// Gets the main lightbox div element
			var currentDivId = currentLightbox.substring(0, currentLightbox.indexOf('Container'));
			// Gets the current fiv
			var currentDiv = $(currentDivId);
			// Checks for the first div of the lightbox container
			if (currentDiv != null && currentDiv != undefined)
			{
				// Gets the div id
				var currentId = currentDiv.id;
				var currentClass = currentDiv.getAttribute('class');
				var currentStyle = currentDiv.getAttribute('style');
				// IE considers the getAttribute('style') as an object
				if (currentStyle != null && typeof currentStyle == 'object')
					currentStyle = currentStyle.cssText;
				// Removes the div of the lightbox container
				$(currentLightbox).removeChild(currentDiv);
				// Creates the new div
				var newDiv = document.createElement("div");
				// Sets the id
				newDiv.id = currentId;
				// Sets the css class
				if (currentClass != null && currentClass.length > 0)
					newDiv.setAttribute('class', currentClass);
				// Sets the inline style
				if (currentStyle != null && currentStyle.length > 0)
					newDiv.style.cssText = currentStyle;
				// Appends the new div to the lightbox container
				$(currentLightbox).appendChild(newDiv);

				// Breaks the loop
				break;
			}
		}
	}
}

// Repositions the overlay and all the opened lightboxes.
function repositionLightboxes()
{
	// If there are opened lightboxes, reposition them
	if (openedLightboxes > 0)
	{
		/* get window dimensions */
		var arrayWindowSize = getWindowSize();
		/* get page dimensions */
		var arrayPageSize = getPageSize();
		/* get scroll dimensions */
		var arrayPageScroll = getPageScroll();
		
		// Reposition the lightboxes
		for (var i = 0; i < shownLightboxes.length; i++)
		{
			// Gets the lightbox
			var lightbox = shownLightboxes[i].id;
			
			/* get lightbox width and height */
			var width = Element.getWidth(lightbox) // lightbox width accept only px size
			var height = Element.getHeight(lightbox) // lightbox height accept only px size
		
			/* if width or height is empty or in % default to width = 600 and height = 400 */
			if(width == '' || width.substring(width.length - 1) == '%') {
				width = 600
			} else if(width.substring(width.length - 2) == 'px'){
				width = width.substring(0, width.length - 2)
			}
			if(height == '' || height.substring(height.length - 1) == '%') {
				height = 400
			} else if(height.substring(height.length - 2) == 'px'){
				height = height.substring(0, height.length - 2)
			}
		
			/* Centralize lightbox */
			var left = ((arrayWindowSize[0] - width) / 2) + arrayPageScroll[0];
			var top = ((arrayWindowSize[1] - height) / 2) + arrayPageScroll[1];
		
			if (left < arrayPageScroll[0])
				left = arrayPageScroll[0];
				
			if (top < arrayPageScroll[1])
				top = arrayPageScroll[1];
			
			Element.setTop(lightbox,top);
			Element.setLeft(lightbox,left);
		}
		
		// It's necessary to reload the window dimensions
		// In case the LB generated scrolls, the window size is bigger than the visible area, and after the
		// reposition these arrays change again
		// So, in this block these arrays are reloaded
		
		// get window dimensions
		arrayWindowSize = getWindowSize();
		// get page dimensions
		arrayPageSize = getPageSize();
		// get scroll dimensions
		arrayPageScroll = getPageScroll();
		// Reposition the overlay
		Element.setWidth('overlay', arrayPageSize[0]);
		Element.setHeight('overlay', arrayPageSize[1]);
	}
	
	// If the busy responder is visible, reposition it
	if ($('busyResponder') && $('busyResponder').style.display != 'none')
		showBusyResponder();
}

// Controls the dynamic light boxes on show
function updateDynamicLightboxesOnShow(element) {
	
	// Gets the light box attribute
	var lbRel = element.getAttribute('rel');
	
	// Validation light box - dynamic height implementation
	for (var i = 0; i < dynamicLightboxesRel.length; i++) {
		
		if (lbRel.indexOf(dynamicLightboxesRel[i]) != -1) {
			
			// Gets the error message span element
			var dynamicElement = dynamicLightboxesElement[i];
			if (lbRel.length > dynamicLightboxesRel[i].length)
				dynamicElement += lbRel.substring(dynamicLightboxesRel[i].length);
			var lbElement = $(dynamicElement);
			
			// To get the element height, it can not be display = none, so changes it
			$(lbRel).style.visibility = 'hidden';
			$(lbRel).style.overflow = 'hidden';
			$(lbRel).style.display = '';
	
			// Defines the element height according to the offset height (to correct the IE scroll bug)
			lbElement.style.height = lbElement.offsetHeight;
			
			// Gets the light box height (error message span + 110px)
			var totalHeight = parseInt(lbElement.offsetHeight) + 110;
			
			// Changes the light box height and width
			$(lbRel).style.height = totalHeight + 'px';
			$(lbRel).style.width = (parseInt(lbElement.offsetWidth) + 35) + 'px';
			
			// Returns to the original state (visible and display = none)
			$(lbRel).style.display = 'none';
			$(lbRel).style.visibility = 'visible';
		}
	}
}

// Controls the dynamic light boxes on hide
function updateDynamicLightboxesOnHide(element) {

	// Gets the light box attribute
	var lbRel = element.getAttribute('rel');
	
	// Validation light box - dynamic height implementation
	for (var i = 0; i < dynamicLightboxesRel.length; i++) {
		
		if (lbRel.indexOf(dynamicLightboxesRel[i]) != -1) {
			
			// Gets the error message span element
			var errorSpan = dynamicLightboxesElement[i];
			if (lbRel.length > dynamicLightboxesRel[i].length)
				errorSpan += lbRel.substring(dynamicLightboxesRel[i].length);
			$(errorSpan).style.height = null;
		}
	}
}

function getLightboxTitleElement(parentElement) {
	
	// Iterates the light box elements to get the lightboxTitle paragraph
	for (var i = 0; i < parentElement.childNodes.length; i++)
	{
		if (parentElement.childNodes[i].className == 'lightboxTitle' || parentElement.childNodes[i].className == 'lightboxTitleMargin')
			return parentElement.childNodes[i];
		
		var childElement = getLightboxTitleElement(parentElement.childNodes[i]);
		if (childElement != null)
			return childElement;
	}
}

function initLightbox() {
	objLightbox = new Lightbox();
	for (var i = 0; i < callFunctionsAfterInit.length; i++)
		callFunctionsAfterInit[i]();
}
Event.observe(window, 'load', initLightbox, false);
Event.observe(window, 'resize', repositionLightboxes, false);
