
/*************************************************************************
* Slide-clip Menu / Title Bar
*   written for Netfielders
* Copyright 2003 Daniel Pupius (http://pupius.co.uk)
* Description:  A title bar that has the added functionality a clipped
*               region follows the mouse revealing clickable items.
***************************************************************************
* Version: 1.0.0
***************************************************************************
* Functionality:
* - Follows mouse with interta based clip region
* - Random wander when mouse is outside
***************************************************************************
* Known Compatibility:
* - Internet Explorer 5+ Windows/Mac
* - Netscape 4+ & Mozilla
* Assumed to Work:
* - Browsers that support the NS4 DOM or the standard DOM
* Known Issues:
* - none
***************************************************************************/

//Slider object
var Slider = {
	x:		0,					//current x position of the clipped slider (variable)
	y:		0,					//top of the clipped slider (fixed)
	w:		100,					//width of the clipped slider (fixed)
	h:		133,					//height of the clipped slider (fixed)

	maxw:		763,					//how wide is the scroll area (fixed)
	num_items:	1,					//how many items (cross and labels) do we have 
	
	//CONFIG ABOVE THIS LINE
	
	v:		0,					//velocity of slider, used to create a smooth slide
	a:		0,					//the slider's current accelleration (variable for interesting movement)
	cr:		null,					//reference to the area we are clipping
	unit:		(document.getElementById)?"px":"",	//unit to use for the style values
	target:		0,
	wander:		true,					//whether the slider should wander (happens when mouse is out of the area)
	
	labels:		new Array(),

	//initiate the slider stuff
	init:		function(n) {
				this.num_items = n;
				this.cr = this.getElement("clipregion");
				
				for(var i=1;i<=this.num_items;i++) {
					this.labels[i] = this.getElement("label" + i);
				}
				
				this.getElement("aback").onmousemove = Slider.mousemove;
				this.getElement("aclip").onmousemove = Slider.mousemove;
				
				this.getElement("aback").onmouseout = Slider.startwander;
				this.getElement("aclip").onmouseout = Slider.startwander;
				
				this.clip();
				this.cycle();
			},


	//iteration that handles all the sliding, will only call the clip if necessary!
	cycle:		function() {
				var dist = this.getTarget() - this.x;
	
				this.v += dist / 200;	//accelleration
				this.v *= 0.9;		//friction
				
				//only call clip if it is actually necessary
				if(Math.round(1000*this.v)!=0) {
					this.x+=this.v;
					this.clip();
				}
				setTimeout("Slider.cycle()",10);
			},
			
	//mouseover function to show the labels for the crosses
	showlabel:	function(n) {
				if(document.layers) this.labels[n].visibility = "visible";
				else this.labels[n].style.visibility = "visible";
				Slider.wander = false;
			},
			
	//mouseover function to hide the labels for the crosses
	hidelabel:	function(n) {
				if(document.layers) this.labels[n].visibility = "hidden";
				else this.labels[n].style.visibility = "hidden";
				Slider.wander = false;
			},
			
	//retrieves the target and if the mouse is outside the slider area then a random wander is added	
	getTarget:	function() {
				if(this.wander) {
					this.a += 0.05*Math.random() - 0.025;
					if(this.a > 1.2) this.a = 1.2;
					if(this.a < -1.2) this.a = -1.2;
					this.target += this.a;
				}
				if(this.target<0) this.target = 0;
				if(this.target>(this.maxw-this.w)) this.target = this.maxw-this.w;
				return this.target;
			},
			
	//sets the current target	
	setTarget:	function(x) {
				this.a = 0;
				this.target = x;
				if(this.target<0) this.target = 0;
				if(this.target>(this.maxw-this.w)) this.target = this.maxw-this.w;
				return this.target;
			},

	//update the slider to its current position
	clip:		function() {
				var x = Math.round(this.x);
				if(document.layers) {
					this.cr.clip.top = this.y;
					this.cr.clip.left = x;
					this.cr.clip.bottom = this.y + this.h;
					this.cr.clip.right = x + this.w;
				} else	this.cr.style.clip = "rect(" + this.y + this.unit + " " + (x+this.w) + this.unit + " " + (this.y+this.h) + this.unit + " " + x + this.unit + ")";
			},

	//Wrapper function for finding an element (crossbrowser)
	getElement:	function(id) {
				var el = this.find(id);
				if(!el) alert("ERROR in Slider.getElement: Can not find [" + id + "]");
				else return el;
			},
	
	//Finds a layer, link or an image based on it's id (recurses for ns4)
	find:		function(id,d) {
				var el = null;
				if(!d) d = document;

				if (d.layers) {
					el = d.layers[id];
					if(!el) el = d.links[id];
					if(!el) el = d.images[id];
					if(!el) el = d.anchors[id];
				}
				else if (d.getElementById) el = d.getElementById(id);
				for (var i=0; !el && d.layers && i<d.layers.length; i++) el = this.find(id,d.layers[i].document);
				return el;
			},
			
			
	//EVENT FUNCTIONS	
						
	//mouse move function for images
	mousemove:	function(e) {
				e = fixEvent(e);
				Slider.setTarget(e.layerX-50);
				Slider.wander = false;
				window.status = "";
			},

	//called on mouseout and starts a random wander
	startwander:	function() {
				Slider.wander = true;
			}


}

function fixEvent(e) {
	if(!e) e = window.event;
	if(typeof e.clientX == "undefined") e.clientX = e.pageX;
	if(typeof e.clientY == "undefined") e.clientY = e.pageY;
	if(typeof e.layerX == "undefined") e.layerX = e.offsetX;
	if(typeof e.layerY == "undefined") e.layerY = e.offsetY;
	if(typeof e.currentTarget == "undefined") e.currentTarget = e.srcElement || e.target;
	if(typeof e.currentTarget.height == "undefined") e.currentTarget.height = e.height;
	if(typeof e.currentTarget.width == "undefined") e.currentTarget.width = e.width;
	return e;
};




