// Dynamic Layer Object
// sophisticated layer/element targeting and animation object which provides 
// the core functionality needed in most DHTML applications

// Extensively Modified and Restructured by Micah Goulart

// Distributed under the terms of the GNU Library General Public License
// Available at http://www.dansteinman.com/dynduo/

function DynLayer(ID, nestRef)
{	this.parent = nestRef ? eval(nestRef + "Ref") : this
	
	if (is.ns)
	{	if (is.ns4)
		{	this.css = nestRef ? this.parent.doc[ID] : document.layers[ID]
			this.elm = this.event = this.css	}
		else if (is.ns5)
		{	this.elm = document.getElementById(id)
			this.css = this.elm.style
			this.doc = document	}

		this.x = this.pageX = this.css.left
		this.y = this.pageY = this.css.top
		this.w = this.css.clip.width
		this.h = this.css.clip.height	}

	else if (is.ie)
	{	this.css = document.all[ID].style
		this.elm = this.event = document.all[ID]
		this.x = this.pageX = this.elm.offsetLeft
		this.y = this.pageY = this.elm.offsetTop

		this.w = is.ie4 ? this.css.pixelWidth : this.elm.offsetWidth
		this.h = is.ie4 ? this.css.pixelHeight : this.elm.offsetHeight		}
	
	this.depth = 0
	this.isChild = false

	if (this.parent != this)
	{	this.pageX += this.parent.pageX
		this.pageY += this.parent.pageY
		this.parent.children[this.parent.children.length] = this
		this.depth = this.parent.depth + 1
		this.parent.hasChildren = this.isChild = true	}

	this.doc = is.ns ? this.css.document : document
	this.event.obj = this
	
	this.children = []
	this.hasChildren = false
	this.keepUpdating = true

	this.ID = ID
	this.ref = ID + "Ref"
	eval(this.ref + " = this")	}
	

function DynLayerUpdate(x,y)
{	if (!this.hasChildren) return
	var children = []
	for (var i = 0; i < this.children.length; i++)
	{	child = this.children[i]
		child.pageX = this.pageX + child.x
		child.pageY = this.pageY + child.y
		if (child.hasChildren) child.update() }
			}

function DynLayerMoveTo(x,y)
{	if (this.keepUpdating && this.hasChildren)
		this.update(x,y)

	if (x != null)
	{	this.pageX -= (this.x - x)
		this.x = x
		if (is.ns) this.css.left = this.x
		else this.css.pixelLeft = this.x	}

	if (y != null)
	{	this.pageY -= (this.y - y)
		this.y = y
		if (is.ns) this.css.top = this.y
		else this.css.pixelTop = this.y	}
			}

function DynLayerMoveBy(x,y)
{	this.moveTo(this.x+x, this.y+y)	}

function DynLayerSetSize(w, h)
{	if (is.ns)
	{	if (w) this.css.clip.width = w
		if (h) this.css.clip.height = h	}
	if (is.ie)
	{	if (w) this.css.width = w
		if (h) this.css.height = h	}
			}
	
function DynLayerBgColor(color)
{	if (is.ns) this.doc.bgColor = color
	else if (is.ie) this.css.backgroundColor = color	}
	
function DynLayerShow()
{	this.css.visibility = is.ns ? "show" : "visible"	}

function DynLayerHide()
{	this.css.visibility = is.ns ? "hide" : "hidden"	}

// Write Method
function DynLayerWrite(html)
{	if (is.ns)
	{	this.doc.open()
		this.doc.write(html)
		this.doc.close()	}
	else if (is.ie)
		this.elm.innerHTML = html	}

DynLayer.prototype.update = DynLayerUpdate
DynLayer.prototype.moveTo = DynLayerMoveTo
DynLayer.prototype.moveBy = DynLayerMoveBy
DynLayer.prototype.setSize = DynLayerSetSize
DynLayer.prototype.bgColor = DynLayerBgColor
DynLayer.prototype.show = DynLayerShow
DynLayer.prototype.hide = DynLayerHide
DynLayer.prototype.write = DynLayerWrite


// Slide Methods
function DynLayerSlideTo(endX,endY,inc,speed,Fn)
{	if (endX == null) endX = this.x
	if (endY == null) endY = this.y
	var distX = endX-this.x
	var distY = endY-this.y
	this.slideStart(endX,endY,distX,distY,inc,speed,Fn)	}
	
function DynLayerSlideBy(distX,distY,inc,speed,Fn)
{	var endX = this.x + distX
	var endY = this.y + distY
	this.slideStart(endX,endY,distX,distY,inc,speed,Fn)	}

function DynLayerSlideStart(endX,endY,distX,distY,inc,speed,Fn)
{	if (this.slideActive) return
	var num = Math.sqrt(Math.pow(distX,2) + Math.pow(distY,2))/inc
	if (num == 0) return
	var dX = distX/num
	var dY = distY/num
	if (!Fn) Fn = null
	this.slideActive = true
	this.slide(dX,dY,endX,endY,num,1,speed,Fn)	}
	
