//DHTML LIB JS GMM
//Created on: 5-11-2001
//Latest Revision: 23-11-2001
//Function Oriented version /w Scrollable object
//Basic Functions for: Layer/CSS-P Containers, Images and Windows & Documents

//Featured browsers: NN 4.0+, NN6.0+, IE5.0+ (IE6.0 browser can use IE5.0+ interfaces)

//Requires: gmm_browser.js

/*Description:
Basic funtions for Layers/CSS-P Containers. Image functions are included because they are
useful for positioning the Layers / CSS-P Containers. Document functions return info about
the current document.

Revision 23-11-2001:
Added GMM_Scrollable-object, this object can be used for creating elements that can load
external URL's . The object has the following functions:

GMM_Scrollable.load(URL) => Loads an URL into the scrollable element
GMM_Scrollable.scrollBy(dX, dY) => Scrolls the document in the scroll. element by dX, dY
GMM_Scrollable.getVRatio() => Returns a float representing the ratio:
								scroll document height / scrollable element height
							  Call repeatedly to keep track of changes in this ratio when the
							  document is loading.
GMM_Scrollable.getHRatio() => Same as getVRatio() but then for ratio:
								scroll document width / scrollable element width
GMM_Scrollable.setVisibility(VisStr) => Set the visibility of the scroll. element using W3C
										standard strings
*/

/*------------------------------------------------------------------------------------
LAYER / CSS-P Container Functions
------------------------------------------------------------------------------------*/

//Creates a new Layer / CSS-P Container and returns a handle to it.
function GMM_CreateLayer(LayerID, LayerX, LayerY, LayerW, LayerH, LayerZ) //[, ContentStr, Parent]
{	if(bIsNN4)
	{	if(arguments[7])
		{	ParentLayer = GMM_FindLayerNN4(arguments[7]);
			theLayer = new Layer(LayerW, ParentLayer);
			theLayer.visibility = "inherit";
		}
		else
		{	theLayer = new Layer(LayerW);
			theLayer.visibility = "hide";
		}
		theLayer.id = LayerID;
		theLayer.x = LayerX;
		theLayer.y = LayerY;
		theLayer.clip.left = 0;
		if(LayerW != -1)
			theLayer.clip.width = LayerW;
		theLayer.clip.top = 0;
		if(LayerH != -1)
			theLayer.clip.height = LayerH;
		theLayer.zIndex = LayerZ;
		if(arguments[6])
		{	theLayer.document.open();
			theLayer.document.write(arguments[6]);
			theLayer.document.close();
		}
		return theLayer;
	}
	else if(bIsIE5)
	{	DIVStr = "\n<div id='"+LayerID+"' style='position: absolute; left: "+LayerX+"px; top: "+LayerY+"px; ";

		if(LayerW != -1)
			DIVStr += "width: "+LayerW+"px; overflow: hidden;";

		if(LayerH != -1)	
			DIVStr += "height: "+LayerH+"px; ";
		
		DIVStr += "z-index:"+LayerZ+"; visibility:"+(arguments[7]? "inherit" : "hidden")+";'></div>\n";
	
		if(arguments[7])
		{	theParent = document.all[arguments[7]];
			theParent.insertAdjacentHTML("beforeEnd", DIVStr);
		}
		else
		{	document.body.insertAdjacentHTML("beforeEnd", DIVStr);
		}

		if(arguments[6])
		{	document.all[LayerID].innerHTML = arguments[6];
		}
		
		return document.all[LayerID];
	}
	else if(bIsNN6)
	{	theLayer = document.createElement('DIV');
		theLayer.id = LayerID;
		theLayer.style.position = "absolute";
		theLayer.style.left = LayerX + "px";
		theLayer.style.top = LayerY + "px";
		if(LayerW != -1)
			theLayer.style.width = LayerW + "px";
		if(LayerH != -1)
			theLayer.style.height = LayerH + "px";
		theLayer.style.overflow = "hidden";
		if(arguments[6])
			theLayer.innerHTML = arguments[6];
		theLayer.style.zIndex = LayerZ;
		if(arguments[7])
			theLayer.style.visibility = "inherit";
		else
			theLayer.style.visibility = "hidden";

		if(arguments[7])
		{	theParent = document.getElementById(arguments[7]);
			theParent.appendChild(theLayer);
		}
		else
			document.body.appendChild(theLayer);
		
		return theLayer;
	}
}

