/* ----------------------------------------------------------------------
 * js/ui.php : javascript-based user interface controls
 * ----------------------------------------------------------------------
 * OpenCollection
 * Open-source collections management software
 * ----------------------------------------------------------------------
 *
 * Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
 * Copyright 2004 - 2007 Whirl-i-Gig
 *
 * For more information visit http://www.opencollection.org
 *
 * This program is free software; you may redistribute it and/or modify it under
 * the terms of the provided license as published by Whirl-i-Gig
 *
 * OpenCollection is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTIES whatsoever, including any implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * This source code is free and modifiable under the terms of 
 * GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See
 * the "license.txt" file for details, or visit the OpenCollection web site at
 * http://www.opencollection.org
 *
 * ----------------------------------------------------------------------
 */
// ------------------------------------------------------------------------------
//
// Hierarchy browser class definition
//
// ------------------------------------------------------------------------------
// Constructor
function hierScroller(name, parent_id, dataUrl, options) {
	this.scrollerName = name;
	this.dataUrl = dataUrl;
	
	this.moveItem = undefined;
	
	this.levelLists = new Array();
	
	if (!options) { options = {}; }
	this.options = options;
	if(parent_id > 0) {
		this.hierLoadAllLevels(parent_id, dataUrl);
	} else {
		this.hierLoadLevel(parent_id, 0, dataUrl);
	}
}
// ------------------------------------------------------------------------------
hierScroller.prototype.hierLoadAllLevels = function(parent_id, dataUrl) {
	this.setupHierLevel(0);

	var o = this;
	var processLevelList = function(resp) {
		o.hierProcessAllLevels(resp);
	}
    /*
	new Ajax.Request(
		dataUrl + parent_id + '&all=1', 
		{onSuccess:processLevelList, onFailure:this.hierHandleError}
	);
    */
    jQuery.ajax({
       type : "GET",
       url: dataUrl +parent_id + '&all=1',
       dataType: "xml",
       success : processLevelList,
       error: this.heirHandleError
    });
}
// ------------------------------------------------------------------------------
hierScroller.prototype.hierProcessAllLevels = function(xmlData) {
	var i, levels, l;
	for(i=0; i < xmlData.childNodes.length; i++) {
		if (xmlData.childNodes[i].nodeName == 'items') {
			levels = xmlData.childNodes[i];
			break;
		}
	}
	if (!levels) {  return; } // alert('Error: No item list in server response!'); }

	l = 0;
	for(i=0; i < levels.childNodes.length; i++) {
		var levelContainer = levels.childNodes[i];
		switch(levelContainer.nodeType) {
			case 1:			// element
				var level = levelContainer.getAttribute('level');
				this.setupHierLevel(level);
				this.processHierLevel(level, levelContainer, levelContainer.getAttribute('selected_id'), false);
				l++;
				break;
		}
	}
	
	// Scroll hierarchy viewer to current level after short delay
	// (Safari won't scroll without the delay)
	var o = this;
	var f = function(p) {
        jQuery("#"+o.scrollerName).attr('scrollLeft', 250*l);
		this.stop();
	}
	var pe = new PeriodicalExecuter(f, 0.2);
}
// ------------------------------------------------------------------------------
hierScroller.prototype.hierLoadLevel = function (parent_id, level, dataUrl) {
	if (!level) { level = 0; }
	
	this.setupHierLevel(level);

	var o = this;
	var processCompleteLevel = function(resp) {
		o.processHierLevel(level, resp, undefined, true);
	}
    /*
	new Ajax.Request(
		dataUrl + parent_id, 
		{onSuccess:processCompleteLevel, onFailure:this.hierHandleError}
	);
    */
    jQuery.ajax({
       type : "GET",
       url: dataUrl +parent_id + '&all=1',
       dataType: "xml",
       success : processLevelList,
       error: this.heirHandleError
    });

	
}
// ------------------------------------------------------------------------------
hierScroller.prototype.setupHierLevel = function(level) {	
	var levelDiv;
	// Remove any levels *after* the one we're populating
	var l = level;
	while(jQuery('#hierScroller_' + this.scrollerName + '_' + l)) {
		levelDiv = jQuery('#hierScroller_' + this.scrollerName + '_' + l);
		if (levelDiv) { levelDiv.parentNode.removeChild(levelDiv); }
		this.levelLists[l] = undefined;
		l++;
	}
	
	// Create div to enclose new level
	var newLevelDiv = document.createElement('div');
	newLevelDiv.className = 'hierScrollerLevel';
	newLevelDiv.style.top = '0px';
	newLevelDiv.style.left = (250 * level) + "px";
	newLevelDiv.id = 'hierScroller_' + this.scrollerName + '_' + level;
	
	// Create new ul to display list of items
	var newLevelList = document.createElement('ul');
	newLevelDiv.className = 'hierScrollerLevel';
	
	newLevelList.id = 'hierScroller_' + this.scrollerName + '_list_' + level;
	newLevelList.className = 'hierScrollerLevel';
	
	newLevelDiv.appendChild(newLevelList);
	jQuery("#"+this.scrollerName).append(newLevelDiv);
	
	if (this.options.indicator) {
		var indicator = document.createElement('IMG');
		indicator.src = this.options.indicator;
		indicator.style.position = 'absolute';
		indicator.style.left = '50%';
		indicator.style.top = '50%';
		newLevelDiv.appendChild(indicator);
	}

	newLevelDiv.style.display = 'block';
	
	this.levelLists[level] = newLevelDiv;
	return newLevelDiv;
}
// ------------------------------------------------------------------------------
hierScroller.prototype.processHierLevel = function(level, resp, selected_id, isAjax) {	
	if (!level) { level = 0; }

	var levelDiv = jQuery('#hierScroller_' + this.scrollerName + '_' + level);
	var levelList = jQuery('#hierScroller_' + this.scrollerName + '_list_' + level);
	
	var i, items;
	if (isAjax) {
		for(i=0; i < resp.childNodes.length; i++) {
			if (resp.childNodes[i].nodeName == 'items') {
				items = resp.childNodes[i];
				break;
			}
		}
		if (!items) { return; } //alert('Error: No item list in server response!'); }
	} else {
		items = resp;
	}
	
	var o = this;
	for(i=0; i < items.childNodes.length; i++) {
		var item = items.childNodes[i];
	
		switch(item.nodeType) {
			case 1:			// element
				var name = item.getAttribute('name');
				
				if (item.getAttribute('childCount') > 0) {
					name += ' (' + item.getAttribute('childCount') + ') >';
				}
				var id = item.getAttribute('id');
				
				var a = document.createElement('A');
				a.href='#';
				
				if (this.options.editUrl) {
					var editUrl = this.options.editUrl;
					a.ondblclick= function() { 
						var item_id = this.parentNode.id.split('_').pop();
						document.location = editUrl + item_id;
					};
				}
				
				a.onclick=function() {
					var item_id = this.parentNode.id.split('_').pop();
					o.hierLoadLevel(item_id, (parseInt(level) + 1), o.dataUrl);
					
					var itemList = this.parentNode.parentNode.childNodes;
					var j;
					for (j=0; j < itemList.length; j++) {
						var item = itemList.item(j);
						if (item.nodeType == 1) {
							if (item.nodeName == 'LI') {
								var a_nodes = item.getElementsByTagName('A');
								var k;
								for(k=1; k < a_nodes.length; k++) {		// k=1 to skip the first a tag which is the "move" link
									var a_node = a_nodes[k];
									a_node.className = 'hierScrollerItem';
								}
							}
						}
					}
					this.className = 'hierScrollerSelectedItem';
					return false;
				}
				
				var li = document.createElement('LI');
				
				li.className = 'hierScrollerItem';
				li.id = 'hierScroller_' + this.scrollerName + '_item_'  + id;
				a.appendChild(document.createTextNode(name));
				
				var item_id = id.split('_').pop();
				if (item_id == selected_id) {
					a.className = 'hierScrollerSelectedItem';
				} else {
					a.className = 'hierScrollerItem';
				}
				
				if (this.options.allowMoving) {
					if (this.moveItem) {
						var move_div = document.createElement('DIV');
						move_div.className = 'hierScrollerMoveItem';
						var move_a = document.createElement('A');
						move_a.className = 'hierScrollerMoveItem';
						move_a.appendChild(document.createTextNode('< put'));
						move_a.href = '#';
						var o = this;
						move_a.item_id = item_id;
						move_a.item_name = item.getAttribute('name');
						move_a.onclick = function() {
							o.doMove(this);
						}
					} else {
						var move_div = document.createElement('DIV');
						move_div.className = 'hierScrollerMoveItem';
						var move_a = document.createElement('A');
						move_a.className = 'hierScrollerMoveItem';
						move_a.href = '#';
							move_a.item_id = item_id;
							move_a.item_name = item.getAttribute('name');
						
						if (level > 0) {
							move_a.appendChild(document.createTextNode('move >'));
							var o = this;
							move_a.onclick = function() {
								o.setMoveMode(this);
							}
						} else {
							move_a.appendChild(document.createTextNode('_'));
						}
					}
					move_div.appendChild(move_a);
					li.appendChild(move_div);
				}
				li.appendChild(a);
				
				levelList.appendChild(li);
				
				break;
			case 3:			//text
				// noop
				break;
		}
	}
	
	// Add 'Add item' button to level
	var a = document.createElement('A');
	if (items.getAttribute('parent_id') > 0) {
		if (this.options.addUrl) {
			a.href= this.options.addUrl + items.getAttribute('parent_id');
		} else {
			a.href = '#';
		}
		a.className = 'hierScrollerItem';
		
		var li = document.createElement('LI');
		li.appendChild(a);
		li.className = 'hierScrollerAddItem';
		li.id = 'hierScroller_' + this.scrollerName + '_add_to_level_' + level;
		a.appendChild(document.createTextNode('Add item'));
		levelList.appendChild(li);
	}
	
	// Hide loading indicator graphic
	if (this.options.indicator) {
		levelDiv.lastChild.style.display = 'none';
	}
	
	
	// Scroll hierarchy viewer to current level
	jQuery("#"+this.scrollerName).scrollLeft = (250 * level);
}

