/*
 * Cross-browser API for manipulating positional html elements (divs).
 * Recently updated to support Netscape 6.
 * Author: Scott Martin, razorfish (scott.martin@razorfish.com)
 */
function Div(divId)
{	this.id = divId;
	this.alias = (document.getElementById) ? document.getElementById(this.id).id : (document.layers) ? findLayerAlias(this.id) : new String("document.all." + this.id);
	this.styleAlias = (document.getElementById || document.all) ? this.alias + ".style" : this.alias;
	this.documentObject = (document.getElementById) ? document.getElementById(this.id) : eval(this.alias);
	this.styleObject = (document.getElementById) ? this.documentObject.style : eval(this.styleAlias);
		
	function findLayerAlias(name, docAlias) 
	{	var i, layer, docLayers, layerAlias;
		if(!docAlias) docAlias = "document";
		docLayers = eval(docAlias + ".layers");
		for(i = 0; i < docLayers.length; i++) 
		{	layerAlias = docAlias + ".layers." + docLayers[i].name;
			layer = eval(layerAlias);
			if(layer.name == name) return layerAlias;
			if(layer.document.layers.length > 0) 
			{	layerAlias = findLayerAlias(name, layerAlias + ".document");
				if(layerAlias != null) return layerAlias;
			}
		}
		return null;
	}
	
	return this;
}

Div.prototype.getId = function()
{	return this.id;
}

Div.prototype.getAlias = function()
{	return this.alias;
}

Div.prototype.getStyleAlias = function()
{	return this.styleAlias;
}

Div.prototype.getDocumentObject = function()
{	return this.documentObject;
}

Div.prototype.getStyleObject = function()
{	return this.styleObject;
}

Div.prototype.isVisible = function()
{	return (this.styleObject.visibility == "visible" || this.styleObject.visibility == "show");
}

Div.prototype.setVisible = function(bool)
{	this.styleObject.visibility = (document.layers) ? ((bool) ? "show" : "hide") : ((bool) ? "visible" : "hidden");
}

Div.prototype.getLeft = function()
{	return (document.getElementById) ? (document.all || !this.documentObject.parentNode)
		? this.documentObject.offsetLeft : (this.documentObject.offsetLeft - this.documentObject.parentNode.offsetLeft) 
			: (document.all) ? this.styleObject.pixelLeft : this.styleObject.left;
}

Div.prototype.setLeft = function(x)
{	if(!isNaN(x)) 
	{	if(document.getElementById)
			this.styleObject.left = new String(x + "px");
		else this.styleObject.left = x;
	}
}

Div.prototype.getTop = function()
{	return (document.getElementById) ? (document.all || !this.documentObject.parentNode)
		? this.documentObject.offsetTop : (this.documentObject.offsetTop - this.documentObject.parentNode.offsetTop) 
			: (document.all) ? this.styleObject.pixelTop : this.styleObject.top;
}

Div.prototype.setTop = function(y)
{	if(!isNaN(y)) 
	{	if(document.getElementById)
			this.styleObject.top = new String(y + "px");
		else this.styleObject.top = y;
	}
}

Div.prototype.getRight = function()
{	return (this.getLeft() + this.getWidth());
}

Div.prototype.setRight = function(x)
{	if(!isNaN(x)) this.setLeft(x - this.getWidth());
}

Div.prototype.getBottom = function()
{	return (this.getTop() + this.getHeight());
}

Div.prototype.setBottom = function(y)
{	if(!isNaN(y)) this.setTop(y - this.getHeight());
}

Div.prototype.getHeight = function()
{	return (document.getElementById) ? this.documentObject.offsetHeight
		: (document.all) ? (this.styleObject.pixelHeight) ? this.styleObject.pixelHeight
			: eval("document.all." + this.id + ".clientHeight") : this.styleObject.clip 
				? (this.styleObject.clip.bottom - this.styleObject.clip.top)
					: (this.documentObject.height) ? this.documentObject.height : -1;
}