//Searches for a layer with id=layername and returns a handle to is when found
function GMM_FindLayerNN4(LayerName)
{	if(!arguments[1])
		var doc = document;
	else
		var doc = arguments[1];

	for(var i=0; i < doc.layers.length; i++)
	{	CurrLayer = doc.layers[i];
		if(CurrLayer.id == LayerName)
			return CurrLayer;
		if(CurrLayer.document.layers.length)
		{	if((CurrLayer = GMM_FindLayerNN4(LayerName, CurrLayer.document)) != null)
				return CurrLayer;
		}
	}
	return null;	
}

//Updates a layer's content with ContentStr.
function GMM_UpdateLayerContent(theLayer, ContentStr)
{	if(bIsNN4)
	{	theLayer.document.open();
		theLayer.document.write(ContentStr);
		theLayer.document.close();
	}
	if(bIsIE5 || bIsNN6)
	{	theLayer.innerHTML = ContentStr;
	}
}

//Returns an integer representing the layer's vertical offset relative to the layer's parent, in pixels.
function GMM_GetLayerTop(theLayer)
{	if(bIsNN4)
		return theLayer.top;
	if(bIsIE5 || bIsNN6)
		return parseInt(theLayer.style.top);
	return -1;
}

//Returns an integer representing the layer's horizontal offset relative to the layer's parent, in pixels.
function GMM_GetLayerLeft(theLayer)
{	if(bIsNN4)
		return theLayer.left;
	if(bIsIE5 || bIsNN6)
		return parseInt(theLayer.style.left);
	return -1;
}

//Returns an integer representing the width of the layer in pixels.
function GMM_GetLayerWidth(theLayer)
{	if(bIsNN4)
	{	if(theLayer.document.width)
			return theLayer.document.width;
		else
			return theLayer.clip.right - theLayer.clip.left;
	}
	if(bIsIE5 || bIsNN6)
		return parseInt(theLayer.offsetWidth);
	return -1;
}

//Returns an integer representing the height of the layer in pixels.
function GMM_GetLayerHeight(theLayer)
{	if(bIsNN4)
	{	if(theLayer.document.height)
			return theLayer.document.height;
		else
			return theLayer.clip.bottom - theLayer.clip.top;
	}
	if(bIsIE5 || bIsNN6)
		return theLayer.offsetHeight;
	return -1;
}


//Clips a given layer with rectangle defined by [ClLeft, ClTop] , [ClRight, ClBottom].
function GMM_SetLayerClip(theLayer, ClLeft, ClTop, ClRight, ClBottom)
{	if(bIsNN4)
	{	theLayer.clip.top = ClTop;
		theLayer.clip.left = ClLeft;
		theLayer.clip.bottom = ClBottom;
		theLayer.clip.right = ClRight;
	}
	if(bIsIE5 || bIsNN6)
	{	theLayer.style.clip = "rect(" + ClTop + "px " + ClRight + "px " + ClBottom + "px " + ClLeft + "px)";
	}
}

//Returns an array of integers representing respectivly the layers left, top, right and bottom clip values in pixels.
function GMM_GetLayerClip(theLayer)
{	if(bIsNN4)
	{	ClipVals =  new Array(theLayer.clip.left, theLayer.clip.top, theLayer.clip.right, theLayer.clip.bottom);
	}
	if(bIsIE5 || bIsNN6)
	{	ClipStr = theLayer.style.clip;
		if(!clipStr)
			ClipVals = new Array(0, 0, parseInt(theLayer.offsetWidth), parseInt(theLayer.offsetHeight));
		else
		{	ClipVals = new Array();
			pos = ClipStr.indexOf("(");
			ClipVals[0] = parseInt(ClipStr.substring(++pos, ClipStr.length));
			pos = ClipStr.indexOf(" ", pos);
			ClipVals[1] = parseInt(ClipStr.substring(++pos, ClipStr.length));
			pos = ClipStr.indexOf(" ", pos);
			ClipVals[2] = parseInt(ClipStr.substring(++pos, ClipStr.length));
			pos = ClipStr.indexOf(" ", pos);
			ClipVals[3] = parseInt(ClipStr.substring(++pos, ClipStr.length));
		}
	}
	return ClipVals;
}