function DynLayerSlide(dX,dY,endX,endY,num,i,speed,Fn)
{	if (!this.slideActive) return
	if (i++ < num)
	{	this.moveBy(dX,dY)
		setTimeout(this.ref + ".slide("+dX+","+dY+","+endX+","+endY+","+num+","+i+","+speed+
		",\""+Fn+"\")", speed)	}
	else
	{	this.slideActive = false
		this.moveTo(endX, endY)
		eval(Fn)	}
			}

DynLayer.prototype.slideTo = DynLayerSlideTo
DynLayer.prototype.slideBy = DynLayerSlideBy
DynLayer.prototype.slideStart = DynLayerSlideStart
DynLayer.prototype.slide = DynLayerSlide


// Clip Methods
function DynLayerClipInit(clipTop,clipRight,clipBottom,clipLeft)
{	if (is.ie)
	{	if (arguments.length==4) this.clipTo(clipTop,clipRight,clipBottom,clipLeft)
		else if (is.ie4) this.clipTo(0,this.css.pixelWidth,this.css.pixelHeight,0)	}
			}

function DynLayerClipTo(t,r,b,l)
{	if (t == null) t = this.clipValues("t")
	if (r == null) r = this.clipValues("r")
	if (b == null) b = this.clipValues("b")
	if (l == null) l = this.clipValues("l")
	if (is.ns)
	{	this.css.clip.top = t
		this.css.clip.right = r
		this.css.clip.bottom = b
		this.css.clip.left = l	}
	else if (is.ie)
	{	if (r > 0 && b > 0) this.setSize(r,b)
		this.css.clip = "rect("+t+"px "+r+"px "+b+"px "+l+"px)"	}
	this.w = r
	this.h = b	}

function DynLayerClipBy(t,r,b,l)
{	this.clipTo(this.clipValues("t")+t,this.clipValues("r")+r,this.clipValues("b")+
		b,this.clipValues("l")+l)	}

function DynLayerClipValues(which)
{	if (is.ie) var clipv = this.css.clip.split("rect(")[1].split(")")[0].split("px")
	if (which=="t") return is.ns ? this.css.clip.top : Number(clipv[0])
	if (which=="r") return is.ns ? this.css.clip.right : Number(clipv[1])
	if (which=="b") return is.ns ? this.css.clip.bottom : Number(clipv[2])
	if (which=="l") return is.ns ? this.css.clip.left : Number(clipv[3])	}

DynLayer.prototype.clipInit = DynLayerClipInit
DynLayer.prototype.clipTo = DynLayerClipTo
DynLayer.prototype.clipBy = DynLayerClipBy
DynLayer.prototype.clipValues = DynLayerClipValues

// BrowserCheck Object
function BrowserCheck()
{	var b = navigator.appName
	if (b == "Netscape") this.b = "ns"
	else if (b == "Microsoft Internet Explorer") this.b = "ie"
	else this.b = b
	this.version = navigator.appVersion
	this.v = parseInt(this.version)
	this.ns = (this.b == "ns" && this.v >= 4)
	this.ns4 = (this.b == "ns" && this.v == 4)
	this.ns5 = (this.b == "ns" && this.v == 5)
	this.ie = (this.b == "ie" && this.v >= 4)
	this.ie4 = (this.version.indexOf('MSIE 4') > 0)
	this.ie5 = (this.version.indexOf('MSIE 5') > 0)
	this.min = (this.ns || this.ie)	}

is = new BrowserCheck()

// CSS Function
function css(ID,x,y,w,h,bg,v,z,other)
{	if (ID == "START") return "<STYLE TYPE='text/css'>\n"
	else if (ID == "END") return "</STYLE>"
	var str = (x != null && y != null) ? 
		"#"+ID+" { position:absolute; left:" + x + "px; top:"+y+"px;" :
		"#"+ID+" {position:relative;"
	
	var args = arguments.length
	if (args >= 4 && w != null) str += " width:"+w+"px;"
	
	if (args >= 5 && h != null)
	{	str += " height:" + h + "px;"
		if (args < 9 || other.indexOf("clip") == -1)
			str += " clip:rect(0px "+w+"px "+h+"px 0px);"	}
			
	if (args >= 6 && bg != null)
		str += is.ns ? " layer-background-color:"+bg+";" : " background-color:"+bg+";"
		
	if (args >= 7 && v != null) str += " visibility:"+ v + ";"
	
	if (args >= 8 && z != null) str += " z-index:" + z + ";"
	
	if (args == 9 && other != null) str += " " + other
	
	if (ID == null)
		str = str.split("{")[1]
	else
		str += "}\n"
	return str	}

function writeCSS(str,showAlert)
{	str = css("START") + str + css("END")
	document.write(str)
	if (showAlert) alert(str)	}
