// SyAni (c) Copyright 2001-2002 by Marc Worrell (marcw@pobox.com)
// 
// Permission granted to Sylvia Ritsch to use this source in
// commercial and non-commercial projects.
//
////////////////////////////////////////////////////////////////////////

// 20010105 MW: added dragging of the syani objects 

////////////////////////////////////////////////////////////////////////
// Start SYANI
////////////////////////////////////////////////////////////////////////

// Check for netscape or internet explorer
var gAppName   = navigator.appName.toLowerCase();
var gUserAgent = navigator.userAgent.toLowerCase();
var gNetscape  = gAppName.indexOf("netscape") >= 0;
var gMacOS     = gUserAgent.indexOf("mac") >= 0;
var gW3C       = document.getElementById != null;		// W3C compatible browser

var gSyaniTopMargin    = 100;
var gSyaniScreenWidth  = 640;
var gSyaniScreenHeight = 400;
var gSyaniMargin 	   = 100;

// Some state vars and a lost parameter
var gSyaniSleepyTime       = 50;     // mSec between two steps
var gSyaniWaveStep         = 0.2;    // 0.2 radials for each SinStep
var gSyaniWaveMult         = 10;     // Multiplication factor for wave stepper
var gSyaniMaxDirChange     = 0.08;   // Maximum direction change
var gSyaniMaxDirChangeDiv  = 500;    // Divisor for delta's <-0.5,0.5> on the dir change

var gSyaniTop              = new Array();    // Current position of the animation
var gSyaniLeft             = new Array();
var gSyaniDirection        = new Array();    // Direction of movement (radials)
var gSyaniDirectionChange  = new Array();    // Speed of direction change
var gSyaniWaveStepper      = new Array();    // sinus stepper for delta from main movement
var gSyaniStepPixX         = new Array();    // pixels for each step
var gSyaniStepPixY         = new Array();    // pixels for each step

var gSyaniImgWidth         = new Array();
var gSyaniImgHeight        = new Array();

// The SynAni div sections
var gSyani                 = new Array();

// The div that is being dragged and some extra state
var gSyaniDragNr           = -1;
var gSyaniOldZIndex        = 0;
var gSyaniOldLeft          = 0;
var gSyaniOldTop           = 0;
var gSyaniOffsetLeft       = 0;
var gSyaniOffsetTop        = 0;

// Dragging functions - handling events
function syaniGrab( evt )
{
	var nr;	
	if (gSyaniDragNr >= 0) syaniDrop(null);
	
	// Get the div
	evt  = (evt) ? evt : (window.event) ? window.event : null;
	if (evt)
	{
		nr = syaniGetTarget(evt, this);
		if (nr >= 0)
		{
			gSyaniDragNr = nr;
			gSyaniLeft[nr] += 20;
		}  
	
		// Get the mouse loc
		if (gSyaniDragNr >= 0)
		{
			gSyaniOldZIndex         = gSyani[nr].style.zIndex;
			gSyani[nr].style.zIndex = 2000;
			gSyaniOldLeft           = gSyaniLeft[nr];
			gSyaniOldTop            = gSyaniTop[nr];
	
			if (evt.layerX)
			{
				gSyaniOffsetLeft = evt.layerX;
				gSyaniOffsetTop  = evt.layerY;
			}
			else
			{
				gSyaniOffsetLeft = evt.offsetX;
				gSyaniOffsetTop  = evt.offsetY;
			}
		}
	}
	
	// continue or stop processing the event
	if (gSyaniDragNr >= 0) return false;
	else return true;
}

function syaniDrag( evt )
{
	var left;
	var top;
	evt = (evt) ? evt : (window.event) ? window.event : null;
		
	if (evt != null && gSyaniDragNr >= 0)
	{
		if (evt.pageX)
		{
			left = evt.pageX - gSyaniOffsetLeft;
			top  = evt.pageY - gSyaniOffsetTop;
		}
		else
		{
			left = evt.clientX - gSyaniOffsetLeft;
			top  = evt.clientY - gSyaniOffsetTop;
		}
		gSyaniLeft[gSyaniDragNr] = left;
		gSyaniTop [gSyaniDragNr] = top;
		
		// Move the animation
		if (gW3C || !gNetscape)
		{
			gSyani[gSyaniDragNr].style["top"]  = top;
			gSyani[gSyaniDragNr].style["left"] = left;
		}
		else
		{ 
			gSyani[gSyaniDragNr].top  = top;
			gSyani[gSyaniDragNr].left = left;
		}
	}
	return false;
}

