//	alert("Module historyLib.js [v20020420.1] has loaded.");
//  <!-- to use this module, copy following (commented) line to your html file -->
//	<!-- <script src="/{server_alias}/includes/historyLib.js"></script> -->

	/* <!--
	name:	historyLib.js
	dir:	\htdocs\includes
	by: 	OpenAsia Solutions Pte Ltd
	func:	provides javascript functions for node group management, eg- history lists
	rev: 	20020425, wmc, created this module
			20020401, wmc, fixed uninitialized history object bug in 'dropPageFromHistory'
			20020529, wmc, modified 'url' keyword (changed to pageurl), to avoid conflicts with iPlanet server
	--------------------------------------------------------------------------------
	Following are the common client-side functions defined in this module.
	--------------------------------------------------------------------------------

	History List Functions 
	````````````````````````````````
	addPageToHistory		adds a page to the current history, which is created if req'd
	removePageFromHistory	removes a page, if one exists, from the current history
	getHistoryList			returns history as an HTML string
	gotoPageInHistory		find page in the history list, and drop pages not needed
	
	Generic Node Group Functions 
	````````````````````````````````
	addNodeGroup;			adds a new node group
	addNode;				adds a node to the indicated group
	deleteNode;				removes a node from the indicated group
	viewNodeGroup;			displays attributes of the indicated node group (for debugging)
	countNodes;				returns count of nodes in the indicated node group
	
	--> */

var historyLib = this;
	
	// define global variables 
var BOOLEAN_TRUE = -1;
var HISTORY = null;				// pointer to a NodeGroup object
var BASE_URL = "/servlet/Framer?template=";

	// add a new page to history, and create history if req'd; invoke as 'addPageToHistory()'
function addPageToHistory (pagename, pageurl, targetframe) {
	if (pagename != null && pageurl != null && targetframe != null) {
		if (this.HISTORY == null)
			this.HISTORY = addNodeGroup('history');
					// only add to history if the current node doesn't have the same url
		if (this.HISTORY.last_node == null || this.HISTORY.last_node.PAGEURL != pageurl) {
			var node = this.HISTORY.addNode();
			node.pagename = pagename;				// add property for the displayed page name
			node.PAGEURL = pageurl;					// add property for URL of the page
			node.targetframe = targetframe.name;	// add property for targetframe to display page
		}
	} else {
		alert("Function 'addPageToHistory' called with missing parameter.");
	}
}

	// returns history as an HTML string; invoke as 'getHistoryList()'
function getHistoryList () {
	var str = '';
	if (this.HISTORY != null) {
		var frame = self;					// get the frame that contains this library
		var libFrame = frame.name;			// assemble frame name that includes full path
		while (frame != top) {
			frame = frame.parent;
			libFrame = (frame == top ? 'top.' + libFrame : frame.name + '.' + libFrame);
		}
		var node = this.HISTORY.first_node;	// start at first node
		while (node != null) {
			if (node.PAGEURL && node.pagename)	// assemble list of pages in the history
				str += "<a href=\"javascript:" + libFrame + ".gotoPageInHistory('" + 
				  node.PAGEURL + "');\">" + node.pagename + "</a> > ";
			node = node.childNode;
		}
		if (str.length >= 3) 
			str = str.substr(0, str.length - 3); 
	}
	return (str);
}

	// find page in the history list, and drop pages not needed; invoke as 'gotoPageInHistory()'
	// if url is not specified, proceed to last page in history, whatevery the url