Div.prototype.setHeight = function(newHeight)
{	if(!isNaN(newHeight))
	{	if(document.getElementById) this.styleObject.height = new String(newHeight + "px");
		else if(document.all) this.styleObject.pixelHeight = newHeight;
		else this.styleObject.clip.bottom += (newHeight - this.getHeight());
	}
}

Div.prototype.getWidth = function()
{	return (document.getElementById) ? this.documentObject.offsetWidth
		: (document.all) ? (this.styleObject.pixelWidth) ? this.styleObject.pixelWidth
			: eval("document.all." + this.id + ".clientWidth") : this.styleObject.clip 
				? (this.styleObject.clip.right - this.styleObject.clip.left)
					: (this.documentObject.width) ? this.documentObject.width : -1;
}

Div.prototype.setWidth = function(newWidth)
{	if(!isNaN(newWidth))
	{	if(document.getElementById) this.styleObject.width = new String(newWidth + "px");
		else if(document.all) this.styleObject.pixelWidth = newWidth;
		else this.styleObject.clip.right = newWidth;
	}
}

Div.prototype.getClip = function()
{	// clip could be defined but null in Mac IE 4.5
	if(this.styleObject.clip && this.styleObject.clip != null)
	{	if((document.getElementById || document.all) && (this.styleObject.clip.length > 0))
			return Clip.parseClip(this.styleObject.clip);
		else return new Clip(this.styleObject.clip.top, this.styleObject.clip.right, this.styleObject.clip.bottom, this.styleObject.clip.left);
	}
	else return new Clip(0, this.getWidth(), this.getHeight(), 0);
}

Div.prototype.getClipTop = function()
{	cl = this.getClip();
	return cl.top;
}

Div.prototype.getClipRight = function()
{	cl = this.getClip();
	return cl.right;
}

Div.prototype.getClipBottom = function()
{	cl = this.getClip();
	return cl.bottom;
}

Div.prototype.getClipLeft = function()
{	cl = this.getClip();
	return cl.left;
}

Div.prototype.getClipHeight = function()
{	cl = this.getClip();
	return (cl.bottom - cl.top);
}

Div.prototype.getClipWidth = function()
{	cl = this.getClip();
	return (cl.right - cl.left);
}

Div.prototype.setClip = function(newClip)
{	clipObj = (typeof newClip == "string") ? Clip.parseClip(newClip) : newClip;
	
	if(document.getElementById || document.all)
		this.styleObject.clip = clipObj.toString();
	else
	{	this.documentObject.clip.top = clipObj.top;
		this.documentObject.clip.right = clipObj.right;
		this.documentObject.clip.bottom = clipObj.bottom;
		this.documentObject.clip.left = clipObj.left;
	}
}

Div.prototype.moveTo = function(x, y)
{	this.setLeft(x);
	this.setTop(y);
}

Div.prototype.moveBy = function(dx, dy)
{	this.moveTo((this.getLeft() + dx), (this.getTop() + dy));
}

Div.prototype.getZIndex = function()
{	zi = parseInt(this.styleObject.zIndex);
	return (!isNaN(zi)) ? zi : -1;
}

Div.prototype.setZIndex = function(z)
{	if(!isNaN(z)) this.styleObject.zIndex = z;
}

Div.prototype.isAbove = function(anotherDiv)
{	return (this.getZIndex() > anotherDiv.getZIndex());
}

Div.prototype.isBelow = function(anotherDiv)
{	return (this.getZIndex() < anotherDiv.getZIndex());
}

Div.prototype.moveAbove = function(anotherDiv)
{	this.setZIndex(anotherDiv.getZIndex() + 1);
}

Div.prototype.moveBelow = function(anotherDiv)
{	this.setZIndex(anotherDiv.getZIndex() - 1);
}

// NS 4: doesn't return the original contents of the div
Div.prototype.getContent = function()
{	return (document.all) ? eval("document.all." + this.id + ".innerHTML") 
		: (this.documentObject.innerHTML) ? this.documentObject.innerHTML : new String("");
}

