// XSL Stylesheets and Processors
var xslLightBoxTemplate;	// XSL Temlate
var xslLightBoxProc; 		// XSL Processor
var lightBoxXMLDoc;		// DOM Document containing lightbox XML

var lightBoxData;



var EXPIRATION_EXTENSION = 60;

function lightbox_initialize ()
{
//alert ("lightbox_initialize");
	lightbox_persist_initialize (false);
	// Load the XSL sheet
	
	if (window.XSLTProcessor) {
		var lightBoxXSLDoc = document.implementation.createDocument ("","",null);
 		lightBoxXSLDoc.async = false;
		lightBoxXSLDoc.load(BASE_URL+'LightBoxDraw.xsl');
		xslLightBoxProc = new XSLTProcessor();
		xslLightBoxProc.importStylesheet(lightBoxXSLDoc);
	} else if (window.ActiveXObject) {
		var lightBoxXSLDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");
		lightBoxXSLDoc.async = false;
//alert ("Before load of xsl file");
		lightBoxXSLDoc.load(BASE_URL+'LightBoxDraw.xsl');
//alert ("After load of XSL file");
		// Initialize the XSL processor and associate the template with the processor
		xslLightBoxTemplate = new ActiveXObject("Msxml2.xslTemplate.3.0");
		xslLightBoxTemplate.stylesheet = lightBoxXSLDoc;
		xslLightBoxProc = xslLightBoxTemplate.createProcessor();
	}
// NEED TO CHECK THE STATUS OF THE LOAD
	lightbox_draw ();

}



function lightbox_draw ()
{
//alert ("lightbox_draw");
	if (window.XSLTProcessor) {
		try {
			var outputXHTML = xslLightBoxProc.transformToFragment (lightBoxXMLDoc, document);
//alert ("transformed output is "+outputXHTML.xml);
			document.getElementById ("lightbox_area").innerHTML = "";
			document.getElementById ("lightbox_area").appendChild (outputXHTML);
		}
		catch (Exception) {
			alert ("transformation failed");
		}
	} else if (window.ActiveXObject) {
		// Render the lightbox
		xslLightBoxProc.input = lightBoxXMLDoc;
		xslLightBoxProc.transform();
		lightbox_area.innerHTML = xslLightBoxProc.output;
	}
}


// Remove an image from the lightbox
function lightbox_delete (image_number)
{
	if (!window.confirm ("Are you sure you want to remove image "+image_number+" from the lightbox")) {
		return;
	}

	// Construct the xpath for the image, select the node, delete the node.
	var xpath_string = "/LightBox/Image[@n='"+image_number+"']";

//alert ("delete the node xpath "+xpath_string);
	var deleteXMLNode = lightBoxXMLDoc.selectSingleNode (xpath_string);
//alert ("Deleted node xml is "+deleteXMLNode.xml);
	// Delete the node from the current context
	var thisParent = deleteXMLNode.parentNode;
	thisParent.removeChild (deleteXMLNode);
//lightBoxXMLDoc.removeChild (deleteXMLNode);
//alert ("after delete xx ["+thisParent.xml+"]");
	// Save out the XML and redraw
//alert ("updated nodes after delete are ["+thisParent.xml+"]");
	lightboxXMLDoc = thisParent;
	lightbox_persist_save (lightboxXMLDoc.xml);
	lightbox_draw ();
	return;
}


// Add an image to the lightbox from the Detail page.
function lightbox_add (image_number)
{	
//alert ("lightbox add "+image_number);
	lightbox_persist_initialize (false);
	var xpath_string = "/LightBox/Image[@n='"+image_number+"']";
	var currentXMLContext = lightBoxXMLDoc.selectSingleNode ("/LightBox");

//alert ("check if already in lightbox "+xpath_string);
	var dupElement = lightBoxXMLDoc.selectSingleNode (xpath_string);
	if (dupElement != null) {
		alert ("That image is already in the lightbox.");
		return;
	}

	var newImage = lightBoxXMLDoc.createElement ("Image");
	newImage.setAttribute ("n", image_number);
	currentXMLContext.appendChild (newImage);

	// Save out the XML and load the lightbox page.
	lightbox_persist_save (lightBoxXMLDoc.documentElement.xml);
	window.location=BASE_URL+"lightbox_show.htm";
}