//Set the layer's visibility using W3C-standard strings: visible, hidden or inherit.
function GMM_SetLayerVisibility(theLayer, VisStr)
{	if(bIsNN4)
	{	switch(VisStr)
		{	case "visible":
				theLayer.visibility = "show";
				break;
			case "hidden":
				theLayer.visibility = "hide";
				break;
			case "inherit":
				theLayer.visibility = "inherit";
				break;
		}
	}
	if(bIsIE5 || bIsNN6)
		theLayer.style.visibility = VisStr;
}

//Returns a string representing the layer's visibility, according to W3C standards: visible, hidden or inherit.
function GMM_GetLayerVisibility(theLayer)
{	if(bIsNN4)
	{	VisStr = "";
		switch(theLayer.visibility)
		{	case "show":
				VisStr = "visible";
				break;
			case "hide":
				VisStr = "hidden";
				break;
			case "inherit":
				VisStr = "inherit";
				break;
		}
		return VisStr;
	}
	if(bIsIE5 || bIsNN6)
		return theLayer.style.visibility;
}

//Change the stacking order of a layer specified by integer LayerZ.
function GMM_SetLayerZIndex(theLayer, LayerZ)
{	if(bIsNN4)
		theLayer.zIndex = LayerZ;
	if(bIsIE5 || bIsNN6)
		theLayer.style.zIndex = LayerZ;
}

//Returns an integer representing the stacking order of the specified layer.
function GMM_GetLayerZIndex(theLayer)
{	if(bIsNN4)
		return theLayer.zIndex;
	if(bIsIE5 || bIsNN6)
		return theLayer.style.zIndex;
}

//Sets the backgroundcolor of the layer specified, using RGB hex-codes or colorwords
function GMM_SetLayerBgColor(theLayer, Color)
{	if(bIsNN4)
		theLayer.bgColor = Color;
	if(bIsIE5 || bIsNN6)
		theLayer.style.backgroundColor = Color;
}

//Returns a string representing the specified layer's backgroundcolor
function GMM_GetLayerBgColor(theLayer)
{	if(bIsNN4)
		return theLayer.bgColor;
	if(bIsIE5 || bIsNN6)
		return theLayer.style.backgroundColor;
}

//Move a layer to coordinates specified by [LayerX, LayerY]. Coordinates are in pixels and relative to parent.
function GMM_MoveLayerTo(theLayer, LayerX, LayerY)
{	if(bIsNN4)
	{	theLayer.left = LayerX;
		theLayer.top = LayerY;
	}
	if(bIsIE5 || bIsNN6)
	{	theLayer.style.left = LayerX + "px";
		theLayer.style.top = LayerY + "px";
	}
}

//Move a layer by LayerX and LayerY, both values are in pixels.
function GMM_MoveLayerBy(theLayer, LayerX, LayerY)
{	if(bIsNN4)
	{	theLayer.left += LayerX;
		theLayer.top += LayerY;
	}
	if(bIsIE5 || bIsNN6)
	{	posX = parseInt(theLayer.style.left) + LayerX;
		posY = parseInt(theLayer.style.top) + LayerY;
		theLayer.style.left = posX + "px";
		theLayer.style.top = posY + "px";
	}
}

/*------------------------------------------------------------------------------------
IMAGE FUNCTIONS
------------------------------------------------------------------------------------*/

//Returns an integer representing the x-coordinate of an image relative to the document's upperleft corner in pixes.
function GMM_GetImagePageX(theImage)
{	if(!theImage)
		return -1;

	if(bIsNN4)
	{	if(theImage.container != null)
			return theImage.container.pageX + theImage.x;
		else
			return theImage.x;
	}
	if(bIsIE5 || bIsNN6)
	{	posX = theImage.offsetLeft;
		ImParent = theImage.offsetParent;
	  	while(ImParent != null)
		{	posX += ImParent.offsetLeft;
	  		ImParent = ImParent.offsetParent;
  		}
		return posX;
	}
}