function gotoPageInHistory (pageurl) {
	var i_url = "";	// 'i_url' is a keyword iPlanet server needs to prepend the url with 'HTTPS', for those outside intranet
	if (this.HISTORY != null && this.HISTORY.last_node != null) {
		var node = this.HISTORY.last_node;			// start at the last node
		if (pageurl != null) {
			while (node != null && node.PAGEURL != pageurl) {
				dropPageFromHistory();				// remove nodes that don't match URL
				node = this.HISTORY.last_node;
			}
		} else {
			if (node != null)
				var pageurl = node.PAGEURL;
		}
		if (node != null) {
			var targetframe = null;
			if (eval("parent." + node.targetframe) != null)
				targetframe = eval("parent." + node.targetframe);
			else if (eval("parent.parent." + node.targetframe) != null)
				targetframe = eval("parent.parent." + node.targetframe);
			else if (eval("parent.parent.parent." + node.targetframe) != null)
				targetframe = eval("parent.parent.parent." + node.targetframe);
			if (targetframe != null) {
				dropPageFromHistory();				// remove node for the requested page
				if (pageurl.indexOf(BASE_URL) < 0)
					pageurl = BASE_URL + pageurl;				// if baseurl not included, add prefix
				i_url = pageurl;								// prepend it now!
				targetframe.document.location = i_url;			// fetch document from history
			} else {
				alert("Function 'gotoPageInHistory' called with invalid targetframe.");
			}
		}
	} else {
		alert("Function 'gotoPageInHistory' called without target, try 'browser back'.");
	}
}

	// remove last page in history, optional count; invoke as 'dropPageFromHistory()'
function dropPageFromHistory (count) {	
	if (this.HISTORY != null) {
		if (count == null) count = 1;
		for (var i = 0; i < count; i++)
			this.HISTORY.deleteNode();
	}
}

///////////////////// Begin Generic NodeGroup Objects and Methods /////////////////////

	// define 'NodeGrop' object, representing a doubly-linked list of 'Node' objects
function NodeGroup (group_id) { 
	this.group_id = group_id;
	this.first_node = null; 				// initialized to null before 1st node added
	this.last_node = null; 					// initialized to null before 1st node added

		// NodeGroup methods
	this.addNode = addNode;
	this.deleteNode = deleteNode;						
	this.viewNodeGroup = viewNodeGroup;
	this.countNodes = countNodes;
}

	// define 'Node' object as a single element in a doubly-linked list
function Node (NodeGroup, parentNode) { 
	this.NodeGroup = NodeGroup;	
	this.parentNode = parentNode;
	this.childNode = null;					// initialized to null before next node added
}

	// create a new group of nodes; invoke as 'addNodeGroup()'
function addNodeGroup (group_id) {
	if (group_id != null) 
		return (new NodeGroup(group_id));
	else
		alert("Function 'addNodeGroupObj' called with missing parameter.");
}

	// add a node to this group; invoke as 'group_id.addNode()'
function addNode () {
	var node = null;
	if (this.group_id != null) {
		node = new Node(this, this.last_node);
		if (node.parentNode == null) 
			this.first_node = node;
		else 
			node.parentNode.childNode = node;
		this.last_node = node;
	} else {
		alert("Function 'addNode' called without object reference.");
	}
	return (node);
}		

	// remove a node from this group; invoke as 'group_id.deleteNode()'
function deleteNode () {
	if (this.group_id != null) {
		if (this.last_node != null) {
			var node = this.last_node;
			if (node.parentNode == null) {
				this.first_node = null;
				this.last_node = null;
			} else {
				node.parentNode.childNode = null;
				this.last_node = node.parentNode;
			}
			node = null;
		}
	} else {
		alert("Function 'deleteNode' called without object reference.");
	}
}

	// displays attributes of each node; invoke as 'group_id.viewNodeGroup()'
function viewNodeGroup () {
	if (this.group_id != null) {
		var str = '';
		var node_count = this.countNodes();
		str += "group id: " + this.group_id + "\n";
		str += "number of nodes: " + node_count + "\n";
		var node = this.first_node;
		for (var n = 1; n < node_count + 1; n++) {
			str += "node " + n + " contains:\n" ;
			for (var property in node)
				str += "\t" + property + ": " + node[property] + "\n";
			node = node.childNode;
		}
		alert("Group Object\n````````````````````````````````````\n" + str);
	} else {
		alert("Function 'viewNodeGroup' called without object reference.");
	}
}	

	// returns count of nodes in this group; invoke as 'group_id.countNodes()'
function countNodes () {
	var count = 0;
	if (this.group_id != null) {
		var node = this.first_node;
		while (node != null) {
			count++;
			node = node.childNode;
		}
	} else {
		alert("Function 'countNodes' called without object reference.");
	}
	return (count);
}	

///////////////////// End Generic NodeGroup Objects and Methods /////////////////////

