/*INGUS API v1.0.0 beta (c) 2002-2005 INGUS, http://www.INGUS.com/us/
Altered or removed this notice or redistributive this file is prohibited.*/

// LayerObj API v: 1.0.0  - Octomber. 20, 2005

// isDOM: W3C-DOM compatible browser? (IE5+, NS6+, others like Opera, Konqueror, etc...)
// isIE: Internet Explorer (v4 and up), also Opera emulatINGUS it.
// isIE4, isNS4: Each of the 4-series browsers (not DOM compatible).
// isOp: Any Opera version (useful as Opera emulates IE above).
// isWin: True is Windows, false if Mac/Linux etc.
// isDyn: Any DHTML-capable browser.
var isDOM = document.getElementById ? 1 : 0,
 	isIE = document.all ? 1 : 0,
 	isNS4 = navigator.appName == 'Netscape' && !isDOM ? 1 : 0,
 	isOp = self.opera ? 1 : 0,
 	isDyn = isDOM || isIE || isNS4;

// Get a reference to an element by its ID, and optionally a parent element/frame.
// Pass a parameter 'par' as either null to find a element in the current document,
// a reference to a parent element usINGUS another getRef call or similar,
// or reference to another window (e.g. parent.content) for frames usage.
function getRef(i, p) {
	p = !p ? document : p.navigator ? p.document : p;
	return isIE ? p.all[i] :isDOM ? (p.getElementById?p:p.ownerDocument).getElementById(i) : isNS4 ? p.layers[i] : null;
};

// Returns a reference to the .style property of an element, same parameters.
function getSty(i, p) {
	var r = getRef(i, p);
 	return r ? isNS4 ? r : r.style:null;
};

// You must pass an ID, and optionally a reference to a parent layer for NS4, like getRef().
// Usage: var xyz = getLyr('layerID'); or for frames: getLyr('layerID', parent.content);
// You can then access xyz.ref or .sty, which are reference from the functions above, or
// other functions of the layer object defined below, e.g. xyz.vis('visible').

// Only create a class if one is not defined already.
if (!self.LayerObj)
	var LayerObj = new Function('i', 'p','this.ref=getRef(i, p); this.sty=getSty(i, p); return this');

// Allows addition of functions to object (see below...)
function LyrFn(n, f) {
	LayerObj.prototype[n] = new Function('var a=arguments,p=a[0],px=isNS4||isOp?0:"px"; ' +
  	'with (this) { '+f+' }');
};

// Sets or gets the position of the layer, pass a number to set or nothing to get.
LyrFn('x','if (!isNaN(p)) sty.left=p+px; else return parseInt(sty.left)');
LyrFn('y','if (!isNaN(p)) sty.top=p+px; else return parseInt(sty.top)');

// This is the function you call to create a layer object.
function getLyr(i, p) { return new LayerObj(i, p) };

if (!window.aeOL) {
	// "AddEvent Object List" is our global object/function tracking array.
 	var aeOL = [];
 	var addEvent = function(obj, name, fn, legacy) {
  		// Get the 'on'-prefixed event handle, and create two variables which are
  		// references to all events of a particular type (typeArr), and all
  		// functions run by one instance of the event manager function (arrayFns).
  		var handle = 'on' + name, typeArr, arrayFns;
  	
		// Default to the DOM Event model where supported.
  		// Users can force "legacy" event model usage if they want to use this as a
  		// generic DOM Event emulation facility with their own JS objects.
  		if (obj.addEventListener && !legacy) return obj.addEventListener(name, fn, false);
  	
		// Each object has an 'aE' property that's its unique index within window.aeOL.
  		// That entry has a property 'o' and arrays for each type of event added to it.
  		if (!obj.aE) { obj.aE = aeOL.length || 1; aeOL[obj.aE] = { o:obj } }
  	
		// typeArr contains sub-arrays of events of the current type, with one array
  		// run by each instance of the event manager. It's created now if necessary.
  		typeArr = aeOL[obj.aE][name] || (aeOL[obj.aE][name] = []);
  	
		// Quit if we have already attached this function to this type of event.
  		// These next three lines are optional and can be removed if you want.
  		for (var i = 0; i < typeArr.length; i++)
   			for (var j = 0; j < typeArr[i].length; j++)
    			if (typeArr[i][j] == fn) return;
  	
		if (obj[handle] && obj[handle]._ae) {
   		// If addEvent's event manager function is already handling this event,
   		// append it to our list of functions to be run for this instance.
  	 		arrayFns = typeArr[typeArr.length - 1];
   			arrayFns[arrayFns.length] = fn;
 	 	} else {
   			// Create a new list of functions of this type, and populate it with any
   			// pre-existing handler (if any) and the function we're adding this time.
   			typeArr[typeArr.length] = obj[handle] ? [obj[handle], fn] : [fn];
   		
			// Assign our event manager function (not a closure, so avoids memory leaks)
   			// which runs all functions within its "arrayFn" instance array.
   			// It gets an object reference and arrayFns from the global aeOL array,
   			// loops through, runs them as a method of "obj", manages return values,
   			// passes the correct event object, and clears "_f" to avoid memory leaks.
   			obj[handle] = new Function('e', 'var r = true, i = 0, obj = aeOL[' + obj.aE + '].o,' +
    		'arrayFns = aeOL[' + obj.aE + ']["' + name + '"][' + (typeArr.length - 1) + '];' +
    		'for (; i < arrayFns.length; i++) { ' +
	 		'obj._f = arrayFns[i]; r = obj._f(e||window.event) != false && r; obj._f = null;' +
    		'} return r');
   			
			// Set a flag indicating that addEvent is handling this event, so future
   			// calls can just add functions to the current instance of "arrayFns" above.
   			obj[handle]._ae = 1;
  		}
 	};
	
	var removeEvent = function(obj, name, fn, legacy) {
  		// Much like addEvent() in reverse. i and j are counter variables.
  		var typeArr, arrayFns, i, j, splice;
  		if (obj.removeEventListener && !legacy) return obj.removeEventListener(name, fn, false);
  		if (!obj.aE || !aeOL[obj.aE]) return;
  		
		typeArr = aeOL[obj.aE][name];
  		i = typeArr.length;
  		
		// Loop through all events of this type within aeOL.
  		// Once we find the same function, splice it out of its array and quit.
  		while (i--) {
   			arrayFns = typeArr[i];
   			j = arrayFns.length;
  	 		splice = 0;
   			while (j--) {
    			if (arrayFns[j] == fn) splice = 1;
    			if (splice) arrayFns[j] = arrayFns[j + 1];
   			}
   		
			if (splice) { arrayFns.length--; return }
  		}
 	};
}


// Optional cancelEvent() function you can call within your event handlers to
// stop them performing the normal browser action or kill the event entirely.
// Pass an event object, and the second "c" parameter cancels event bubbling.
function cancelEvent(e, c) {
	e.returnValue = false;
 	if (e.preventDefault) e.preventDefault();
 	if (c) {
  		e.cancelBubble = true;
  		if (e.stopPropagation) e.stopPropagation();
 	}
};