function syaniRelease( evt )
{
	evt = (evt) ? evt : (window.event) ? window.event : null;
	if (evt != null && gSyaniDragNr >= 0)
	{
		syaniDrag(evt);
		gSyani[gSyaniDragNr].style.zIndex = gSyaniOldZIndex;
		gSyaniDragNr = -1;
	}
	return false;
}


// Return the div that was targeted by the mousedown event
function syaniGetTarget(evt, obj)
{
	var elem;
	var i;
	var div;
	if (gSyani.length > 0)
	{
		if (gSyani[0].addEventListener)	elem = obj;	// W3C DOM
		else if (evt.srcElement && evt.srcElement.parentElement) elem = evt.srcElement.parentElement;
		else elem = null;
		
		// sanity check...
		nr = -1;
		for (i=0; i<gSyani.length; i++) if (gSyani[i] == elem)	nr = i;
	}
	else nr = -1;
	return nr;
}

// Called when the page is loaded
// Sets the global object refs to the full and low height
// versions of the navigation.
function syaniOnLoad()
{
	if (gNetscape)
	{
		gSyaniScreenWidth  = window.innerWidth;
		gSyaniScreenHeight = window.innerHeight;
	}
	else if (document.all)
	{
		gSyaniScreenWidth  = window.document.body.scrollWidth;
		gSyaniScreenHeight = window.document.body.scrollHeight;
	}
	setTimeout("syaniMove()", gSyaniSleepyTime)
}

// Backward compatibility function
function syaniGenerate( img, img2, height, width, func, attr)
{
	syaniGenerateLoc(img, img2, height, width, func, attr);
}

// Generate the div section containing the image that should be moved around
function syaniGenerateLoc(img, img2, height, width, func, attr)
{
	var nr;
	var name;
	var z;
	var top;
	var left;
	
	nr   = gSyani.length;
	z    = nr + 300;
	name = "syani" + nr;
	
	top = 100;
	left = 100;
	
	var div = createDiv(name, top, left, z, img, img2, width, height, func, attr);
	document.body.appendChild(div);
	
	gSyani[nr]                = null;
	gSyaniTop[nr]             = top;
	gSyaniLeft[nr]            = left;
	gSyaniDirection[nr]       = Math.random() * 3.1415 * 2;
	gSyaniDirectionChange[nr] = Math.random() * gSyaniMaxDirChange;
	gSyaniWaveStepper[nr]     = 0;
	gSyaniImgWidth[nr]        = width;
	gSyaniImgHeight[nr]       = height;
	gSyaniStepPixX[nr]        = Math.round(Math.random() * 2 + 1);
	gSyaniStepPixY[nr]        = Math.round(Math.random() * 2 + 1);
}

function createDiv (id, top, left, z, src, src2, width, height, func, attr)
{
	var newElem = document.createElement("div");
	newElem.id 					= id;
	newElem.style['left']		= top+"px";
	newElem.style['top']		= left+"px";
	newElem.style['zIndex']		=  z+10000;
	newElem.style['position']	= 'absolute';
	//newElem.style['visibility'] = 'hidden';
	newElem.style['cursor']		= "pointer";
	newElem.img					= loadImage(src);
	newElem.img2				= loadImage(src2);
	newElem.callAttribs			= attr;
	newElem.callFunc			= func;
	newElem.onclick				= clickProxy;
	newElem.onmouseover			= f_rollin;
	newElem.onmouseout			= f_rollout;
	var newImage				= document.createElement("img");
	newImage.src				= src;
	newImage.width				= width;
	newImage.height				= height;
	newImage.style['border']	= '0';
	newElem.appendChild(newImage);
	newElem.myimage				= newImage;
	return newElem;
}
function loadImage (src)
{
	var i = new Image();
	i.src = src;
	return i;
}
function clickProxy ()
{
	window.newsClick (this.callAttribs);
}

function f_rollin()
{
	var i = getImage(this);
	if (i.nodeName == "IMG") i.src = this.img2.src;
}

function f_rollout()
{
	var i = getImage(this);
	if (i.nodeName == "IMG") i.src = this.img.src;
}

function getImage (div)
{
	var n = div.firstChild;
	while (n.nodeName!="IMG") n = n.nextSibling;
	return n;
}