// Clear out all of the images from the lightbox.
function lightbox_clear_all ()
{
//alert ("lightbox_clear_all");
	if (!window.confirm ("Are you sure you want to clear your lightbox images")) {
		return;
	}
	lightbox_persist_initialize (true);
	
	// Draw empty lightbox.
	lightbox_draw ();
}

function strip_XML_whitespace ()
{
//alert ("Strip whitespace");
	if (window.XSLTProcessor) {
		var stripXSLDoc = document.implementation.createDocument ("","",null);
 		stripXSLDoc.async = false;
		stripXSLDoc.load(BASE_URL+'LightBoxStrip.xsl');
		var stripProc = new XSLTProcessor();
		stripProc.importStylesheet(stripXSLDoc);
		try {
			var outputXML = stripProc.transform (lightBoxXMLDoc, document);
//alert ("transformed output is "+outputXML.xml);
			document.getElementById ("lightbox_area").innerHTML = "";
			document.getElementById ("lightbox_area").appendChild (outputXHTML);
		}
		catch (Exception) {
			alert ("transformation failed");
		}
	} else if (window.ActiveXObject) {
		var stripXSLDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");
		stripXSLDoc.async = false;
		stripXSLDoc.load(BASE_URL+'LightBoxStrip.xsl');
		// Initialize the XSL processor and associate the template with the processor
		var stripTemplate = new ActiveXObject("Msxml2.xslTemplate.3.0");
		stripTemplate.stylesheet = stripXSLDoc;
		var stripProc = stripTemplate.createProcessor();
		// Render the lightbox
		xslLightBoxProc.input = lightBoxXMLDoc;
		xslLightBoxProc.transform();
		lightbox_area.innerHTML = xslLightBoxProc.output;
	}
}

// Load an XML file into a DOM XML document.
function XMLLoadFile (file_path)
{
	var newLightBoxXMLDoc;

//alert ("path is "+xml_path);
	if (window.XSLTProcessor) {
		newLightBoxXMLDoc = document.implementation.createDocument ("","",null);
  		newLightBoxXMLDoc.async = false;
		newLightBoxXMLDoc.load (file_path);
		if (!newLightBoxXMLDoc.documentElement || 
				newLightBoxXMLDoc.documentElement.tagName == "parsererror") {
			alert ("Could not load the custom lightbox.");
			return null;
		}
//alert (newLightBoxXMLDoc.xml);
	} else if (window.ActiveXObject) {
		newLightBoxXMLDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
// DOM 3 stuff is not properly supported yet. We have to do a transform to rip out the whitespace.
//var config = newLightBoxXMLDoc.getConfig();
//config.setParameter ("comments", false);
//config.setParameter ("element-content-whitespace", false);
		newLightBoxXMLDoc.async = false;
		newLightBoxXMLDoc.load (file_path);
		if (newLightBoxXMLDoc.parseError.errorCode != 0) {
			alert ("Could not load the custom lightbox.");
			return null;
		}

	}
//alert (newLightBoxXMLDoc.xml);
	return newLightBoxXMLDoc;
}

// Load a user selected lightbox file
function lightbox_select ()
{
	var loadedLightBoxXMLDoc;
	
// THIS WONT WORK ON NETSCAPE, RIGHT??
	var lightbox_name = document.lightbox_select_form.lightbox_name.value;
//alert ("lightbox select custom "+lightbox_name);
	var xml_path = BASE_URL+lightbox_name+".xml";

	if ((loadedLightBoxXMLDoc = XMLLoadFile (xml_path)) == null) {
		return false;
	}
	lightBoxXMLDoc = loadedLightBoxXMLDoc;
	
	// Save the XML to the user data area.
	lightbox_persist_save (lightBoxXMLDoc.documentElement.xml);
	
	// Draw the boxes.
	lightbox_draw ();
	return false;  // Supress further processing
}


