//***************************************************************************
// graphicslib.js
// A set of javascript functions for object positioning and animation 
//
// Created: 07-Dec-2004
// Author:  D.Niemeyer
// Copyright ©2004, Xionetic Technologies, Inc.  All rights reserved.
//***************************************************************************

//===========================================================
//	getX
//-----------------------------------------------------------
// Get an object's absolute (document) horizontal position
//-----------------------------------------------------------
// o = object to position
//===========================================================
function getX(o)
{
	var x = 0;
	if (o.offsetParent)
	{
		while (o.offsetParent)
		{
			x += o.offsetLeft
			o = o.offsetParent;
		}
	}
	else if (o.x)
		x += o.x;
	return x;
}//getX

//===========================================================
//	getY
//-----------------------------------------------------------
// Get an object's absolute (document) vertical position
//-----------------------------------------------------------
// o = object to position
//===========================================================
function getY(o)
{
	var y = 0;
	if (o.offsetParent)
	{
		while (o.offsetParent)
		{
			y += o.offsetTop
			o = o.offsetParent;
		}
	}
	else if (o.y)
		y += o.y;
	return y;
}//getY

//===========================================================
// setAbsPos
//-----------------------------------------------------------
// Generic absolute positioning function
//-----------------------------------------------------------
// o = object to position
// x = horizontal position in pixels
// y = vertical position in pixels
//===========================================================
function setAbsPos(o,x,y)
{
	// Save the width for IE where this value is changed.
	var w=o.clientWidth;
	if(y<0)y=0;
	if(x<0)x=0;
	o.style["left"] = x + "px";
	o.style["top"] = y + "px";
	o.style["position"] = "absolute";
	// Reset the width to its original width.
	o.style["width"] = w + "px";

}//setAbsPos

//===========================================================
// setPos
//-----------------------------------------------------------
// Sets the position of an object according to the parameters
// sent: by absolute, mouse relative, or control relative.
//-----------------------------------------------------------
// o = object to position
// c = control to use for control relative positioning
// m = struct containing mouse position
//
// rtype = type of object to position relatively
//			  A: absolute positioning
//			  M: mouse relative
//			  C: control relative
//
// halign = type of horizontal positioning
//        LL: align source left edge with the destination left edge
//        LR: align source left edge with the destination right edge
//        RL: align source right edge with the destination left edge
//        RR: align source right edge with the destination right edge
//        C: center source horizontally with the destination
//
// valign = type of vertical positioning
//			 TT: align source top edge with the destination top edge
//			 TB: align source top edge with the destination bottom edge
//			 BT: align source bottom edge with the destination top edge
//			 BB: align source bottom edge with the destination bottom edge
//        C: center source vertically with the destination
//
// dx = additional horizontal offset
// dy = additional vertical offset 
//===========================================================
function setPos(o, c, m, rtype, halign, valign, dx, dy)
{
	var x,y;		// calculated position of the source object
	var t,l,b,r;// top, left, bottom, right - destination object
	
	//set up initial source rect(t,l,b,r)
	//absolute
	if(rtype == 'A')
	{
		t = l = 0;
		b = D.body.clientHeight; 
		r = D.body.clientWidth;
	}
	
	//mouse relative	
	if(rtype == 'M')
	{
		if(m != N)
		{
			b = t = m.y;
			r = l = m.x;
		}
		else
			alert("setPos : Mouse Relative : Mouse position cannot be null.");
	}
	
	//control relative	
	if(rtype == 'C')
	{
		if(c != N)
		{
			l = getX(c);
			t = getY(c);
			b = t + c.clientHeight;
			r = l + c.clientWidth;
		}
		else
			alert("setPos : Control Relative : Control cannot be null.");
	}

	//set horizontal position based on requested alignment
	switch(halign)
	{
		case 'LL':
			x = l;
			break;
		case 'LR':
			x = r;
			break;
		case 'RL':
			x = l - o.clientWidth;
			break;
		case 'RR':
			x = r - o.clientWidth;
			break;
		case 'C':
			x = l + ((r-l)/2) - (o.clientWidth/2);
			break;
	}

	//set vertical position based on requested alignment
	switch(valign)
	{
		case 'TT':
			y = t;
			break;
		case 'TB':
			y = b;
			break;
		case 'BT':
			y = t - o.clientHeight;
			break;
		case 'BB':
			y = b - o.clientHeight;
			break;
		case 'C':
			y = t + ((b-t)/2) - (o.clientHeight/2);
			break;
	}

	//add additional offsets
	x += dx;
	y += dy;
	setAbsPos(o,x,y); //finally, set the object to its calculated position

}//setPos

