/*

LICENZE:
	This software is copyright by Antonio GALLO
	http://www.linux.it/~agx/	e-mail: agx(at)toglimi.linux.it
	Version 1.00 - Supports only Netscape 4.x
	Version 2.00 - Revisited to support also IE 4.0
	Version 2.02 - Fixed a small bug in the EventList_Animate that
				prevent the animation running in some case


==========================================================================
AGXLayer.js
A set of usefull object to build a channel with dinamic HTML
This code was inspirated by the example into Netscape Netcaster
and "The Channel The Channel", however i writed all the code by myself
==========================================================================

NOTES:
	OK guys ! 
	Netscape inheritance of object does not work 
	well with layer :-(

	(1) You can allocate a new layer inside of a constructor as with
		this.layer = new Layer(1);
	i override this creating my layer writing into the document 
	code as i did for MSIE DIV tag.

	(2) Do not use object inheritance ... it won't work well.
	
	(3) At the end, Netscape mess-up things when doing animation 
	with derived object, i.e. moving all the layer at a times 
	instead of one, so i switch using a common Animation Engine 
	for all the Layer
*/



// Global flag that tell if your browser is DHTML enabled
var dhtml_ok = false;
// This is the browser sniffer that sets the dhtml_ok flag
// #begin Sniffer
// Ultimate client-side JavaScript client sniff.
// (C) Netscape Communications 1999.  Permission granted to reuse and distribute.
// Revised 20 April 98 to add is_nav5up and is_ie5up (see below).
// Modified by AGX on 19980611 to fit my needs (i.e. make it smaller)
    agt=navigator.userAgent.toLowerCase();
    is_major = parseInt(navigator.appVersion);
    is_minor = parseFloat(navigator.appVersion);
    is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1) && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1) && (agt.indexOf('webtv')==-1));
    is_nav3 	= (is_nav && (is_major == 3));
    is_nav4 	= (is_nav && (is_major == 4));
    is_nav4up = (is_nav && (is_major >= 4));
    is_nav5 = (is_nav && (is_major == 5));
    is_nav5up = (is_nav && (is_major >= 5));
    is_ie   	= (agt.indexOf("msie") != -1);
    is_ie3  	= (is_ie && (is_major == 2));
    is_ie4  	= (is_ie && (is_major == 4));
    is_ie4up  = (is_ie  && (is_major >= 4));
    is_ie5  = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.0")!=-1) );
    is_ie5up  = (is_ie  && !is_ie3 && !is_ie4);
// #end Sniffer
dhtml_ok = ( is_nav4up || is_ie4up );


// ================================================================================================
// Constants

var AnimationFramePerSecond = 10;		// Frame Rate
var AnimationTimeRate = 1000 / AnimationFramePerSecond;		// Frame Rate for setTimeout

// Private Vars
var LastLayerNumber = 0;			// Number of Layers added to the document

var EventList = new Array(1);			// Animation Event List
var EventLastID = 0;				// Number of animation added
var EventListIsPlaying = 0;			// Tell if the animation is playing or not

// ================================================================================================


// Return true if the object exists
function IsObject( obj ) {
	return ( typeof( obj ) != "undefined" );
	//
	if ( typeof( obj ) == "undefined" ) return false;
	if ( obj == null ) return false;
	if ( obj == "undefined" ) return false;
	if ( obj == "" ) return false;
	return true;
}

// Call a function with a given delay
// This should be used to avoid multitasking into the animation
function Callback( millisecs, callback ){
	setTimeout( callback, millisecs );
	return;
	//
	if ( IsObject(callback) ) {
		if (is_nav) {
			setTimeout( callback, millisecs );
		} else {
			setTimeout( callback(), millisecs );
		}
	}

}



// Return the relative width of an object into the Page
function PageW(Percent, Wi) {
  if ( Percent == 0 ) return 0;
	if ( isNaN(Wi) ) { Wi=0; }
  if ( is_nav ) iW = window.innerWidth; else iW = document.body.clientWidth;
	return ( ( iW - Wi) / (100/Percent) );
}