function lightbox_persist_initialize (force_new)
{
	var loadedLightBoxXMLDoc;

//alert ("lightbox_persist_initialize");
	// If force_new, then just clear the lightbox
	if (!force_new) {
	// Try and load the peristent data. If it is there, just return
		if (lightbox_persist_load_cookie () == true) {
//alert ("using lightbox data from cookie");
			return;
		}
	}
//alert ("Set cookie from lightbox initial state");
	var xml_path = BASE_URL+"LightBoxInitialState.xml";

	if ((loadedLightBoxXMLDoc = XMLLoadFile (xml_path)) == null) {
		alert ("Could not load initial lightbox state");
		return;
	}
	lightBoxXMLDoc = loadedLightBoxXMLDoc;
//alert ("initialize with "+lightBoxXMLDoc.documentElement.xml);

	// Save the XML to the user data area.
	lightbox_persist_save (lightBoxXMLDoc.documentElement.xml);
}
	


function lightbox_persist_load_cookie ()
{
//alert ("lightbox_persist_load_cookie");
	var lightbox_cookie = get_cookie ("lightbox_cookie");
	if (lightbox_cookie == "") {
//alert ("no cookie available for lightbox");
		return false;
	}
//alert ("lightbox cookie XML is ["+lightbox_cookie+"]");
	if (window.XSLTProcessor) {
		lightBoxXMLDoc = document.implementation.createDocument("","",null);
  		lightBoxXMLDoc.async = false;
//		lightBoxXMLDoc.myLoadXML(lightbox_cookie); 

 		var domParser = new DOMParser();
  		var xmlDocument = domParser.parseFromString (lightbox_cookie,'application/xml');
// GET THE RIGHT CODE FOR ERROR CHECKING ON PARSING
// 		var parseError = checkForParseError (xmlDocument);
//		if (parseError.errorCode != 0) {
//			alert ("Population of DOM XML document with cookie failed.");
//		}
		lightBoxXMLDoc = xmlDocument;
//alert("imported XML from cookie");
//alert (lightBoxXMLDoc.xml)
	} else if (window.ActiveXObject) {
		lightBoxXMLDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
		lightBoxXMLDoc.async = false;
		var loadComplete = lightBoxXMLDoc.loadXML (lightbox_cookie);
		if (loadComplete == false) {
			alert ("Population of DOM XML document with cookie failed.");
		}
	}
	return true;
}


function lightbox_persist_save (XMLData)
{

//alert ("save data is "+XMLData);
	// Extend time of expiration of cookie.
	var expire = new Date();
	expire.setTime(expire.getTime() + EXPIRATION_EXTENSION * 24 * 60 * 60 * 1000);
	var tempData = XMLData + "; expires=" + expire.toUTCString()
	save_cookie("lightbox_cookie",tempData,"/");
}

function lightbox_left_arrow (image_number)
{
//alert ("left arrow");
	var xpath_string = "/LightBox/Image[@n='"+image_number+"']";
	var thisElement = lightBoxXMLDoc.selectSingleNode (xpath_string);
	if (thisElement.previousSibling == null) {
		alert ("At top of list");
		return;
	}
	thisElement.parentNode.insertBefore(thisElement, thisElement.previousSibling);

	// Save the XML to the user data area.
	lightbox_persist_save (lightBoxXMLDoc.documentElement.xml);
	
	// Draw the boxes again.
	lightbox_draw ();
}

function lightbox_up_arrow (image_number)
{
	var xpath_string = "/LightBox/Image[@n='"+image_number+"']";
//alert ("up arrow path "+xpath_string);
//alert (lightBoxXMLDoc.xml);
	var thisElement = lightBoxXMLDoc.selectSingleNode (xpath_string);
	// Need to have 4 previous nodes to be able to to a move up.
	var targetElement = thisElement;
	for (var i=0;i<4;i++) {
		targetElement = targetElement.previousSibling;
		// If we hit the beginning of the list, then there is not room to move the node.
		if (targetElement == null) {
			alert ("At top of list");
			return;
		}
	}
	thisElement.parentNode.insertBefore (thisElement, targetElement);

	// Save the XML to the user data area.
	lightbox_persist_save (lightBoxXMLDoc.documentElement.xml);
//alert ("Updated XML");
//alert (lightBoxXMLDoc.xml);
	
	// Draw the boxes again.
	lightbox_draw ();
}