// ------------------------------------------------------------------------------
hierScroller.prototype.setMoveMode = function(moveItem) {
	//alert('moving ' + name);
	if (this.options.status) {
		jQuery("#"+this.options.status).html('Choose an item to move ' + moveItem.item_name + ' under.');
	}
	this.moveItem = moveItem;
	this.setMoveButtons('put');
}
// ------------------------------------------------------------------------------
hierScroller.prototype.setMoveButtons = function(m) {
	var i, j, k;
	for(i=0; i < this.levelLists.length; i++) {
		if (this.levelLists[i] == undefined) { continue; }
		for(j=0; j < this.levelLists[i].childNodes.length; j++) {
			var node = this.levelLists[i].childNodes[j];
			if (node.nodeName == 'UL') {
				var itemList = node;
				for(k=0; k < itemList.childNodes.length; k++) {
					var itemDiv = itemList.childNodes[k].firstChild;
					if (itemDiv.firstChild.nodeName == 'A') {
						var move_a = itemDiv.firstChild;
						if (m == 'put') {
							var o = this;
							move_a.onclick = function() {
								o.doMove(this);
							}
							move_a.firstChild.nodeValue = '< put';
						} else {
							
							var o = this;
							move_a.onclick = function() {
								o.setMoveMode(this);
							}
							move_a.firstChild.nodeValue = '< move';
						}
					}
				}
			}
		}
	}
}
// ------------------------------------------------------------------------------
hierScroller.prototype.clearMoveMode = function() {
	if (this.options.status) {
		jQuery("#"+this.options.status).html("");
	}
	this.setMoveButtons('move');
	this.moveItem = undefined;
}
// ------------------------------------------------------------------------------
hierScroller.prototype.doMove = function(destItem) {
	if (destItem.item_id != this.moveItem.item_id) {
		//alert('Put item id='+ this.moveItem.item_id + ' (' + this.moveItem.item_name + ') under ' + destItem.item_id + ' (' + destItem.item_name + ')');
		
		this.setMoveButtons('move');
		// this.moveItem is the move a element itself
		var o = this;
		var item_id = destItem.item_id;
		var processLevelList = function(resp) {
			var i, messages; 
			for(i=0; i < resp.childNodes.length; i++) {
				if (resp.childNodes[i].nodeName == 'wstransaction') {
					messages = resp.childNodes[i].childNodes;
					break;
				}
			}
			if (!messages) { alert('Error: No item list in server response!'); }
			
			var statusMessage = '';
			var success = false;
			
			for(i=0; i < messages.length; i++) {
				if (messages[i].nodeType == 1) {
					if (messages[i].getAttribute('code') == 0) {
						statusMessage = messages[i].getAttribute('message');
						success = true;
						break;
					} else {
						statusMessage += messages[i].getAttribute('message') + '<br/>';
					}
				}
			}
			o.clearMoveMode();
			if (o.options.status) {
				jQuery("#"+o.options.status).html(statusMessage);
			}
			if (success) {
				o.hierLoadAllLevels(item_id, o.dataUrl);
			}
		}
		/*
		new Ajax.Request(
			this.dataUrl + this.moveItem.item_id + '&haction=move&move_to_id=' + destItem.item_id, 
			{onSuccess:processLevelList, onFailure:this.hierHandleError}
		);
        */
        jQuery.ajax({
            type: "GET",
            url:this.dataUrl + this.moveItem.item_id + '&haction=move&move_to_id=' + destItem.item_id,
            success: processLevelList,
            error: this.hierHandleError
        });
	}
}
// ------------------------------------------------------------------------------
hierScroller.prototype.hierHandleError = function(req) {
	alert('XMLHTTP Error: ' + req.statusText + ' (' + req.status + ')');
}
// ------------------------------------------------------------------------------
//
// Workspace (aka "Filespace") user interface functions
//
// ------------------------------------------------------------------------------