// Fetch all refs to all defined divs and install the event handlers for the dragging
function syaniGetDivs()
{
	var has_listener;  
	has_listener = false;
	for (var i=0; i<gSyani.length; i++)
	{
		if (gNetscape && !gW3C) eval("gSyani["+i+"] = document.syani"+i);
		else if (document.all) gSyani[i] = document.all["syani"+i];
		else gSyani[i] = document.getElementById("syani"+i);
	
		if (gSyaniTop[i] < 0 && gSyaniLeft[i] < 0)
		{
			gSyaniTop[i]  = gSyaniScreenHeight - gSyaniImgHeight[i]; 
			gSyaniLeft[i] = Math.round(Math.random() * (gSyaniScreenWidth - gSyaniImgWidth[i] - 10));
		}
		/*if (gSyani[i].addEventListener)
		{
			gSyani[i].addEventListener("mousedown", syaniGrab,    true);
			gSyani[i].addEventListener("mouseup",   syaniRelease, true);
			has_listener = true;
		}*/
		addEvent(gSyani[i], 'mousedown', syaniGrab);
		addEvent(gSyani[i], 'mouseup', syaniRelease);
		has_listener = true;
	}
	
	/*if (!has_listener)
	{
		if (gNetscape) document.captureEvents(Event.MOUSEDOWN|Event.MOUSEMOVE|Event.MOUSEUP);// Netscape 4.x
		document.onmouseup   = syaniRelease;
		document.onmousedown = syaniGrab;
	}*/
	document.onmousemove = syaniDrag;
}


// Move the object to its new position
function syaniMove()
{
	var x;
	var y;
	var top;
	var sin;
	var dx;
	var dy;
	
	if (gSyani.length > 0 && gSyani[0] == null) syaniGetDivs();

	if (gNetscape) top = window.pageYOffset;
	else top = document.body.scrollTop;

	for (var i=0; i<gSyani.length; i++)
	{
		if (i != gSyaniDragNr)
		{
			// Change the direction of the movement (in radians)
			gSyaniDirectionChange[i] += (Math.random() - 0.5) / gSyaniMaxDirChangeDiv;
			if (gSyaniDirectionChange[i] > gSyaniMaxDirChange) gSyaniDirectionChange[i] = gSyaniMaxDirChange;
			else if (gSyaniDirectionChange[i] < -gSyaniMaxDirChange) gSyaniDirectionChange[i] = -gSyaniMaxDirChange;
			gSyaniDirection[i] += gSyaniDirectionChange[i];
			if (Math.random() < 0.01) gSyaniDirectionChange[i] = -gSyaniDirectionChange[i];
			
			// Calculate the xy speed from the direction
			dy = Math.sin(gSyaniDirection[i]);
			dx = Math.cos(gSyaniDirection[i]);
			// Calculate the next 'clean' position
			x   = gSyaniLeft[i] + dx * gSyaniStepPixX[i];
			y   = gSyaniTop[i]  + dy * gSyaniStepPixY[i];
			
			// Check if we are going to bounce of the window edge
			if ((dx < 0 && x + gSyaniImgWidth[i] <= gSyaniMargin) || (dx > 0 && x + gSyaniImgWidth[i] > gSyaniScreenWidth-gSyaniMargin))
			{
				// bounce in the x direction
				gSyaniDirection[i] = 3.141592 - gSyaniDirection[i];
				gSyaniDirectionChange[i] =  0;
			}
			if ((dy < 0 && y + gSyaniImgHeight[i] <= gSyaniMargin) || (dy > 0 && y + gSyaniImgHeight[i] > gSyaniScreenHeight-gSyaniMargin))
			{
				// bounce in the y direction
				gSyaniDirection[i] = -gSyaniDirection[i];
				gSyaniDirectionChange[i] = 0;
			}
			
			// The sine destroys the 'straight' path to a duck-waggling
			sin = Math.sin(gSyaniWaveStepper[i]) * gSyaniWaveMult;
			gSyaniWaveStepper[i] += gSyaniWaveStep;

			// Move the animation
			if (gW3C || !gNetscape)
			{
				gSyani[i].style['top']  = (y + sin)+"px";
				gSyani[i].style['left'] = x+"px";
			}
			else
			{
				gSyani[i].top  = y + sin;
				gSyani[i].left = x;
			}	
			
			// Remember the last 'clean' position (without the waggling)
			gSyaniTop[i]  = y;
			gSyaniLeft[i] = x;
			if (gW3C || !gNetscape) gSyani[i].style.visibility = "inherit";
			else if (gNetscape)	gSyani[i].visibility = "inherit";
			else gSyani[i].style.visibility = "inherit";
		}
	}	
	// Next movement
	setTimeout("syaniMove()", gSyaniSleepyTime)
}