//===========================================================
// getMouseXY
//-----------------------------------------------------------
//Gets the mouse position from an event
//-----------------------------------------------------------
// e = the event to obtain coords from
// returns : a struct with x,y properties containing the position
//===========================================================
function getMouseXY(e)
{
	var m = new Point();
	if(isdf(e.pageX))
	{
		m.x = e.pageX;
		m.y = e.pageY;
	}
	else if(isdf(e.clientX))
	{
		m.x = e.clientX + D.body.scrollLeft;
		m.y = e.clientY + D.body.scrollTop;
	}
	return m;
}//getMouseXY()



//===========================================================
// animOpen
//-----------------------------------------------------------
// Initialize the animation settings in preparation to open
// (display) a DOM object.
//
// This function requires the object p to have the following
// member variables:
//		obj - The object to display (usually a div)
//		anim - The animation structure containing instructions
//           for open animation.
//		og - Member containing the text string name of the
//         global variable for object p.
//-----------------------------------------------------------
//	p - Object containing open configuration settings.
//===========================================================
function animOpen(p)
{
	var o = p.obj;
	var a = p.anim;
	if(a.wipe_u)
	{
		if(a.wipe_d)
		{
			p.cliptop = o.clientHeight/2;
			p.clipbottom = o.clientHeight/2;
		}
		else
		{
			p.cliptop = o.clientHeight;
			p.clipbottom = o.clientHeight;
		}
	}
	else 
	{
		p.cliptop = 0;		
		if(a.wipe_d)
			p.clipbottom = 0;
		else
			p.clipbottom = o.clientHeight;
	}

	if(a.wipe_l)
	{
		if(a.wipe_r)
		{
			p.clipleft = o.clientWidth/2;
			p.clipright = o.clientWidth/2;
		}
		else
		{
			p.clipleft = o.clientWidth;
			p.clipright = o.clientWidth;
		}
	}
	else 
	{
		p.clipleft = 0;		
		if(a.wipe_r)
			p.clipright = 0;
		else
			p.clipright = o.clientWidth;
	}
	p.action='o';
	clipOpen(p);
} // animOpen

//===========================================================
// animClose
//-----------------------------------------------------------
// Initialize the animation settings in preparation to close
// (hide) a DOM object.
//
// This function requires the object p to have the following
// member variables:
//		obj - The object to display (usually a div)
//		anim - The animation structure containing instructions
//           for open animation.
//		og - Member containing the text string name of the
//         global variable for object p.
//-----------------------------------------------------------
//	p - Object containing open configuration settings.
//===========================================================
function animClose(p)
{
	p.cliptop = 0;
	p.clipbottom = p.obj.clientHeight;
	p.left = 0;
	p.right = p.obj.clientWidth;
	p.action='c';
	clipClose(p);
}

//===========================================================
// clipOpen
//-----------------------------------------------------------
//	Timeout function used to animate the opening of a window.
// This function is called from animOpen and should not be 
// called directly.
//-----------------------------------------------------------
// p - Animation settings
//===========================================================
function clipOpen(p)
{
	// If the current action is not to open, then exit at once.
	if(p.action!='o')
		return;

	var a = p.anim;
	var f = "clipOpen(" + p.og + ")";
	if(a.wipe_u)
		p.cliptop -= a.wiperate;
	if(a.wipe_d)
		p.clipbottom += a.wiperate;
	if(a.wipe_l)
		p.clipleft -= a.wiperate;
	if(a.wipe_r)
		p.clipright += a.wiperate;

	p.obj.style.clip = 'rect(' + p.cliptop + ' ' + p.clipright + ' ' + p.clipbottom + ' ' + p.clipleft +')';
	if(p.clipbottom < p.obj.clientHeight || p.clipright < p.obj.clientWidth || p.cliptop > 0 || p.clipleft > 0)
		window.setTimeout(f,a.wipetime);
}