function showWorkspaceBrowser(x, y) {
	e = document.getElementById("workspace_browser");	
	e.style.left = x+"px";
	e.style.top = y+"px";
	e.style.display = "inline";
}
// ------------------------------------------------------------------------------
function hideWorkspaceBrowser() {
	e = document.getElementById("workspace_browser");
	
	e.style.display = "none";
}
// ------------------------------------------------------------------------------
function setMedia(item_id, previewSrc, w, h, labelText) {
	e = document.getElementById("workspace_item_id");
	e.value = item_id;
	img = document.getElementById("workspace_selected_image");
	img.src = previewSrc;
	img.width = w;
	img.height = h;
	
	label = document.getElementById("workspace_item_preview_label");
	label.innerHTML = labelText;
	
	title = document.getElementById("workspace_item_preview_title");
	title.innerHTML = "Media to upload:";
}
// ------------------------------------------------------------------------------
function clearMedia() {
	e = document.getElementById("workspace_item_id");
	e.value = "";
	img = document.getElementById("workspace_selected_image");
	img.src = "graphics/spacer.gif";
	img.width = 1;
	img.height = 1;
	
	label = document.getElementById("workspace_item_preview_label");
	label.innerHTML = "";
	
	title = document.getElementById("workspace_item_preview_title");
	title.innerHTML = "";
}
// ------------------------------------------------------------------------------
//
// Javascript/CSS dropdown menu; used in administrative screens and for 
// "most recently" edited list
//
// Taken from Plone v2. Thanks guys!
//
// ------------------------------------------------------------------------------
// Code to determine the browser and version.

