/*
 * iKnowBase Dimension Navigator
 *
 * Copyright (c) 2007 e-vita as
 *
 * $Id: $
 */



// Constructor
function ikbDimensionNavigator(options) {
	this.init (options);
}

// Class prototype
ikbDimensionNavigator.prototype = {

	// Member variables
	currentNodeId: "",

	init: function(options) {
		this.config = {};
		this.setOptions(options);
	},

	setOptions: function (options) {
		jQuery.extend(this.config, options);
	},
	
	getOptions: function () {
		return this.config;
	},

	navClickHandler: function (e) {

		// http://www.quirksmode.org/js/events_properties.html
   		// identify the item clicked, due to MSIE non-compliance
   		// W3C/Netscape says: the target. No, says Microsoft, the srcElement.
   		// Both properties return the HTML element the event took place on.
		// The last two lines of code are especially for Safari. If an event takes place
		// on an element that contains text, this text node, and not the element, becomes the target
		// of the event. Therefore we check if the target's nodeType is 3, a text node. If it is we
		// move to its parent node, the HTML element.
		var target;
		if (e.srcElement) target = e.srcElement;
		else if (e.target) target = e.target;
		if (target.nodeType == 3) // defeat Safari bug
			target = target.parentNode;

		var node = jQuery(target);

		if (node.is("img.t_imgs"))
		{
			// An expand/collaps image (class=t_imgs)
			this.expandCollapseNode (target.id.substring(2));
		} else {
			node = node.closest(".t_head, .t_leaf");
			if (node.length > 0 && ! node.is(".t_not_selectable")) {
				this.clickNode (node[0].id.substring(2));
			} 
		}
	},

	clickNode: function (dim) {
		this.setCurrentNode (dim);
		this.clickDimensionCallback (dim);
	},

	clickDimensionCallback: function (dim) {

		/* Dimension -1 is the first dimension */
		if (dim < 0) {
			var node = jQuery("#" + this.config.treeID + " div:first");
			dim = node.attr("id").substring(2);
		}

        /* If there is a user-defined onClick event handler */
        if (this.config.onClick) {
			var node = jQuery("#" + this.config.treeID + " #L-" + dim);
			return this.config.onClick.call (this.config, dim, node.text());
        }

		/* If there is a user-defined function (iKnowBase 5.0 and earlier)*/
		if (window.navClickDimensionCallback) {
			var node = jQuery("#" + this.config.treeID + " #L-" + dim);
			return navClickDimensionCallback (this.config, dim, node.text());
		}

		/* If target is defined go to target */
		if (this.config.targetGuid) {
			var cfg = this.config;
			return iKnowBase.PageEngine.goTarget ({
				guid: cfg.targetGuid, 
				data: [ dim, cfg.urlParameters.editorname, '', cfg.urlParameters.cbFunction, 
				      cfg.urlParameters.cbClosure, cfg.maxCount, cfg.urlParameters.mode]
			});
		}


		/* No target */
		// remove leading whitespace
		var node = jQuery("#" + this.config.treeID + " #L-" + dim);
		var text = jQuery.trim(node.text());

		if (this.config.maxCount <= 1)
		{
			var runThis = "parent.opener." + this.config.urlParameters.cbFunction 
				+ "(parent, this.config.urlParameters.cbClosure, [dim], [text], new Array());";
			eval(runThis);
		}
		else
		{
			// Multiselect; this.config.maxCount > 1
			var numInList = jQuery("#selectlist option").length;
			if (numInList < this.config.maxCount)
			{
				if (! checkIfElementInList(jQuery("#selectlist")[0], text, dim))
				{
					listAddElement(jQuery("#selectlist")[0], text, dim);
				}
			}
			else
			{
				alert(this.config.msgMax);
			}
		}
	},

	listSelectCallback: function () {
		var list = jQuery('#selectlist')[0];
		var list_ids = new Array();
		var list_labels = new Array();

		for (var i=0; i<list.length; i++)
		{
			if (list[i].value.length == 0)
				continue;
			list_ids.push (list[i].value);
			list_labels.push (list[i].text);
		}

		var runThis = "parent.opener." + this.config.urlParameters.cbFunction + "(parent, this.config.urlParameters.cbClosure, list_ids, list_labels, []);";
		eval(runThis);
	},

	expandCollapseNode: function (dim) {
		var parentDiv = jQuery("#" + this.config.treeID + " #L-" + dim);
		var coll = jQuery("#" + this.config.treeID + " #C-" + dim);

		// Load from database, if required
		if (coll.is('.t_server'))
		{
			return this.navLoadChildren (coll, dim, 1);
		}
	
		if (coll.is('.t_closed'))
		{
			coll.removeClass('t_closed');
			jQuery("img.t_imgi", parentDiv).attr("src", this.config.imageurl + "mappe_apen.gif");
			jQuery("img.t_imgs", parentDiv).attr("src", this.config.imageurl + "minus.gif");
		}
		else
		{
			coll.addClass('t_closed');
			jQuery("img.t_imgi", parentDiv).attr("src", this.config.imageurl + "mappe_lukket.gif");
			jQuery("img.t_imgs", parentDiv).attr("src", this.config.imageurl + "pluss.gif");
		}
	},

	loadParams: function (opts) {
		var defParams = {
			mode:'LOADCHILDREN'
		};

		jQuery.extend (defParams, this.config.loadParams);
		jQuery.extend (defParams, opts);

		return defParams;
	},

	// Loads into the tree container
	navLoadTree: function (params) {
		var tree = jQuery("#" + this.config.treeID);

		var img = jQuery("<div><img src='/ressurs/evita/iKBDesktop/images/common/loading-16x16.gif' /></div>").insertBefore(tree);
		this.navLoad(tree, params, function() {
			img.remove();
		});
	},

	navLoadChildren: function (coll, dim, levels, cbComplete) {
		var parents = coll.parents(".t_coll");
		var parentDiv = jQuery("#" + this.config.treeID + " #L-" + dim);
		var imgi = jQuery("img.t_imgi", parentDiv);
		var imgs = jQuery("img.t_imgs", parentDiv);
		var imageurl = this.config.imageurl;

		var params = {
			ikbSubDimensionID:dim,
			expandLevels:levels,
			currLevel:parents.length + 1
		};

		imgs.attr("src", "/ressurs/evita/iKBDesktop/images/common/loading-16x16.gif");
		this.navLoad(coll, params, function() {
			imgi.attr("src", imageurl + "mappe_apen.gif");
			imgs.attr("src", imageurl + "minus.gif");
			coll.removeClass('t_server');
			if (cbComplete)
			    cbComplete();
		});
	},

	navLoad: function (self, params, cbComplete) {
		jQuery.ajax({
			url: this.config.dataurl,
			type: 'POST',
			contentType: "application/x-www-form-urlencoded; charset=utf-8",
			data: this.loadParams(params),
			error: function (xhr,message,ex) {
				iKnowBase.errorPopup ("Error loading dimensions: message=" + message + "; statusText=" + xhr.statusText);
			},
			complete: cbComplete,
			success: function (data) {
				self.html (data);
			}
		});
	},

	// Perform or reset a search (depending on searchString)
	doSearch: function () {
		var searchString = jQuery("#" + this.config.treeID + "_search").val();
		this.navLoadTree ({
			searchString: searchString,
			expandLevels: (searchString ? this.config.numLevels : this.config.expandLevels)
		});
	},

	// Expand tree by loading as much as possible
	expand: function () {
		this.navLoadTree ({
			expandLevels: this.config.numLevels	// Expand maximum
		});
	},

	// Collapse locally
	collapse: function () {
		var tree = jQuery("#" + this.config.treeID);
		jQuery("div.t_coll", tree).not(".t_coll_only").addClass("t_closed");
		jQuery("img.t_imgi", tree).attr("src", this.config.imageurl + "mappe_lukket.gif");
		jQuery("img.t_imgs", tree).attr("src", this.config.imageurl + "pluss.gif");
	},

	searchKey: function (e) {
		var code = e.keyCode ? e.keyCode : e.which;
		if (code == 13)
			this.doSearch();
	},

	setCurrentNode: function (id) {

		var tree = jQuery("#" + this.config.treeID);
		var oldN = jQuery("div.t_selected", tree);
		var newN = jQuery("#L-" + id, tree);

		// Remove old hightlighting
		oldN.removeClass ("t_selected");
		newN.addClass("t_selected");
	},
	
	deleteNode: function(dim, newCurrentNode) {
	    // alert ("Deleting node: #" + dim);
	    jQuery ("#" + this.config.treeID + " #L-" + dim + ", #" + this.config.treeID + " #C-" + dim).fadeOut().remove();
	    if (newCurrentNode)
		this.setCurrentNode(newCurrentNode);
	},
	
	addNode: function(dim, parent) {
	    // alert ("Adding  node: #" + dim + " under parent #" + parent);
	    var coll = jQuery("#" + this.config.treeID + " #C-" + parent);
	    if (coll.length == 0) {
		coll = jQuery ("<div id='C-" + parent + "' class='t_coll'></div>").insertAfter("#" + this.config.treeID + " #L-" + parent);
	    }
	    var tree = this;	// Because "this" is bound differently in the callback
	    this.navLoadChildren (coll, parent, 1, function() {
		tree.setCurrentNode(dim);
	    });
	},
	
	moveNode: function(dim, oldParent, newParent) {
	    // alert ("Moving node: #" + dim + " from parent #" + oldParent + " to parent #" + newParent);
	    this.deleteNode (dim);
	    this.addNode (dim, newParent);
	}
};