//===========================================================
// clipClose
//-----------------------------------------------------------
//	Timeout function used to animate the closing of a window.
// This function is called from animClose and should not be 
// called directly.
//-----------------------------------------------------------
// p - Animation settings
//===========================================================
function clipClose(p)
{
	// If the current action is not to open, then exit at once.
	if(p.action!='c')
		return;

	var a = p.anim;
	var f = "clipClose(" + p.og + ")";
	if(a.wipe_u)
		p.cliptop += a.wiperate;
	if(a.wipe_d)
		p.clipbottom -= a.wiperate;
	if(a.wipe_l)
		p.clipleft += a.wiperate;
	if(a.wipe_r)
		p.clipright -= a.wiperate;

	p.obj.style.clip = 'rect(' + p.cliptop + ' ' + p.clipright + ' ' + p.clipbottom + ' ' + p.clipleft +')';
	if(p.clipbottom >= p.cliptop && p.clipright >= p.clipleft)
		p.clipid = window.setTimeout(f,a.wipetime);
	else
		show(p.obj,F);
}


//===========================================================
// resize
//-----------------------------------------------------------
// function that resizes one object to another's size
//-----------------------------------------------------------
// o1 = source object that contains the desired size
// o2 = destination object to resize
//===========================================================
function resize(o1,o2)
{
	setWidth(o2,o1.clientWidth);
	setHeight(o2,o1.clientHeight);
}//resize

//===========================================================
// setHeight
//-----------------------------------------------------------
// function that sets an object's height
//-----------------------------------------------------------
// o = object to set
// h = height in pixels
//===========================================================
function setHeight(o,h)
{
	o.style["height"] = h;
}//setWidth

//===========================================================
// setWidth
//-----------------------------------------------------------
// function that sets an object's width
//-----------------------------------------------------------
// o = object to set
// w = width in pixels
//===========================================================
function setWidth(o,w)
{
	o.style["width"] = w;
}//setWidth



//===========================================================
//Point structure - x,y position object
// x = horizontal position
// y = vertical position
//===========================================================
function Point()
{
	this.x;
	this.y;
}//Point()

//===========================================================
//AnimType structure - describes how and what animations will be performed
// showdelay = milliseconds delay before object becomes visible
// hidedelay = milliseconds delay before object becomes hidden
// slide = true if wipes also have slide motion where applicable
// wipe_u = true if the wipe motion includes the up direction
// wipe_d = true if the wipe motion includes the down direction
// wipe_l = true if the wipe motion includes the left direction
// wipe_r = true if the wipe motion includes the right direction
// wiperate = the number of pixels expanded for each clip update 
// wipetime = the number of milliseconds between clip updates
//===========================================================
function AnimType()
{
	this.showdelay = 0;
	this.hidedelay = 0;
	
	this.slide = F;
	this.wipe_u = F;
	this.wipe_d = F;
	this.wipe_l = F;
	this.wipe_r = F;
	this.wiperate = 0;
	this.wipetime = 5;
}//AnimType()


//===========================================================
//AlignType structure - describes how and what object alignments will be
// reltype = relative positioning type
//			  A : default - absolute (document)
//			  C : control relative
//			  M : mouse relative
//
// halign = type of horizontal positioning
//        LL: align source left edge with the destination left edge
//        LR: align source left edge with the destination right edge
//        RL: align source right edge with the destination left edge
//        RR: align source right edge with the destination right edge
//        C: default - center source horizontally with the destination
//
// valign = type of vertical positioning
//			 TT: align source top edge with the destination top edge
//			 TB: align source top edge with the destination bottom edge
//			 BT: align source bottom edge with the destination top edge
//			 BB: align source bottom edge with the destination bottom edge
//        C: default - center source vertically with the destination
//
// dx = additional horizontal offset in pixels (default 0)
// dy = additional vertical offset in pixels (default 0)
//===========================================================
function AlignType()
{
	this.rtype = 'A';
	this.halign = 'LL';
	this.valign = 'TT';
	
	this.dx = 0;
	this.dy = 0;
}//AlignType()