// ------------------------------------------------------------------------------
function Browser() {
    var ua, s, i;
    
    this.isIE = false; // Internet Explorer
    this.isNS = false; // Netscape
    this.version = null;
    
    ua = navigator.userAgent;
    
    s = "MSIE";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isIE = true;
        this.version = parseFloat(ua.substr(i + s.length));
        return;
    }  
    s = "Netscape6/";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isNS = true;
        this.version = parseFloat(ua.substr(i + s.length));
        return;
    }
    
    // Treat any other "Gecko" browser as NS 6.1.
    
    s = "Gecko";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isNS = true;
        this.version = 6.1;
        return;
    }
}
var browser = new Browser();

// ------------------------------------------------------------------------------
// - jQuery implementation of the drop-down menu
function listMenu(menuId){
    // - variable for the menu
    $menu = $(document.getElementById(menuId));

    $menu.css("visibility","visible")
    .show()
    .mouseleave(function(){
        $(document).mousedown(function(){
            $(document).unbind("mousedown");
            $menu.hide();
        });
    })
    .mouseenter(function(){
       $(document).unbind("mousedown");
    });

    $(document).mousedown(function(){
        $(document).unbind("mousedown");
        $menu.hide();
    });

    return false;
}
String.prototype.unescapeHTML = function(){
	return this.replace(/<\/?[^>]+>/gi, "").replace(/\&amp\;/mg,"&").replace(/\&nbsp\;/mg," ").replace(/\&gt\;/mg,">").replace(/\&lt\;/mg,"<").replace(/\&quot\;/mg,"\"");
}