//Returns an integer representing the y-coordinate of an image relative to the document's upperleft corner in pixels.
function GMM_GetImagePageY(theImage)
{	if(!theImage)
		return -1;

	if(bIsNN4)
	{	if(theImage.container != null)
			return theImage.container.pageY + theImage.y;
		else
			return theImage.y;
	}
	if(bIsIE5 || bIsNN6)
	{	posY = theImage.offsetTop;
		ImParent = theImage.offsetParent;
	  	while(ImParent != null)
		{	posY += ImParent.offsetTop;
	  		ImParent = ImParent.offsetParent;
  		}
		return posY;
	}
}

/*------------------------------------------------------------------------------------
WINDOW & DOCUMENT FUNCTIONS
------------------------------------------------------------------------------------*/

//Returns an integer representing the width of the canvas within a window in pixels.
//WARNING: NN returns width with scrollbar included, IE returns width without scrollbar.
function GMM_GetWindowInnerWidth()
{	if(bIsNN4 || bIsNN6)
		return self.innerWidth;
	if(bIsIE5)
		return document.body.clientWidth;
	return -1;
}

//Returns an integer representing the height of the canvas within a window in pixels.
//WARNING: NN returns width with scrollbar included, IE returns width without scrollbar.
function GMM_GetWindowInnerHeight()
{	if(bIsNN4 || bIsNN6)
		return self.innerHeight;
	if(bIsIE5)
		return document.body.clientHeight;
	return -1;
}

//Returns integer representing the width of a webpage in pixels.
function GMM_GetDocumentWidth()
{	if(bIsNN4 || bIsNN6)
		return document.width
	if(bIsIE5)
		return document.body.scrollWidth;
	return -1;
}

//Returns integer representing the height of a webpage in pixels.
function GMM_GetDocumentHeight()
{	if(bIsNN4 || bIsNN6)
		return document.height
	if(bIsIE5)
		return document.body.scrollHeight;
	return -1;
}

//Returns an integer representing the amount a page is scrolled horizontally in pixels.
function GMM_GetDocumentScrollX()
{	if(bIsNN4 || bIsNN6)
		return self.pageXOffset;
	if(bIsIE5)
		return document.body.scrollLeft;
}

//Returns an integer representing the amount a page is scrolled vertically in pixels.
function GMM_GetDocumentScrollY()
{	if(bIsNN4 || bIsNN6)
		return self.pageYOffset;
	if(bIsIE5)
		return document.body.scrollTop;
}

/*------------------------------------------------------------------------------------
SCROLLABLE OBJECT
------------------------------------------------------------------------------------*/

GMM_Scrollables = new Array();

function GMM_Scrollable(ScrollerX, ScrollerY, ScrollerW, ScrollerH, ScrollerZ) //[ScrollerParent]
{	this.num = GMM_Scrollables.length;
	this.left = ScrollerX;
	this.top = ScrollerY;
	this.width = ScrollerW;
	this.height = ScrollerH;
	
	if(bIsNN4)
	{	if(arguments[5])
			this.ScrollFrame = GMM_CreateLayer("GMM_Scrollable"+this.num, ScrollerX, ScrollerY, ScrollerW, ScrollerH, ScrollerZ, "", arguments[5]);
		else
			this.ScrollFrame = GMM_CreateLayer("GMM_Scrollable"+this.num, ScrollerX, ScrollerY, ScrollerW, ScrollerH, ScrollerZ);
	}
	if(bIsIE5)
	{	IFrameStr = "\n<iframe name='"+("GMM_Scrollable"+this.num)+"' id='"+("GMM_Scrollable"+this.num)+"' scrolling='no' noresize marginwidth=0 marginheight=0 border=0 frameborder=0 width="+ScrollerW+" height="+ScrollerH+" style='position:absolute; left:"+ScrollerX+"px; top:"+ScrollerY+"px; z-index:"+ScrollerZ+"; "

		if(arguments[5])
		{	IFrameStr += "visibility: inherit;'></iframe>\n";
			theParent = document.all[arguments[5]];
			theParent.insertAdjacentHTML("beforeEnd", IFrameStr);
		}
		else	
		{	IFrameStr += "visibility: hidden;'></iframe>\n";
			document.body.insertAdjacentHTML("beforeEnd", IFrameStr);
		}
		this.ScrollFrame = document.all["GMM_Scrollable"+this.num];
	}
	if(bIsNN6)
	{	TmpFrame = document.createElement("IFRAME");
		TmpFrame.id = "GMM_Scrollable"+this.num;
		TmpFrame.style.position = "absolute";
		TmpFrame.style.left = ScrollerX + "px";
		TmpFrame.style.top = ScrollerY + "px";
		TmpFrame.style.width = ScrollerW + "px;"
		TmpFrame.style.height = ScrollerH + "px;"
		TmpFrame.style.overflow = "hidden";
		TmpFrame.style.border = "0px solid #ffffff";
		TmpFrame.style.visibility = (arguments[5]? "inherit" : "hidden");
		if(arguments[5])
		{	theParent = document.getElementById(arguments[5]);
			theParent.appendChild(TmpFrame);
		}
		else
			document.body.appendChild(TmpFrame);
		this.ScrollFrame = TmpFrame;
	}

	this.load = GMM_ScrollableLoad;
	this.scrollBy = GMM_ScrollableScrollBy;
	this.getHRatio = GMM_ScrollableGetHRatio;
	this.getVRatio = GMM_ScrollableGetVRatio;
	this.setVisibility = GMM_ScrollableSetVisibility;

	GMM_Scrollables[this.num] = this;
}

