// ajax

var Ajax = new Object();
Ajax.isUpdating = true;

Ajax.Request = function(method, url, formname, callback)
{
	var allElementList = eval('document.' + formname + '.elements');
	var l = allElementList.length;
	var qs = 'junk=';
	for (var i = 0; i < l; i++)
	{
		var element = allElementList[i]; //element is taken
		if (element.type == 'radio' || element.type == 'checkbox') {
			if (element.checked) {
				qs += '&' + element.name + '=' + escape(element.value)
			}
		} else {
			qs += '&' + element.name + '=' + escape(element.value)
		}
	}

	this.isUpdating = true;
	this.callbackMethod = callback;
	this.request = (window.XMLHttpRequest)? new XMLHttpRequest(): new ActiveXObject("MSXML2.XMLHTTP"); 
	this.request.onreadystatechange = function() { Ajax.checkReadyState(); };
	if (method == 'GET') 
	{
		this.request.open(method, url + '?' + qs, true);
		this.request.send(null);
	}
	if (method == 'POST')
	{
		this.request.open(method, url, true);
		//Send the proper header information along with the request
		this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this.request.setRequestHeader("Content-length", qs.length);
		this.request.setRequestHeader("Connection", "close");
		this.request.send(qs);
	}
}
	
Ajax.SimpleGET = function(url, callback)
{
	this.isUpdating = true;
	this.callbackMethod = callback;
	this.request = (window.XMLHttpRequest)? new XMLHttpRequest(): new ActiveXObject("MSXML2.XMLHTTP"); 
	this.request.onreadystatechange = function() { Ajax.checkReadyState(); };
	this.request.open('GET', url, true);
	this.request.send(null);
}

Ajax.checkReadyState = function(_id)
{
	switch(this.request.readyState)
	{
		case 1: break;
		case 2: break;
		case 3: break;
		case 4:
			this.isUpdating = false;
			this.callbackMethod(this.request.responseText);
	}
}

// validation

function Validator(frmname) {
  this.formobj=document.forms[frmname];
	if(!this.formobj)
	{
	  alert("BUG: could not get Form object "+frmname);
		return;
	}
	if(this.formobj.onsubmit) {
		this.formobj.old_onsubmit = this.formobj.onsubmit;
		this.formobj.onsubmit=null;
	} else {
		this.formobj.old_onsubmit = null;
	}
	this.formobj.onsubmit=form_submit_handler;
	this.addValidation = add_validation;
	this.setAddnlValidationFunction=set_addnl_vfunction;
	this.clearAllValidations = clear_all_validations;
}

function set_addnl_vfunction(functionname) {
	this.formobj.addnlvalidation = functionname;
}

function clear_all_validations() {
	for(var itr=0; itr < this.formobj.elements.length; itr++) {
		this.formobj.elements[itr].validationset = null;
	}
}

function form_submit_handler() {
	var isok = true;
	for (var itr=0;itr < this.elements.length;itr++) {
		if(this.elements[itr].validationset && !this.elements[itr].validationset.validate()) {
		  isok = false;
		}
	}
	if(this.addnlvalidation) {
		str =" var ret = "+this.addnlvalidation+"()";
		eval(str);
		if(!ret) isok = false;
	}
	return isok;
}

function add_validation(itemname,descriptor,errstr) {
	if(!this.formobj) {
	  alert("BUG: the form object is not set properly");
		return;
	}//if
	var itemobj = this.formobj[itemname];
	if(!itemobj) {
	  alert("BUG: Couldnot get the input object named: "+itemname);
		return;
	}
	if(!itemobj.validationset) {
	  itemobj.validationset = new ValidationSet(itemobj);
	}
	itemobj.validationset.add(descriptor,errstr);
}

function ValidationDesc(inputitem,desc,error) {
	this.desc = desc;
	this.error = error;
	this.itemobj = inputitem;
	this.validate = vdesc_validate;
}

