var IE4 = (document.all) ? 1 : 0;
var NN4 = (document.layers) ? 1 : 0;
var DOM = (document.getElementById) ? 1 : 0;

var winObj = new function WindowObj(){
	this.screen_width = window.screen.width;
	this.screen_height = window.screen.height;
	this.active = false;
	this.offsetX = 0;
	this.offsetY = 0;
	this.zIndex = 0;
	this.array = new Array();	
}
function checkWithin(x,y,left,width,top,height) {
	return (x>=left && x<=(left + width) && y>=top && y<=(top + height));
}
function checkWithinLayer(x,y,lyr) {	
	var XY = lyr.getAbsoluteXY();
	return (checkWithin(x,y,XY[0],lyr.w,XY[1],lyr.h))
}
winObj.DragAdd = function() {
	var l = this.array.length;
	if(l == 0){
		this.initDrag();
	}	
	for (var i=0;i < arguments.length;i++){		
		this.array[l] = arguments[i];
		this.zIndex += 1
	}
}
winObj.DragRemove = function() {
	for (var i=0; i<arguments.length; i++) {
		for (var j=0; j<this.array.length; j++) {
			if (this.array[j]==arguments[i]) {
				for (var k=j;k<=this.array.length-2;k++) this.array[k] = this.array[k+1]
				this.array[this.array.length-1] = null
				this.array.length -= 1
				break;
			}
		}
	}
}
winObj.DragMouseDown = function(wObj, type, x, y) {
	wObj.active = false;	
	for (var i=wObj.array.length-1;i>=0;i--) {
		var lyr = wObj.array[i];
		if (checkWithinLayer(x,y,lyr)) {
			if(lyr.parentId){
				var parentXY = lyr.parentId.getAbsoluteXY();
				if(x>=parentXY[0] && x<=(parentXY[0] + lyr.parentId.layer.clientWidth) && 
				   y>=parentXY[1] && y<=(parentXY[1] + lyr.parentId.layer.clientHeight)){
				
				//if(x>=lyr.parentId.getAbsoluteX() && x<=(lyr.parentId.getAbsoluteX() + lyr.parentId.layer.clientWidth) && 
				//   y>=lyr.parentId.getAbsoluteY() && y<=(lyr.parentId.getAbsoluteY() + lyr.parentId.layer.clientHeight)){
					wObj.obj = wObj.array[i];
					wObj.active = true;
					break;
				}
			}else{
				wObj.obj = wObj.array[i];
				wObj.active = true;
				break;			
			}
		}
	}	
	if (!wObj.active) 
		return true;	//false	swapped over to allow events outside layers to run
	else {
		wObj.active = wObj.obj.onDragStart(x,y)
		return false;
	}
	// effectively return !wObj.active
}
winObj.DragMouseMove = function(wObj, type, x,y) {
	if (!wObj.active) 
		return false;	//true
	else {
		wObj.obj.onDragMove(x, y)
		return false;
	}
	// effectively return !wObj.active
}
winObj.DragMouseUp = function(wObj, type, x,y) {	
	if (!wObj.active) 
		return false;	//true
	else {
		wObj.active = false
		wObj.obj.onDragEnd(x, y)
		return false;
	}
	// effectively return !wObj.active
}
function insertDynamicObj(DynEl,width,height){
	DynEl.getAbsoluteXY = function() {
		var obj = this.layer;
		var x = obj.offsetLeft;
		var y = obj.offsetTop;
		while(obj.offsetParent){
			x = x + obj.offsetParent.offsetLeft;
			y = y + obj.offsetParent.offsetTop;
			obj = obj.offsetParent;
		}
		return [x, y];
	}
	var str = '<div id="'+DynEl.id+'Container" style="position: relative; top: 0px; left: 0px;' 
	if (arguments.length>0 && width!=null) str += ' width:'+width+';'
	if (arguments.length>1 && height!=null) str += ' height:'+height+';'
	return str + '">' + DynEl.div + '</div>'
}
function css(id,left,top,width,height,color,vis,z,other) {
	var str = '#'+id+' {position:absolute; left:'+left+'px; top:'+top+'px;'
	if (arguments.length>=4 && width!=null) str += ' width:'+width+'px;'
	if (arguments.length>=5 && height!=null) {
		str += ' height:'+height+'px;'
		//if (arguments.length<9 || other.indexOf('clip')==-1) 
		str += ' clip:rect(0px '+width+'px '+height+'px 0px);'
	}
	if (arguments.length>=6 && color!=null) str += (NN4)? ' layer-background-color:'+color+';' : ' background-color:'+color+';'
	if (arguments.length>=7 && vis!=null) str += ' visibility:'+((NN4)? ((vis)? 'show':'hide'):((vis)? 'visible':'hidden'))+';'
	if (arguments.length>=8 && z!=null) str += ' z-index:'+z+';'
	if (arguments.length==9 && other!=null) str += ' '+other
	str += '}\n'
	return str
}
function DynamicObj(id){
	this.window = window;
	this.children = [];
	this.id = id;
	this.body = "";
	this.x = 0;
	this.y = 0;
	this.w = 0;
	this.h = 0;
}
DynamicObj.prototype.build = function(color,vis,z,other){
	this.css = css(this.id,this.x,this.y,this.w,this.h,color,vis,z,other);
	this.div = '<div id="'+this.id+'">';
	for(var i = 0;i < this.children.length;i++){
		this.children[i].build();
		this.div += this.children[i].div;
		this.css += this.children[i].css;
	}
	this.div += '</div>';
}
DynamicObj.prototype.activate = function(){
	this.getRef();
	this.clipTo(0,this.w,this.h,0);		
	for(var i = 0;i < this.children.length;i++){
		this.children[i].activate();
	}
}
DynamicObj.prototype.refresh = function() {
	this.setContents(this.toString());		
	for(var i = 0;i < this.children.length;i++){
		this.children[i].activate();
	}
}
DynamicObj.prototype.moveBy = function(x,y) {
	this.moveTo(this.x+x,this.y+y);			
}
DynamicObj.prototype.moveTo = function(x,y) {
	this.setX(x);
	this.setY(y);			
}
DynamicObj.prototype.getAbsoluteXY = function() {
	if(this.parentId){
		var parentXY = this.parentId.getAbsoluteXY();
		return [this.x + parentXY[0], this.y + parentXY[1]];
	}else
		return [this.x, this.y];	
}
DynamicObj.prototype.addChild = function(child) {
	this.children[this.children.length] = child;
	child.parentId = this;
	return child;
}
//typically the defintion of these functions will be overridden by the creating object
DynamicObj.prototype.onDragStart = function(x, y){}
DynamicObj.prototype.onDragMove = function(x, y){}
DynamicObj.prototype.onDragEnd = function(x, y){}