// Return the relative height of an object into the Page
function PageH(Percent, Hi) {
  if ( Percent == 0 ) return 0;
	if ( isNaN(Hi) ) { Hi=0; }
  if ( is_nav ) iH = window.innerHeight; else iH = document.body.clientHeight;
	return ( (iH - Hi) / (100/Percent) );
}



// ================================================================================================



// This is the main loop of the animation
function EventList_Animate() {
	var LoopAgain=0;								// Conta il nr. di oggetti mossi
	var l = EventList.length;
	var i = 1;
	for ( i = 1 ; i < l; i++ ) {
		// Verifica se l'oggetto e' attivo
		var active = (EventList[i])[8];
		var alive  = (EventList[i])[9];
		if ( (active+alive) > 1 ) {
			// Muove L'oggetto
			var obj = (EventList[i])[11];
			(EventList[i][6]) += 1;		//C++
			//obj.layer.style.pixelLeft = EventList[i][0]+ ( EventList[i][4] * EventList[i][6] );
			//obj.layer.style.pixelTop =  EventList[i][1]+ ( EventList[i][5] * EventList[i][6] );	
			obj.MoveTo(
				( EventList[i][0]+ ( EventList[i][4] * EventList[i][6] )),
				( EventList[i][1]+ ( EventList[i][5] * EventList[i][6] ))
			);
			// Controlla se ha terminato la corsa
			EventList[i][7] = EventList[i][7] - 1;
			if ( EventList[i][7] == 0 ) {
				// Elimina l'animazione dalla lista
				EventList[i][8] = 0;
				EventList[i][9] = 0;
				// Esegui e quindi elimina la callback
				var onwalk = EventList[i][11].OnWalkCompleted;
				EventList[i][11].OnWalkCompleted = null;
				if ( onwalk != null ) {
					if (is_nav) {
						Callback( 20, onwalk );	
					} else {	
						//Callback( 20, onwalk() );
						onwalk();
					}
				}
			} else {
				LoopAgain++;
			}
		}
	}
	if ( LoopAgain <= 0 ) EventListIsPlaying--;
	if ( EventListIsPlaying >= 0 ) {
		// Still something to move
		Callback( AnimationTimeRate, "EventList_Animate();" );
	
	}
	return;
}



// ================================================================================================



/*
====================================================================
 BasicLayer
====================================================================
 It encapuslate a layer with different function, 
 this is the basic component of my channel engine
 Written by Antonio GALLO into July 1998
====================================================================
*/