function vdesc_validate() {
	if (!V2validateData(this.desc, this.itemobj, this.error)) {
		this.itemobj.focus();
		return false;
	}
	return true;
}

function ValidationSet(inputitem) {
	this.vSet = new Array();
	this.add = add_validationdesc;
	this.validate= vset_validate;
	this.itemobj = inputitem;
}

function add_validationdesc(desc,error) {
	this.vSet[this.vSet.length] = new ValidationDesc(this.itemobj,desc,error);
}

function vset_validate() {
	for (var itr=0; itr<this.vSet.length; itr++) {
		if(!this.vSet[itr].validate()) {
		   return false;
		}
	}
	return true;
}

function validateEmailv2(email) {
// a very simple email validation checking. 
// you can add more complex email checking if it helps 
	if(email.length <= 0) {
	  return true;
	}
	var splitted = email.match("^(.+)@(.+)$");
	if(splitted == null) return false;
	if(splitted[1] != null ) {
		var regexp_user=/^\"?[\w-_\.]*\"?$/;
		if(splitted[1].match(regexp_user) == null) return false;
	}
	if(splitted[2] != null) {
		var regexp_domain=/^[\w-\.]*\.[A-Za-z]{2,4}$/;
		if(splitted[2].match(regexp_domain) == null) {
			var regexp_ip =/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
			if(splitted[2].match(regexp_ip) == null) return false;
		}
		return true;
	}
	return false;
}
function V2validateData (strValidateStr, objValue, strError) { 
	var epos = strValidateStr.search("="); 
	var  command  = ""; 
	var  cmdvalue = ""; 
	if (epos >= 0) { 
		command  = strValidateStr.substring(0,epos); 
		cmdvalue = strValidateStr.substr(epos+1); 
	} else { 
		command = strValidateStr; 
	} 
	var isok = true;
	switch(command) 
	{ 
        case "req": 
        case "required": 
          {
			if(eval(objValue.value.length) == 0) isok = false;
			break;
          }
        case "maxlength": 
        case "maxlen": 
          { 
			if(eval(objValue.value.length) >  eval(cmdvalue)) isok = false;
			break; 
          }
        case "minlength":
        case "minlen":
		{ 
			if(eval(objValue.value.length) <  eval(cmdvalue)) isok = false;
			break; 
		}
        case "alnum": 
        case "alphanumeric": 
           { 
			var charpos = objValue.value.search("[^A-Za-z0-9]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) isok = false;
              break; 
           }
        case "num": 
        case "numeric": 
           { 
			var charpos = objValue.value.search("[^0-9]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) isok = false;
			break;
           }
        case "alnum_s": 
        case "alphanumeric_space": 
           { 
			var charpos = objValue.value.search("[^A-Za-z0-9\\s]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) isok = false;
			break; 
           }		   
        case "dec": 
        case "decimal": 
           { 
			var charpos = objValue.value.search("[^0-9\.]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) isok = false;
               break;               
           }
        case "alphabetic": 
        case "alpha": 
           { 
			var charpos = objValue.value.search("[^A-Za-z]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) isok = false;
			break; 
           }
        case "email": 
          { 
               if(!validateEmailv2(objValue.value)) isok = false;
			break; 
          }
        case "lt": 
        case "lessthan": 
          { 
			if(isNaN(objValue.value)) isok = false;
			if(eval(objValue.value) >= eval(cmdvalue)) isok = false;
			break; 
          }
        case "gt": 
        case "greaterthan": 
          { 
			if(isNaN(objValue.value)) isok = false;
			if(eval(objValue.value) <=  eval(cmdvalue)) isok = false;
			break; 
          }
        case "regexp": 
          { 
		 	if(objValue.value.length > 0) {
				if(!objValue.value.match(cmdvalue)) isok = false;
			}
			break; 
          }
        case "dontselect": 
          { 
		 	if(objValue.selectedIndex == null) isok = false;
		 	if(objValue.selectedIndex == eval(cmdvalue)) isok = false;
		 	break; 
          }
        case "checked": 
          {
			if(objValue.checked == 0) isok = false;
			break;
          }
        case "radioreq": 
          {
          	var cnt = -1;
			for (var i=objValue.length-1; i > -1; i--) {
			   if (objValue[i].checked) {cnt = i; i = -1;}
			}
			if (cnt == -1) isok = false;
			break;
          }
	}
	if (isok) {
		document.getElementById(strError).style.display = "none";
		return true;
	} else {
		document.getElementById(strError).style.display = "inline";
		return false; 
	}
}


//
// global variables
//
var objDiv = null;
var originalDivHTML = "";
var DivID = "";
var over = false;

// dynamically add a div to dim all the page
function buildDimmerDiv()
{
    document.write('<div id="dimmer" class="dimmer"></div>');
}

function displayFloatingDiv(divId, title) 
{
	DivID = divId;

	document.getElementById('dimmer').style.visibility = "visible";
//	if (originalDivHTML == "")
//	    originalDivHTML = document.getElementById(divId).innerHTML;
	
    // add to your div an header	
//	document.getElementById(divId).innerHTML = originalDivHTML;
	
	document.getElementById(divId).className = 'dimming';
	document.getElementById(divId).style.visibility = "visible";
}

function hiddenFloatingDiv(divId) 
{
//	document.getElementById(divId).innerHTML = originalDivHTML;
	document.getElementById(divId).style.visibility='hidden';
	document.getElementById('dimmer').style.visibility = 'hidden';
	
	DivID = "";
}

buildDimmerDiv();


// drag drop

var Coordinates = {
	ORIGIN : new Coordinate(0, 0),

	northwestPosition : function(element) {
		var x = parseInt(element.style.left);
		var y = parseInt(element.style.top);

		return new Coordinate(isNaN(x) ? 0 : x, isNaN(y) ? 0 : y);
	},

	southeastPosition : function(element) {
		return Coordinates.northwestPosition(element).plus(
				new Coordinate(element.offsetWidth, element.offsetHeight));
	},

	northwestOffset : function(element, isRecursive) {
		var offset = new Coordinate(element.offsetLeft, element.offsetTop);

		if (!isRecursive) return offset;

		var parent = element.offsetParent;
		while (parent) {
			offset = offset.plus(
					new Coordinate(parent.offsetLeft, parent.offsetTop));
			parent = parent.offsetParent;
		}
		return offset;
	},

	southeastOffset : function(element, isRecursive) {
		return Coordinates.northwestOffset(element, isRecursive).plus(
				new Coordinate(element.offsetWidth, element.offsetHeight));
	},

	fixEvent : function(event) {
		event.windowCoordinate = new Coordinate(event.clientX, event.clientY);
	}
};

function Coordinate(x, y) {
	this.x = x;
	this.y = y;
}

Coordinate.prototype.toString = function() {
	return "(" + this.x + "," + this.y + ")";
}

Coordinate.prototype.plus = function(that) {
	return new Coordinate(this.x + that.x, this.y + that.y);
}

Coordinate.prototype.minus = function(that) {
	return new Coordinate(this.x - that.x, this.y - that.y);
}

Coordinate.prototype.distance = function(that) {
	var deltaX = this.x - that.x;
	var deltaY = this.y - that.y;

	return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
}

Coordinate.prototype.max = function(that) {
	var x = Math.max(this.x, that.x);
	var y = Math.max(this.y, that.y);
	return new Coordinate(x, y);
}

Coordinate.prototype.constrain = function(min, max) {
	if (min.x > max.x || min.y > max.y) return this;

	var x = this.x;
	var y = this.y;

	if (min.x != null) x = Math.max(x, min.x);
	if (max.x != null) x = Math.min(x, max.x);
	if (min.y != null) y = Math.max(y, min.y);
	if (max.y != null) y = Math.min(y, max.y);

	return new Coordinate(x, y);
}

Coordinate.prototype.reposition = function(element) {
	element.style["top"] = this.y + "px";
	element.style["left"] = this.x + "px";
}

Coordinate.prototype.equals = function(that) {
	if (this == that) return true;
	if (!that || that == null) return false;

	return this.x == that.x && this.y == that.y;
}

// returns true of this point is inside specified box
Coordinate.prototype.inside = function(northwest, southeast) {
	if ((this.x >= northwest.x) && (this.x <= southeast.x) &&
		(this.y >= northwest.y) && (this.y <= southeast.y)) {
		
		return true;
	}
	return false;
}

var Drag = {
	BIG_Z_INDEX : 10000,
	group : null,
	isDragging : false,

	makeDraggable : function(group) {
		group.handle = group;
		group.handle.group = group;

		group.minX = null;
		group.minY = null;
		group.maxX = null;
		group.maxY = null;
		group.threshold = 0;
		group.thresholdY = 0;
		group.thresholdX = 0;

		group.onDragStart = new Function();
		group.onDragEnd = new Function();
		group.onDrag = new Function();
		
		// TODO: use element.prototype.myFunc
		group.setDragHandle = Drag.setDragHandle;
		group.setDragThreshold = Drag.setDragThreshold;
		group.setDragThresholdX = Drag.setDragThresholdX;
		group.setDragThresholdY = Drag.setDragThresholdY;
		group.constrain = Drag.constrain;
		group.constrainVertical = Drag.constrainVertical;
		group.constrainHorizontal = Drag.constrainHorizontal;

		group.onmousedown = Drag.onMouseDown;
	},

	constrainVertical : function() {
		var nwOffset = Coordinates.northwestOffset(this, true);
		this.minX = nwOffset.x;
		this.maxX = nwOffset.x;
	},

	constrainHorizontal : function() {
		var nwOffset = Coordinates.northwestOffset(this, true);
		this.minY = nwOffset.y;
		this.maxY = nwOffset.y;
	},

	constrain : function(nwPosition, sePosition) {
		this.minX = nwPosition.x;
		this.minY = nwPosition.y;
		this.maxX = sePosition.x;
		this.maxY = sePosition.y;
	},

	setDragHandle : function(handle) {
		if (handle && handle != null) 
			this.handle = handle;
		else
			this.handle = this;

		this.handle.group = this;
		this.onmousedown = null;
		this.handle.onmousedown = Drag.onMouseDown;
	},

	setDragThreshold : function(threshold) {
		if (isNaN(parseInt(threshold))) return;

		this.threshold = threshold;
	},

	setDragThresholdX : function(threshold) {
		if (isNaN(parseInt(threshold))) return;

		this.thresholdX = threshold;
	},

	setDragThresholdY : function(threshold) {
		if (isNaN(parseInt(threshold))) return;

		this.thresholdY = threshold;
	},

	onMouseDown : function(event) {
		event = Drag.fixEvent(event);
		Drag.group = this.group;

		var group = this.group;
		var mouse = event.windowCoordinate;
		var nwOffset = Coordinates.northwestOffset(group, true);
		var nwPosition = Coordinates.northwestPosition(group);
		var sePosition = Coordinates.southeastPosition(group);
		var seOffset = Coordinates.southeastOffset(group, true);

		group.originalOpacity = group.style.opacity;
		group.originalZIndex = group.style.zIndex;
		group.initialWindowCoordinate = mouse;
		// TODO: need a better name, but don't yet understand how it
		// participates in the magic while dragging 
		group.dragCoordinate = mouse;

		Drag.showStatus(mouse, nwPosition, sePosition, nwOffset, seOffset);

		group.onDragStart(nwPosition, sePosition, nwOffset, seOffset);

		// TODO: need better constraint API
		if (group.minX != null)
			group.minMouseX = mouse.x - nwPosition.x + 
					group.minX - nwOffset.x;
		if (group.maxX != null) 
			group.maxMouseX = group.minMouseX + group.maxX - group.minX;

		if (group.minY != null)
			group.minMouseY = mouse.y - nwPosition.y + 
					group.minY - nwOffset.y;
		if (group.maxY != null) 
			group.maxMouseY = group.minMouseY + group.maxY - group.minY;

		group.mouseMin = new Coordinate(group.minMouseX, group.minMouseY);
		group.mouseMax = new Coordinate(group.maxMouseX, group.maxMouseY);

		document.onmousemove = Drag.onMouseMove;
		document.onmouseup = Drag.onMouseUp;

		return false;
	},

	showStatus : function(mouse, nwPosition, sePosition, nwOffset, seOffset) {
		window.status = 
				"mouse: " + mouse.toString() + "    " + 
				"NW pos: " + nwPosition.toString() + "    " + 
				"SE pos: " + sePosition.toString() + "    " + 
				"NW offset: " + nwOffset.toString() + "    " +
				"SE offset: " + seOffset.toString();
	},

	onMouseMove : function(event) {
		event = Drag.fixEvent(event);
		var group = Drag.group;
		var mouse = event.windowCoordinate;
		var nwOffset = Coordinates.northwestOffset(group, true);
		var nwPosition = Coordinates.northwestPosition(group);
		var sePosition = Coordinates.southeastPosition(group);
		var seOffset = Coordinates.southeastOffset(group, true);

		Drag.showStatus(mouse, nwPosition, sePosition, nwOffset, seOffset);

		if (!Drag.isDragging) {
			if (group.threshold > 0) {
				var distance = group.initialWindowCoordinate.distance(
						mouse);
				if (distance < group.threshold) return true;
			} else if (group.thresholdY > 0) {
				var deltaY = Math.abs(group.initialWindowCoordinate.y - mouse.y);
				if (deltaY < group.thresholdY) return true;
			} else if (group.thresholdX > 0) {
				var deltaX = Math.abs(group.initialWindowCoordinate.x - mouse.x);
				if (deltaX < group.thresholdX) return true;
			}

			Drag.isDragging = true;
			group.style["zIndex"] = Drag.BIG_Z_INDEX;
			group.style["opacity"] = 0.75;
		}

		// TODO: need better constraint API
		var adjusted = mouse.constrain(group.mouseMin, group.mouseMax);
		nwPosition = nwPosition.plus(adjusted.minus(group.dragCoordinate));
		nwPosition.reposition(group);
		group.dragCoordinate = adjusted;

		// once dragging has started, the position of the group
		// relative to the mouse should stay fixed.  They can get out
		// of sync if the DOM is manipulated while dragging, so we
		// correct the error here
		//
		// TODO: what we really want to do is find the offset from
		// our corner to the mouse coordinate and adjust to keep it
		// the same
		
		// changed to be recursive/use absolute offset for corrections
		var offsetBefore = Coordinates.northwestOffset(group, true);
		group.onDrag(nwPosition, sePosition, nwOffset, seOffset);
		var offsetAfter = Coordinates.northwestOffset(group, true);

		if (!offsetBefore.equals(offsetAfter)) {
			var errorDelta = offsetBefore.minus(offsetAfter);
			nwPosition = Coordinates.northwestPosition(group).plus(errorDelta);
			nwPosition.reposition(group);
		}

		return false;
	},

	onMouseUp : function(event) {
		event = Drag.fixEvent(event);
		var group = Drag.group;

		var mouse = event.windowCoordinate;
		var nwOffset = Coordinates.northwestOffset(group, true);
		var nwPosition = Coordinates.northwestPosition(group);
		var sePosition = Coordinates.southeastPosition(group);
		var seOffset = Coordinates.southeastOffset(group, true);

		document.onmousemove = null;
		document.onmouseup   = null;
		group.onDragEnd(nwPosition, sePosition, nwOffset, seOffset);

		if (Drag.isDragging) {
			// restoring zIndex before opacity avoids visual flicker in Firefox
			group.style["zIndex"] = group.originalZIndex;
			group.style["opacity"] = group.originalOpacity;
		}

		Drag.group = null;
		Drag.isDragging = false;

		return false;
	},

	fixEvent : function(event) {
		if (typeof event == 'undefined') event = window.event;
		Coordinates.fixEvent(event);

		return event;
	}
};

var DragDrop = {
	firstContainer : null,
	lastContainer : null,
	
	makeListContainer : function(list) {
		// each container becomes a linked list node
		if (this.firstContainer == null) {
			this.firstContainer = this.lastContainer = list;
			list.previousContainer = null;
			list.nextContainer = null;
		} else {
			list.previousContainer = this.lastContainer;
			list.nextContainer = null;
			this.lastContainer.nextContainer = list;
			this.lastContainer = list;
		}
		
		// these functions are called when an item is draged over
		// a container or out of a container bounds.  onDragOut
		// is also called when the drag ends with an item having
		// been added to the container
		list.onDragOver = new Function();
		list.onDragOut = new Function();
		
    	var items = list.getElementsByTagName( "li" );
    	
		for (var i = 0; i < items.length; i++) {
			DragDrop.makeItemDragable(items[i]);
		}
	},

	makeItemDragable : function(item) {
		Drag.makeDraggable(item);
		item.setDragThreshold(5);
		
		// tracks if the item is currently outside all containers
		item.isOutside = false;
		
		item.onDragStart = DragDrop.onDragStart;
		item.onDrag = DragDrop.onDrag;
		item.onDragEnd = DragDrop.onDragEnd;
	},

	onDragStart : function(nwPosition, sePosition, nwOffset, seOffset) {
		// update all container bounds, since they may have changed
		// on a previous drag
		//
		// could be more smart about when to do this
		var container = DragDrop.firstContainer;
		while (container != null) {
			container.northwest = Coordinates.northwestOffset( container, true );
			container.southeast = Coordinates.southeastOffset( container, true );
			container = container.nextContainer;
		}
		
		// item starts out over current parent
		this.parentNode.onDragOver();
	},

	onDrag : function(nwPosition, sePosition, nwOffset, seOffset) {
		// check if we were nowhere
		if (this.isOutside) {
			// check each container to see if in its bounds
			var container = DragDrop.firstContainer;
			while (container != null) {
				if (nwOffset.inside( container.northwest, container.southeast ) ||
					seOffset.inside( container.northwest, container.southeast )) {
					// we're inside this one
					container.onDragOver();
					this.isOutside = false;
					
					// since isOutside was true, the current parent is a
					// temporary clone of some previous container node and
					// it needs to be removed from the document
					var tempParent = this.parentNode;
					tempParent.removeChild( this );
					container.appendChild( this );
					tempParent.parentNode.removeChild( tempParent );
					break;
				}
				container = container.nextContainer;
			}
			// we're still not inside the bounds of any container
			if (this.isOutside)
				return;
		
		// check if we're outside our parent's bounds
		} else if (!(nwOffset.inside( this.parentNode.northwest, this.parentNode.southeast ) ||
			seOffset.inside( this.parentNode.northwest, this.parentNode.southeast ))) {
			
			this.parentNode.onDragOut();
			this.isOutside = true;
			
			// check if we're inside a new container's bounds
			var container = DragDrop.firstContainer;
			while (container != null) {
				if (nwOffset.inside( container.northwest, container.southeast ) ||
					seOffset.inside( container.northwest, container.southeast )) {
					// we're inside this one
					container.onDragOver();
					this.isOutside = false;
					this.parentNode.removeChild( this );
					container.appendChild( this );
					break;
				}
				container = container.nextContainer;
			}
			// if we're not in any container now, make a temporary clone of
			// the previous container node and add it to the document
			if (this.isOutside) {
				var tempParent = this.parentNode.cloneNode( false );
				this.parentNode.removeChild( this );
				tempParent.appendChild( this );
				document.getElementsByTagName( "body" ).item(0).appendChild( tempParent );
				return;
			}
		}
		
		// if we get here, we're inside some container bounds, so we do
		// everything the original dragsort script did to swap us into the
		// correct position
		
		var parent = this.parentNode;
				
		var item = this;
		var next = DragUtils.nextItem(item);
		while (next != null && this.offsetTop >= next.offsetTop - 2) {
			var item = next;
			var next = DragUtils.nextItem(item);
		}
		if (this != item) {
			DragUtils.swap(this, next);
			return;
		}

		var item = this;
		var previous = DragUtils.previousItem(item);
		while (previous != null && this.offsetTop <= previous.offsetTop + 2) {
			var item = previous;
			var previous = DragUtils.previousItem(item);
		}
		if (this != item) {
			DragUtils.swap(this, item);
			return;
		}
	},

	onDragEnd : function(nwPosition, sePosition, nwOffset, seOffset) {
		// if the drag ends and we're still outside all containers
		// it's time to remove ourselves from the document
		if (this.isOutside) {
			var tempParent = this.parentNode;
			this.parentNode.removeChild( this );
			tempParent.parentNode.removeChild( tempParent );
			return;
		}
		this.parentNode.onDragOut();
		this.style["top"] = "0px";
		this.style["left"] = "0px";
	}
};

var DragUtils = {
	swap : function(item1, item2) {
		var parent = item1.parentNode;
		parent.removeChild(item1);
		parent.insertBefore(item1, item2);

		item1.style["top"] = "0px";
		item1.style["left"] = "0px";
	},

	nextItem : function(item) {
		var sibling = item.nextSibling;
		while (sibling != null) {
			if (sibling.nodeName == item.nodeName) return sibling;
			sibling = sibling.nextSibling;
		}
		return null;
	},

	previousItem : function(item) {
		var sibling = item.previousSibling;
		while (sibling != null) {
			if (sibling.nodeName == item.nodeName) return sibling;
			sibling = sibling.previousSibling;
		}
		return null;
	}		
};

// fading


function setOpacity(obj, opacity) {
  opacity = (opacity == 100)?99.999:opacity;
  
  // IE/Win
  obj.style.filter = "alpha(opacity:"+opacity+")";
  
  // Safari<1.2, Konqueror
  obj.style.KHTMLOpacity = opacity/100;
  
  // Older Mozilla and Firefox
  obj.style.MozOpacity = opacity/100;
  
  // Safari 1.2, newer Firefox and Mozilla, CSS3
  obj.style.opacity = opacity/100;
}

function fadeIn(objId, opacity) {
  if (document.getElementById) {
    obj = document.getElementById(objId);
    if (opacity <= 100) {
      setOpacity(obj, opacity);
      opacity += 5;
      window.setTimeout("fadeIn('"+objId+"',"+opacity+")", 100);
    }
  }
}

function fadeOut(objId, opacity) {
  if (document.getElementById) {
    obj = document.getElementById(objId);
    if (opacity >= 0) {
      setOpacity(obj, opacity);
      opacity -= 5;
      window.setTimeout("fadeOut('"+objId+"',"+opacity+")", 100);
    }
  }
}

// window positions
function pageWidth() { return window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null; } 
function pageHeight() { return  window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ?  document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null; } 
function posLeft() { return typeof window.pageXOffset != 'undefined' ? window.pageXOffset :document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0; } 
function posTop() { return typeof window.pageYOffset != 'undefined' ?  window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0; } 
function posRight() { return posLeft() + pageWidth(); } 
function posBottom() { return posTop() + pageHeight(); }

                