// NS 4: all style info lost. Use <span style= around the content.
Div.prototype.setContent = function(str)
{	// even if NS 4, store the text here for later retrieval by getContent()
	
	if(document.all)
		eval("document.all." + this.id + ".innerHTML = str;");
	else
	{	this.documentObject.innerHTML = str;
			
		if(document.layers)
		{	thisDoc = this.documentObject.document;
			thisDoc.open();
			thisDoc.write(this.getContent());
			thisDoc.close();
		}
	}
}

Div.prototype.getForm = function(frmName)
{	frmArray = (document.getElementById || document.all) ? document.forms : this.documentObject.document.forms;
	return (frmArray != null && frmArray.length > 0) ? frmArray[frmName] : null;
}

// reference an image inside this div
Div.prototype.getImage = function(imgName)
{	imgArray = (document.getElementById || document.all) ? document.images : this.documentObject.document.images;
	return (imgArray != null && imgArray.length > 0) ? imgArray[imgName] : null;
}

// NS 4: color and image functions only work if the div has content in it.

Div.prototype.getColor = function()
{	return (document.getElementById || document.all) ? this.styleObject.color : this.documentObject.document.fgColor;
}

// NS 4: setColor() only applies to content written to the div *after* this method is called--
// the style of the current content of the div is not changed. A workaround is to call setColor(),
// then setContent() with the content of the div (including tags).
Div.prototype.setColor = function(newColor)
{	if(document.getElementById || document.all) this.styleObject.color = newColor;
	else this.documentObject.document.fgColor = newColor;
}

Div.prototype.getBackgroundColor = function()
{	return (document.getElementById || document.all) ? this.styleObject.backgroundColor : (this.documentObject.document.bgColor) ? this.documentObject.document.bgColor : new String("");
}

Div.prototype.setBackgroundColor = function(color)
{	if(typeof color == "string")
	{	if(document.getElementById || document.all) this.styleObject.backgroundColor = color;
		else this.documentObject.document.bgColor = color;
	}
}

Div.prototype.getBackgroundImage = function()
{	return (document.getElementById || document.all) ? this.styleObject.backgroundImage : this.documentObject.document.background ? this.documentObject.document.background.src : new String("");
}

Div.prototype.setBackgroundImage = function(newImage)
{	strImgName = (newImage.constructor == Image) ? newImage.src : newImage;
	
	if(typeof strImgName == "string")
	{	if(document.getElementById || document.all) this.styleObject.backgroundImage = "url(" + strImgName + ")";
		else 
		{	if(!this.documentObject.document.background || this.documentObject.document.background == null)
				this.documentObject.document.background = new Image();
			
			this.documentObject.document.background.src = strImgName;
		}
	}
}

Div.prototype.toString = function()
{	return "[object Div {id:\"" + this.getId() + "\" alias:\"" + this.getAlias() + "\" styleAlias:\"" + this.getStyleAlias() + "\" documentObject:{" + this.documentObject.toString() + "} styleObject:{" + this.styleObject.toString() + "}}]";
}

function Clip(top, right, bottom, left)
{	// calling parseInt() strips off the trailing "px", if any
	this.top = parseInt(top);
	this.right = parseInt(right);
	this.bottom = parseInt(bottom);
	this.left = parseInt(left);
	return this;
}

Clip.parseClip = function(strClip)
{	if(strClip.indexOf("(") != -1 && strClip.indexOf(")") != -1)
	{	// store variable for compatability with Mac NS 4.06 object bug
		spl = new String(strClip.substring(strClip.indexOf("(") + 1, strClip.indexOf(")")));
		clipVals = spl.split(" ");
		if(clipVals.length == 4) return new Clip(clipVals[0], clipVals[1], clipVals[2], clipVals[3]);
	}
	
	return null;
}

Clip.prototype.toString = function()
{	strPx = (document.getElementById || document.layers) ? "px" : "";
	return "rect(" + this.top + strPx + " " + this.right + strPx + " " + this.bottom + strPx + " " + this.left + strPx + ")";
}