// ------------------------------------------------------------------------------
// General utility functions.

    function getContainerWith(node, tagName, className) {
		
		// Starting with the given node, find the nearest containing element
		// with the specified tag name and style class.
		
		while (node != null) {
			if (node.tagName != null && node.tagName == tagName && hasClassName(node, className)){
				return node;
		}
		node = node.parentNode;
		}
		return node;
	}

// ------------------------------------------------------------------------------
    function hasClassName(el, name) {
		
		var i, list;
		
		// Return true if the given element currently has the given class
		// name.
		
		list = el.className.split(" ");
		for (i = 0; i < list.length; i++)
		if (list[i] == name){
			return true;
			}
		return false;
	}
// ------------------------------------------------------------------------------
	function removeClassName(el, name) {
		
		var i, curList, newList;
		
		if (el.className == null){
			return;
			}
		// Remove the given class name from the element's className property.
		
		newList = new Array();
		curList = el.className.split(" ");
		for (i = 0; i < curList.length; i++){
			if (curList[i] != name){
				newList.push(curList[i]);
				el.className = newList.join(" ");
			}
		}
	}
// ------------------------------------------------------------------------------
	function getPageOffsetLeft(el) {
	
	var x;
		
		// Return the x coordinate of an element relative to the page.
		
		x = el.offsetLeft;
		if (el.offsetParent != null)
			x += getPageOffsetLeft(el.offsetParent);
		
		return x;
	}
// ------------------------------------------------------------------------------
	function getPageOffsetTop(el) {
		
		var y;
		
		// Return the x coordinate of an element relative to the page.
		
		y = el.offsetTop;
		if (el.offsetParent != null){
			y += getPageOffsetTop(el.offsetParent);
		}
		return y;
	}

// ------------------------------------------------------------------------------
//
// Utilities
//
// ------------------------------------------------------------------------------
// Simple Javascript pop-up window function
// ------------------------------------------------------------------------------
function OpenWindow(url,name,width,height,style) {
	browsername=navigator.appName;
	
	var styledesc;
	switch(style) {
		case 'minimal':
			styledesc = ',directories=no,location=no,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no';
			break;
		default:
			styledesc = ',directories=no,location=yes,menubar=yes,resizable=yes,scrollbars=yes,status=no,toolbar=no';
			break;
	}
	
	popupWin = window.open(url, name, 'width=' + width + ',height=' + height + styledesc);
	
	if (popupWin.opener==null) popupWin.opener = window;
	
	popupWin.moveTo(0,0);
	popupWin.focus();
}
// ------------------------------------------------------------------------------
function setSplitHierarchicalSelect(oSelect, aTLID) {
	oSelect.options.length = 0;
	for(i=0;i<aTLID.length;i++) {
		oSelect.options[i] = aTLID[i];
	}
}
// ------------------------------------------------------------------------------
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}
// ------------------------------------------------------------------------------