function BasicLayer( content, ww, hh ) {
	// Check Parameters
	var dimensions = "";
	if (is_nav) {
		if ( ! isNaN(hh) ) { dimensions= dimensions+ " height="+ hh }
		if ( ! isNaN(ww) ) { dimensions= dimensions+ " width="+  ww }
	}else{
		if ( ! isNaN(hh) ) { dimensions= dimensions+ " height:"+ hh+ " px; " }
		if ( ! isNaN(ww) ) { dimensions= dimensions+ " width:"+  ww+ " px; " }
	}

	// Initialize properties
	this.layer 	= null;
	this.name	= "LAYER" + LastLayerNumber;
	LastLayerNumber++;

	// Create MSIE Layer
	if (is_nav) {
		document.writeln('<layer name=' + this.name + ' visibility=hide z-index=100 '+ dimensions+ ' >' );
		if ( IsObject( content ) ) document.writeln(content);
		document.writeln('</layer>');
		this.layer = document.layers[this.name];
	} else {
		document.writeln("<DIV ID='"+ this.name+ "' STYLE='position:absolute; overflow:none; visibility:hidden; z-index:100; "+ dimensions +" ' >");
		if ( IsObject( content ) ) document.writeln( content );
		document.writeln("</DIV>");
		this.layer = document.all[this.name];
	}

	// BackLinks
	this.layer.name = this.name;
	this.layer.parent = this;

	// Initialize Methods
	this.Show				= BasicLayer_Show;
	this.Hide				= BasicLayer_Hide;
	this.Write			= BasicLayer_Write;
	this.WalkTo			= BasicLayer_WalkTo;
	this.Play				= BasicLayer_Play;
	this.Stop				= BasicLayer_Stop;
	if (is_ie) this.layer.moveTo = BasicLayerMSIE_moveTo;
	this.MoveTo			= BasicLayer_MoveTo;
	this.SetZOrder  = BasicLayer_SetZOrder;
	this.GetWidth   = BasicLayer_GetWidth;
	this.GetHeight	= BasicLayer_GetHeight;
	this.GetTop     = BasicLayer_GetTop;
	this.GetLeft	= BasicLayer_GetLeft;
	this.SetSize    = BasicLayer_SetSize;
	this.SetBGColor	= BasicLayer_SetBGColor;

	// Events
	if (is_nav) {
		this.layer.captureEvents(Event.MOUSEDOWN|Event.MOUSEMOVE|Event.MOUSEUP|Event.MOUSEOVER|Event.MOUSEOUT);
	}
	this.OnWalkCompleted 	= null;
	this.OnClick 		= null;
	//this.layer.onmousedown
	this.layer.onmouseup 	= BasicLayer_OnClick;
	this.OnMouseOver 	= null;
	this.layer.onmouseover	= BasicLayer_OnMouseOver;
	this.OnMouseMove 	= null;
	this.layer.onmousemove	= BasicLayer_OnMouseMove;
	this.OnMouseOut 	= null;
	this.layer.onmouseout 	= BasicLayer_OnMouseOut;  
}



// Compatibility function
function BasicLayerMSIE_moveTo(x,y){
	this.style.top = y; //  pixelTop = y;	
	this.style.left = x; // pixelLeft = x;	
}



// Compatibility function
function BasicLayer_MoveTo(x,y){
  if (is_nav) {
    this.layer.moveTo(x,y);
  } else {
    this.layer.style.left = x; // pixelLeft = x;	
  	this.layer.style.top = y; // pixelTop = y;		
  }
}



// Replace the document content
function BasicLayer_Write( s ) {
	if (is_nav) {
		this.layer.document.open();
		this.layer.document.write(s);
		this.layer.document.close();
	} else {
		this.layer.innerHTML = s;
	}
}



// Handle On Click Event
function BasicLayer_OnClick() {
	var ClickEvent = this.parent.OnClick;
	if ( ( ClickEvent == "" ) || ( ClickEvent == null ) ) {
	} else {
		if (is_nav) {
			Callback( 20, ClickEvent );
		} else {
			this.parent.OnClick();
		}
	}
}



// Handle On Mouse Over
function BasicLayer_OnMouseOver() {
	var MouseEvent = this.parent.OnMouseOver;
	if ( ( MouseEvent == "" ) || ( MouseEvent == null ) ) {
	} else {
		if (is_nav) {
			Callback( 20, MouseEvent );
		} else {
			this.parent.OnMouseOver();
		}
	}
}



// Handle On Mouse Move
function BasicLayer_OnMouseMove() {
	var MouseEvent = this.parent.OnMouseMove;
	if ( ( MouseEvent == "" ) || ( MouseEvent == null ) ) {
	} else {
		if (is_nav) {
			Callback( 20, MouseEvent );
		} else {
			this.parent.OnMouseMove();
		}
	}
}



// Handle On Mouse Out
function BasicLayer_OnMouseOut() {
	var MouseEvent = this.parent.OnMouseOut;
	if ( ( MouseEvent == "" ) || ( MouseEvent == null ) ) {
	} else {
		if (is_nav) {
			Callback( 20, MouseEvent );
		} else {
			this.parent.OnMouseOut();
  		}
	}
}