function GMM_ScrollableLoad(URL)
{	if(bIsNN4)
	{	this.ScrollFrame.top = this.top;
		this.ScrollFrame.clip.top = 0;
		this.ScrollFrame.clip.bottom = this.height;
		
		this.ScrollFrame.left = this.left;
		this.ScrollFrame.clip.left = 0;
		this.ScrollFrame.clip.right = this.width;
	}
	this.ScrollFrame.src = URL;
}

function GMM_ScrollableScrollBy(dX, dY)
{	if(bIsNN4)
	{	if(this.ScrollFrame.clip.left >= 0 && this.ScrollFrame.clip.right < this.ScrollFrame.document.width)
		{	this.ScrollFrame.left += dX;
			this.ScrollFrame.clip.left -= dX;
			this.ScrollFrame.clip.right -= dX;
		}
		if(this.ScrollFrame.clip.top >= 0 && this.ScrollFrame.clip.bottom <= this.ScrollFrame.document.height)
		{	if(this.ScrollFrame.clip.top - dY < 0)
				dY += (this.ScrollFrame.clip.top - dY);
			if(this.ScrollFrame.clip.bottom - dY >= this.ScrollFrame.document.height)
				dY += ((this.ScrollFrame.clip.bottom - dY) - this.ScrollFrame.document.height);
			this.ScrollFrame.top += dY;
			this.ScrollFrame.clip.top -= dY;
			this.ScrollFrame.clip.bottom -= dY;
		}
	}
	if(bIsIE5)
		self.frames[this.ScrollFrame.id].scrollBy(-dX, -dY);
	if(bIsNN6)
		this.ScrollFrame.contentDocument.defaultView.scrollBy(-dX, -dY);
}

function GMM_ScrollableGetVRatio()
{	if(bIsNN4)
	{	if(!this.ScrollFrame.document.height)
			return 0;
		return this.ScrollFrame.document.height / this.height;
	}
	if(bIsIE5)
	{	if(!self.frames[this.ScrollFrame.id].document.body.scrollHeight)
			return 0;
		return self.frames[this.ScrollFrame.id].document.body.scrollHeight / this.height;
	}
	if(bIsNN6)
	{	if(!this.ScrollFrame.contentDocument.height)
			return 0;
		return this.ScrollFrame.contentDocument.height / this.height;
	}
}

function GMM_ScrollableGetHRatio()
{	if(bIsNN4)
	{	if(!this.ScrollFrame.document.height)
			return 0;
		return this.ScrollFrame.document.height / this.height;
	}
	if(bIsIE5)
	{	if(!self.frames[this.ScrollFrame.id].document.body.scrollHeight)
			return 0;
		return self.frames[this.ScrollFrame.id].document.body.scrollHeight / this.height;
	}
	if(bIsNN6)
	{	if(!this.ScrollFrame.contentDocument.height)
			return 0;
		return this.ScrollFrame.contentDocument.height / this.height;
	}
}

//Sets the visibility of the Scrollable object using W3C standard strings.
function GMM_ScrollableSetVisibility(VisStr)
{	GMM_SetLayerVisibility(this.ScrollFrame, VisStr);
}