if(DOM){
	winObj.available_width = function(){
		return window.document.body.clientWidth;
	}
	winObj.available_height = function(){
		return window.document.body.clientHeight;
	}
	winObj.initDrag = function()
	{
		this.addEventHandler("onmousedown", this.DragMouseDown);
		this.addEventHandler("onmousemove", this.DragMouseMove);
		this.addEventHandler("onmouseup", this.DragMouseUp);
	}
	DynamicObj.prototype.show = function() { this.style.visibility = "visible"; }
	DynamicObj.prototype.hide = function() { this.style.visibility = "hidden"; }
	DynamicObj.prototype.setContents = function(str)
	{
		if(str.length || !this.timerID){
			// clear any outstanding timeout
			if(this.timerID){
				clearTimeout(this.timerID);
				this.timerID=0;
			}
			this.body = str;
			this.layer.innerHTML = str;
		}
	}
	DynamicObj.prototype.setBgColor = function(color) { 
		this.bgColor = color;
		this.style.backgroundColor = color; 
	}
	DynamicObj.prototype.setBgImage = function(imageURL) {
		this.style.backgroundImage = "url("+imageURL+")";
	}
	DynamicObj.prototype.clipTo = function(t,r,b,l){		
		this.style.clip = "rect("+t+"px "+r+"px "+b+"px "+l+"px)";
	}
	DynamicObj.prototype.setX = function(x) {
		this.x = x;
		this.style.left = x+"px";
	}
	DynamicObj.prototype.setY = function(y) {
		this.y = y;
		this.style.top = y+"px";
	}
	DynamicObj.prototype.setW = function(w) {
		this.w = w;
		//opera 5 seems to want this.style.pixelWidth
		this.style.width = w+"px";
	}
	DynamicObj.prototype.setH = function(h) {
		this.h = h;
		//opera 5 seems to want this.style.pixelHeight		
		this.style.height = h+"px";
	}
	DynamicObj.prototype.setStackingOrder = function(z) { 
		this.z = z;
		this.style.zIndex = z; 
	}
	DynamicObj.prototype.getRef = function()
	{
		this.layer = window.document.getElementById(this.id);
		this.style = this.layer.style;
	}
	// Define an event handler.
	DynamicObj.prototype.addEventHandler = function(eventname, handler) {
		var dynel = this;
		
		var legacy = eventname.indexOf('on')
		
		if(this.layer.attachEvent){
			if(legacy == -1)
				eventname = 'on'+eventname;
			this.layer.attachEvent(eventname, 
						    function() { 
							    var e = window.event;
							    e.cancelBubble = true;
							    
							    return handler(dynel, e.type, e.x, e.y, 
							                   e.button, e.keyCode, 
							                   e.shiftKey, e.ctrlKey, e.altKey); 
						    });
		}else if(this.layer.addEventListener){
			if(legacy == 0)
				eventname = eventname.substring(2);
			this.layer.addEventListener(eventname, 
						    function(e) {
							    e.cancelBubble = true;
		    
							    returnValue = handler(dynel, e.type, e.layerX, e.layerY, 
							                   e.button, e.keyCode, 
							                   e.shiftKey, e.ctrlKey, e.altKey); 
							    if(returnValue == false && e.preventDefault)
								e.preventDefault();
						    }, 
						    false);
		}
	}
	winObj.addEventHandler = function(eventname, handler) {
		var dynel = this;		
		
		var legacy = eventname.indexOf('on')
		
		if(document.attachEvent){
			if(legacy == -1)
				eventname = 'on'+eventname;
			document.attachEvent(eventname, 
						    function() { 
							    var e = window.event;
							    e.cancelBubble = true;
							    
							    return handler(dynel, e.type, e.clientX + document.body.scrollLeft, e.clientY + document.body.scrollTop, 
							                   e.button, e.keyCode, 
							                   e.shiftKey, e.ctrlKey, e.altKey); 
						    });
		}else if(document.addEventListener){
			if(legacy == 0)
				eventname = eventname.substring(2);
			document.addEventListener(eventname, 
						    function(e) {
							    e.cancelBubble = true;
							    
							    returnValue = handler(dynel, e.type, e.pageX, e.pageY, 
							                   e.button, e.keyCode, 
							                   e.shiftKey, e.ctrlKey, e.altKey);
							    if(returnValue == false && e.preventDefault)
								e.preventDefault();
						    }, 
						    false);
		}
	}

	// Remove an event handler.
	DynamicObj.prototype.removeEventHandler = function(eventname) {
		this.layer.removeEventListener(eventname);
	}
	// Remove an event handler.
	winObj.removeEventHandler = function(eventname) {
		document[eventname] = null;
	}
	winObj.enableDesignMode = function(rte, html, readOnly) {
		window.document.getElementById(rte).contentDocument.designMode = "on";
	}
}else if(NN4){
	winObj.available_width = function(){
		return window.innerWidth;
	}
	winObj.available_height = function(){
		return window.innerHeight;
	}
	winObj.initDrag = function()
	{
		this.addEventHandler("onmousedown", this.DragMouseDown);
		this.addEventHandler("onmousemove", this.DragMouseMove);
		this.addEventHandler("onmouseup", this.DragMouseUp);
	}
	DynamicObj.prototype.setContents = function(str)
	{
		if(str.length || !this.timerID){
			// clear any outstanding timeout
			if(this.timerID){
				clearTimeout(this.timerID);
				this.timerID=0;
			}
			this.body = str;
			this.layer.document.writeln(str);
			this.layer.document.close();	
		}
	}
	DynamicObj.prototype.setBgColor = function(color) {
	        this.layer.bgColor = color; 
	}
	DynamicObj.prototype.setBgImage = function(image) { 
	        this.layer.background.src = image;
	}
	DynamicObj.prototype.show = function() { this.layer.visibility = "show"; }
	DynamicObj.prototype.hide = function() { this.layer.visibility = "hide"; }
	DynamicObj.prototype.clipTo = function(t,r,b,l){
		this.layer.clip.top = t;
		this.layer.clip.right = r;
		this.layer.clip.bottom = b;
		this.layer.clip.left = l;
	}
	DynamicObj.prototype.setX = function(x) {
		this.x = x;
		this.layer.left = Math.floor(this.x);
	}
	DynamicObj.prototype.setY = function(y) {
		this.y = y;
		this.layer.top = Math.floor(this.y);
	}	
	DynamicObj.prototype.setW = function(w) {
		this.w = w;
		this.layer.width = w;
	}
	DynamicObj.prototype.setH = function(h) {
		this.h = h;
		this.layer.height = h;
	}
	DynamicObj.prototype.setStackingOrder = function(z) { 
		this.z = z;
		this.layer.zIndex = z; 
	}
	DynamicObj.prototype.getRef = function()
	{
		if(this.parentId){
			//the reference is this.window.document[root.id].layers[this.id] no matter how many layers
			this.layer = this.window.document[this.parentId.id].layers[this.id];
			this.layer.visibility = "inherit";			
		}else{
			this.layer = this.window.document[this.id];
		}
	}
	/*
	* This array is used internally by the two methods above to map
	* from event name to event type.
	*/
	DynamicObj._eventmasks = {
		onabort:Event.ABORT, onblur:Event.BLUR, onchange:Event.CHANGE,
		onclick:Event.CLICK, ondblclick:Event.DBLCLICK, 
		ondragdrop:Event.DRAGDROP, onerror:Event.ERROR, 
		onfocus:Event.FOCUS, onkeydown:Event.KEYDOWN,
		onkeypress:Event.KEYPRESS, onkeyup:Event.KEYUP, onload:Event.LOAD,
		onmousedown:Event.MOUSEDOWN, onmousemove:Event.MOUSEMOVE, 
		onmouseout:Event.MOUSEOUT, onmouseover:Event.MOUSEOVER, 
		onmouseup:Event.MOUSEUP, onmove:Event.MOVE, onreset:Event.RESET,
		onresize:Event.RESIZE, onselect:Event.SELECT, onsubmit:Event.SUBMIT,
		onunload:Event.UNLOAD
	};
	
	/*
	* This method registers a handler for the named event on the
	* element. The event name argument should be the name of an
	* event handler property, such as "onmousedown" or "onkeypress".
	* The handler is a function that takes whatever action is necessary.
	* Because Navigator and IE do not have compatible Event objects,
	* all event details are passed as arguments to the handler function.
	* When invoked, the handler will be passed the following nine arguments:
	*   1) A reference to the DynEl object
	*   2) A string containing the event type
	*   3) The X-coordinate of the mouse, relative to the DynEl
	*   4) The Y-coordinate of the mouse.
	*   5) The mouse button that was clicked (if any)
	*   6) The Unicode code of the key that was pressed (if any)
	*   7) A boolean specifying whether the Shift key was down
	*   8) A boolean specifying whether the Control key was down
	*   9) A boolean specifying whether the Alt key was down
	* Event handlers that are not interested in all these arguments do
	* not have to declare them all in their argument lists, of course.
	*/
	DynamicObj.prototype.addEventHandler = function(eventname, handler)
	{
		// Arrange to capture events on this layer.
		this.layer.captureEvents(DynamicObj._eventmasks[eventname]);
		var dynel = this; 
		
		// Define an event handler that will invoke the specified handler,
		// and pass it the nine arguments specified above.
		this.layer[eventname] = function(event) {		    
		    return handler(dynel, event.type, event.x, event.y, 
		                   event.which, event.which,
		                   ((event.modifiers & Event.SHIFT_MASK) != 0),
		                   ((event.modifiers & Event.CTRL_MASK) != 0),
		                   ((event.modifiers & Event.ALT_MASK) != 0));
		}		
	}
	winObj.addEventHandler = function(eventname, handler)
	{
		// Arrange to capture events on this layer.
		document.captureEvents(DynamicObj._eventmasks[eventname]);
		var dynel = this; 
		
		// Define an event handler that will invoke the specified handler,
		// and pass it the nine arguments specified above.
		document[eventname] = function(event) {
		    return handler(dynel, event.type, event.pageX, event.pageY,  
		                   event.which, event.which,
		                   ((event.modifiers & Event.SHIFT_MASK) != 0),
		                   ((event.modifiers & Event.CTRL_MASK) != 0),
		                   ((event.modifiers & Event.ALT_MASK) != 0));
		}		
	}
	/*
	* This method unregisters the named event handler. It should be 
	* called with a single string argument such as "onmouseover".
	*/
	DynamicObj.prototype.removeEventHandler = function(eventname) {
		this.layer.releaseEvents(DynamicObj._eventmasks[eventname]);
		delete this.layer[eventname];
	}
	
}else if(IE4){
	winObj.available_width = function(){
		return window.document.body.clientWidth;
	}
	winObj.available_height = function(){
		return window.document.body.clientHeight;
	}
	winObj.initDrag = function()
	{
		this.addEventHandler("onmousedown", this.DragMouseDown);
		this.addEventHandler("onmousemove", this.DragMouseMove);
		this.addEventHandler("onmouseup", this.DragMouseUp);
	}
	DynamicObj.prototype.show = function() { this.style.visibility = "visible"; }
	DynamicObj.prototype.hide = function() { this.style.visibility = "hidden"; }
	DynamicObj.prototype.setContents = function(str)
	{
		if(str.length || !this.timerID){
			// clear any outstanding timeout
			if(this.timerID){
				clearTimeout(this.timerID);
				this.timerID=0;
			}
			this.body = str;
			// opera 5.2 this.layer.innerHTML = undefined
			this.layer.innerHTML = str;
		}
	}
	DynamicObj.prototype.setBgColor = function(color) { 
		this.bgColor = color;
		this.style.backgroundColor = color; 
	}
	DynamicObj.prototype.setBgImage = function(imageURL) {
		this.style.backgroundImage = "url("+imageURL+")";
	}
	DynamicObj.prototype.clipTo = function(t,r,b,l){		
		this.style.clip = "rect("+t+"px "+r+"px "+b+"px "+l+"px)";
	}
	DynamicObj.prototype.setX = function(x) {
		this.x = x;
		this.style.pixelLeft = x;
	}
	DynamicObj.prototype.setY = function(y) {
		this.y = y;
		this.style.pixelTop = y;
	}
	DynamicObj.prototype.setW = function(w) {
		this.w = w;
		this.style.pixelWidth = w;
	}
	DynamicObj.prototype.setH = function(h) {
		this.h = h;
		this.style.pixelHeight = h;
	}
	DynamicObj.prototype.setStackingOrder = function(z) { 
		this.z = z;
		this.style.zIndex = z; 
	}
	DynamicObj.prototype.getRef = function()
	{
		this.layer = this.window.document.all[this.id];
		this.style = this.layer.style;
	}
	
	// Define an event handler.
	DynamicObj.prototype.addEventHandler = function(eventname, handler) {
		var dynel = this;
		
		// Set an IE4 event handler that invokes the specified handler
		// with the appropriate nine arguments.
		this.layer[eventname] = function() { 
		    var e = dynel.window.event;
		    e.cancelBubble = true;
		    
		    return handler(dynel, e.type, e.x, e.y, 
		                   e.button, e.keyCode, 
		                   e.shiftKey, e.ctrlKey, e.altKey); 
		}
	}
	winObj.addEventHandler = function(eventname, handler) {
		var dynel = this;
		
		// Set an IE4 event handler that invokes the specified handler
		// with the appropriate nine arguments.
		// used to be , e.x + document.body.scrollLeft, e.y + document.body.scrollTop
		// but didn't work in opera 5.2
		document[eventname] = function() { 
		    var e = dynel.window.event;
		    e.cancelBubble = true;
		    
		    return handler(dynel, e.type, e.clientX, e.clientY, 
		                   e.button, e.keyCode, 
		                   e.shiftKey, e.ctrlKey, e.altKey); 
		}
	}

	// Remove an event handler.
	DynamicObj.prototype.removeEventHandler = function(eventname) {
		delete this.layer[eventname];
	}
	// Remove an event handler.
	winObj.removeEventHandler = function(eventname) {
		document[eventname] = null;
	}
	winObj.enableDesignMode = function(rte, html, readOnly) {
		window.frames[rte].document.designMode = "On";
	}
}