function BasicLayer_Show() {
	if (is_nav) {
		this.layer.visibility = "show";
	}else{
		this.layer.style.visibility = "visible";
	}
}

function BasicLayer_Hide() {
	if (is_nav) {
		this.layer.visibility = "hide";
	}else{
		this.layer.style.visibility = "hidden";
	}
}



function BasicLayer_SetZOrder( z ) {
  if (is_nav)
    this.layer.zIndex = z;
  else
    this.layer.style.zIndex = z;
}



function BasicLayer_GetWidth() {
  if (is_nav) return(this.layer.width);
  else return(this.layer.style.pixelWidth);
}



function BasicLayer_GetHeight() {
  if (is_nav) return(this.layer.height);
  else return(this.layer.style.pixelHeight);
}



function BasicLayer_GetTop() {
  if (is_nav) return(this.layer.top);
  else return(this.layer.style.pixelTop);
}



function BasicLayer_GetLeft() {
  if (is_nav) return(this.layer.left);
  else return(this.layer.style.pixelLeft);
}



function BasicLayer_SetSize(w,h) {
  if (is_nav) {
    this.layer.width  = w;
    this.layer.height = h;
  }else{
    this.layer.style.pixelWidth  = w;
    this.layer.style.pixelHeight = h;
  }
}



function BasicLayer_SetBGColor(c) {
	if (is_nav) {
		this.layer.bgColor = c;
	} else {
		this.layer.style.backgroundColor = c;
	}
}


// Prepare Layer Animation
function BasicLayer_WalkTo( toX, toY, animationTime ) {
	EventLastID++;
	this.AnimationID = EventLastID;

	if (is_nav) {
		ileft = this.layer.left;
		itop = this.layer.top;
		deltaX = toX - this.layer.left;
		deltaY = toY - this.layer.top;
	} else {
		ileft = this.layer.style.pixelLeft;
		itop =  this.layer.style.pixelTop;
		deltaX = toX - this.layer.style.pixelLeft;
		deltaY = toY - this.layer.style.pixelTop;
	}
	deltaN = ( animationTime * 1000 / AnimationTimeRate );
	deltaC = 0;
	deltaX = deltaX / deltaN;
	deltaY = deltaY / deltaN;

	// Add Entry
	i = EventList.length;
	EventList[i] = new Array();
	EventList[i][0] = ileft;	// from X
	EventList[i][1] = itop;		// from Y
	EventList[i][2] = toX;		// to X
	EventList[i][3] = toY;		// to Y
	EventList[i][4] = deltaX;	// dX
	EventList[i][5] = deltaY;	// dY
	EventList[i][6] = deltaC;	// Count ++
	EventList[i][7] = deltaN;	// Count --
	EventList[i][8] = 0;		// Active
	EventList[i][9] = 1; 		// Live
	EventList[i][10] = this.AnimationID;	// EventID
	EventList[i][11] = this;			// Object Link
}



// Start the animation Engine
function BasicLayer_Play() {
  var id = this.AnimationID;
  var l = EventList.length;
  var i = 0;
  for ( i = 1 ; i < l; i++ ) {
    if( id == EventList[i][10] ) {
      EventList[i][8]=1;
      break;
    }
  }
  // Implicit Show the object
  this.Show();
  // Start the Animation engine if not running
  if ( EventListIsPlaying <= 0 ) {
    EventListIsPlaying=1;
    setTimeout( "EventList_Animate();" , AnimationTimeRate );
  } else {
    EventListIsPlaying++;
  }
}



// Stop
function BasicLayer_Stop() {
  var id = this.AnimationID;
  var l = EventList.length;
  var i = 0;
  this.OnWalkCompleted = null;
  for ( i = 1 ; i < l; i++ ) {
    if( id == EventList[i][10] ) {
      EventList[i][8]=0;
			EventList[i][9]=0;
      break;
    }
  }
}

void(0);
// End of AGXdhtml1.js by Antonio GALLO <agx@TOGLIMI.linux.it>