function lightbox_down_arrow (image_number)
{
//alert ("down arrow at image "+image_number);
	var xpath_string = "/LightBox/Image[@n='"+image_number+"']";
	var thisElement = lightBoxXMLDoc.selectSingleNode (xpath_string);
	// Need to have 4 previous nodes to be able to to a move up.
	var targetElement = thisElement;
	for (var i=0;i<4;i++) {
		targetElement = targetElement.nextSibling;
		// If we hit the end of the list, then there is not room to move the node.
		if (targetElement == null) {
			alert ("At bottom of list");
			return;
		}
	}
	if (targetElement.nextSibling != null) {
		thisElement.parentNode.insertBefore (thisElement, targetElement.nextSibling);
	} else {
//alert ("Append to end of list");
		thisElement.parentNode.appendChild (thisElement);
	}
//alert ("moved before 4th item");
//thisElement.parentNode.insertBefore (thisElement.nextSibling, thisElement);

	// Save the XML to the user data area.
	lightbox_persist_save (lightBoxXMLDoc.documentElement.xml);
	
	// Draw the boxes again.
	lightbox_draw ();
}


function lightbox_right_arrow (image_number)
{
//alert ("right arrow");
	var xpath_string = "/LightBox/Image[@n='"+image_number+"']";
	var thisElement = lightBoxXMLDoc.selectSingleNode (xpath_string);
	if (thisElement.nextSibling == null) {
		alert ("At bottom of list");
		return;
	}
	thisElement.parentNode.insertBefore (thisElement.nextSibling, thisElement);

	// Save the XML to the user data area.
	lightbox_persist_save (lightBoxXMLDoc.documentElement.xml);
	
	// Draw the boxes again.
	lightbox_draw ();
}

// Add support to Firefox for MS functions like myLoadXML, xml property, selectNodes, selectSingleNode
if (window.XSLTProcessor) {

// THIS ONE IS UNUSED, BUT WORKS.
	Document.prototype.myLoadXML = function(strXML) {
		var objDOMParser = new DOMParser();
		var objDoc = objDOMParser.parseFromString(strXML, "text/xml");  
		// Remove nodes from document
		while (this.hasChildNodes()) {
		    this.removeChild(this.lastChild);
		}
		//add the nodes from the new document
		for (var i=0; i < objDoc.childNodes.length; i++) {            
		    //import the node
		    var objImportedNode = this.importNode(objDoc.childNodes[i], true);            
		    //append the child to the current document
		    this.appendChild(objImportedNode);
		}
	}
    /**
    * add the xml attribute to the node class
    * Everytime the .xml attribute is called it will be transformed to string
    */
    Node.prototype.__defineGetter__("xml", function () {
        var oSerializer = new XMLSerializer();
        return oSerializer.serializeToString(this, "text/xml");
 	});

	Document.prototype.selectNodes = function ($_XPath, $_xNode) {
		if(!$_xNode) {
			$_xNode = this;
		}
		oNSResolver = this.createNSResolver (this.documentElement);
		$_aItems = this.evaluate($_XPath, $_xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		$_aResult = [];
		for (var i=0;i<$_aItems.snapshotLength; i++) {
			$_aResult[i] =  $_aItems.snapshotItem(i);
		}
		return $_aResult;
	}
	
	Document.prototype.selectSingleNode = function($_XPath, $_xNode) {
		if (!$_xNode) {
			$_xNode = this;
		}
		$_xItems = this.selectNodes ($_XPath, $_xNode);
		return ($_xItems.length > 0)? $_xItems[0] : null ;
	}
	Element.prototype.selectNodes = function ($_XPath) {
		return this.ownerDocument.selectNodes($_XPath, this);
	}
	
	Element.prototype.selectSingleNode = function ($_XPath) {
		return this.ownerDocument.selectSingleNode($_XPath, this);
	}

}
