mouseButton = 0

mainHandle				= document.getElementById( 'main' )
renderAreaHandle		= document.getElementById( 'renderArea' )
additionalNodesHandle	= document.getElementById( 'additionalNodes' )
customImageHandle		= document.getElementById( 'customImage' )
preloadCacheHandle		= document.getElementById( 'preloadCache' )
mp3playerHandle			= document.getElementById('mp3player')
overlayHandleArray		= []

progressBarLength	= 1		// the MP3
progressBarIndex	= 0

timeGlobal			= 0
currentTime			= 0
timeGlobalBegin		= 0
initInProgress		= 0

imagesToPreloadArray	= []
imagesPreloaded			= []
fxUpdateCallbackArray	= []
fxInitCallbackArray		= []
fxDestroyCallbackArray	= []

currentFxTimeline		= 0
currentOverlayTimeline	= [0,0,0]
currentFadeTimeline		= 0



byteToIsoArray			= []
for( var i=-256;i<256*4;i++)
	byteToIsoArray[i]=byteToIso( Math.max( 0,Math.min( i, 255 ) ) )

fadeTimeline = []


mouse =
{
	x:0,
	y:0,
	hover:false,
	down:false
}
renderAreaHandle.onmousemove = function( evt )
{
	evt			= !evt?window.event:evt
	mouse.x		= evt.layerX/renderAreaHandle.offsetWidth
	mouse.y		= evt.layerY/renderAreaHandle.offsetHeight
	mouse.hover	= true
}
renderAreaHandle.onmouseout = function( evt )
{
	mouse.x		=
	mouse.y		= -1
	mouse.hover	= false
	mouse.down	= false
}
renderAreaHandle.onclick = function( evt )
{
	mouse.down	= !mouse.down
}


function v3f( _x,_y,_z)
{
	this.x = _x
	this.y = _y
	this.z = _z
	return this
}


function byteToIso( byteToConvert )
{
	byteToConvert&=255
	if(	byteToConvert!=37
		&& byteToConvert!=92
		&& byteToConvert>32
		&& ( byteToConvert<128 || ( byteToConvert&7 && byteToConvert>127 ) )
		&& byteToConvert<128//220
	)
		return String.fromCharCode( byteToConvert )

	return ((byteToConvert<16?"%0":"%")+byteToConvert.toString(16)).toUpperCase()
}

function buildBmp24Header( w, h )
{
	var fileSize = 54+ w*h*3,
		h1 = 0x100000000-h
	return "data:image/bmp;charset=iso-8859-1,BM"+ byteToIsoArray[ fileSize&255 ]+ byteToIsoArray[ (fileSize>>8)&255 ]+ byteToIsoArray[ (fileSize>>16)&255 ]+ byteToIsoArray[ (fileSize>>24)&255 ] +"\0\0\0\0(\0\0\0(\0\0\0"+ byteToIsoArray[ w&255 ]+ byteToIsoArray[ (w>>8)&255 ]+ byteToIsoArray[ (w>>16)&255 ]+ byteToIsoArray[ (w>>24)&255 ]+ byteToIsoArray[ h1&255 ]+ byteToIsoArray[ (h1>>8)&255 ]+ byteToIsoArray[ (h1>>16)&255 ]+ byteToIsoArray[ (h1>>24)&255 ] +"\1\0%18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
}
function buildBmp8Header( w, h )
{
	var fileSize = 54+ 1024+w*h,
		h1 = 0x100000000-h
	return "data:image/bmp;charset=iso-8859-1,BM"+ byteToIsoArray[ fileSize&255 ]+ byteToIsoArray[ (fileSize>>8)&255 ]+ byteToIsoArray[ (fileSize>>16)&255 ]+ byteToIsoArray[ (fileSize>>24)&255 ] +"\0\0\0\0(\0\0\0(\0\0\0"+ byteToIsoArray[ w&255 ]+ byteToIsoArray[ (w>>8)&255 ]+ byteToIsoArray[ (w>>16)&255 ]+ byteToIsoArray[ (w>>24)&255 ]+ byteToIsoArray[ h1&255 ]+ byteToIsoArray[ (h1>>8)&255 ]+ byteToIsoArray[ (h1>>16)&255 ]+ byteToIsoArray[ (h1>>24)&255 ] +"\1\0%08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
}


function buildFadedImages( rawImage, size, steps, color )
{
	var
		i,j,k,
		r,g,b,
		rawImageIndex	= 0,
		str				= []
		tmpArray		= []
		lutStepsR		= []
		lutStepsG		= []
		lutStepsB		= []
		lutInv			= []
		steps_1			= steps-1

		lutStepsR[ 0 ]	=
		lutStepsG[ 0 ]	=
		lutStepsB[ 0 ]	= [ "%00","%01","%02","%03","%04","%05","%06","%07","%08","%09","%0A","%0B","%0C","%0D","%0E","%0F","%10","%11","%12","%13","%14","%15","%16","%17","%18","%19","%1A","%1B","%1C","%1D","%1E","%1F","%20","%21","%22","%23","%24","%25","%26","%27","%28","%29","%2A","%2B","%2C","-",".","%2F","0","1","2","3","4","5","6","7","8","9","%3A","%3B","%3C","%3D","%3E","%3F","%40","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","%5B","%5C","%5D","%5E","_","%60","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","%7B","%7C","%7D","%7E","%7F","%80","%81","%82","%83","%84","%85","%86","%87","%88","%89","%8A","%8B","%8C","%8D","%8E","%8F","%90","%91","%92","%93","%94","%95","%96","%97","%98","%99","%9A","%9B","%9C","%9D","%9E","%9F","%A0","%A1","%A2","%A3","%A4","%A5","%A6","%A7","%A8","%A9","%AA","%AB","%AC","%AD","%AE","%AF","%B0","%B1","%B2","%B3","%B4","%B5","%B6","%B7","%B8","%B9","%BA","%BB","%BC","%BD","%BE","%BF","%C0","%C1","%C2","%C3","%C4","%C5","%C6","%C7","%C8","%C9","%CA","%CB","%CC","%CD","%CE","%CF","%D0","%D1","%D2","%D3","%D4","%D5","%D6","%D7","%D8","%D9","%DA","%DB","%DC","%DD","%DE","%DF","%E0","%E1","%E2","%E3","%E4","%E5","%E6","%E7","%E8","%E9","%EA","%EB","%EC","%ED","%EE","%EF","%F0","%F1","%F2","%F3","%F4","%F5","%F6","%F7","%F8","%F9","%FA","%FB","%FC","%FD","%FE","%FF" ]


	// prepare the lutSteps
	for(  i=0; i<256; i++ )
		lutInv[ lutStepsR[0][i] ] = i

	if( !color )
		color = "%ff%cc%00"
	color = color.toUpperCase()
	r = lutInv[ color.substr(0,3) ]
	g = lutInv[ color.substr(3,3) ]
	b = lutInv[ color.substr(6,3) ]

	for(  i=1; i<steps; i++ )
	{
		lutStepsR[ i ] = []
		lutStepsG[ i ] = []
		lutStepsB[ i ] = []
		for(  j=0; j<256; j++ )
		{
			lutStepsR[ i ][ j ] = lutStepsR[ 0 ][ Math.round( j*(1.0-i/steps_1)+r*i/steps_1 ) ]
			lutStepsG[ i ][ j ] = lutStepsG[ 0 ][ Math.round( j*(1.0-i/steps_1)+g*i/steps_1 ) ]
			lutStepsB[ i ][ j ] = lutStepsB[ 0 ][ Math.round( j*(1.0-i/steps_1)+b*i/steps_1 ) ]
		}
	}

	toto = buildBmp24Header( Math.sqrt( size ), Math.sqrt( size )*steps )

	// go
	for(  i=0; i<size; i++ )
	{
		// R
		r = rawImage.charAt( rawImageIndex++ )
		if( r=="%" )
		{
			r += rawImage.substr( rawImageIndex,2 )
			rawImageIndex+=2
		}
		// G
		g = rawImage.charAt( rawImageIndex++ )
		if( g=="%" )
		{
			g += rawImage.substr( rawImageIndex,2 )
			rawImageIndex+=2
		}
		// B
		b = rawImage.charAt( rawImageIndex++ )
		if( b=="%" )
		{
			b += rawImage.substr( rawImageIndex,2 )
			rawImageIndex+=2
		}

		tmpArray[ i ] = b+g+r

		b = lutInv[b]
		g = lutInv[g]
		r = lutInv[r]
		for( j=1; j<steps; j++ )
			tmpArray[ i+j*size ] = lutStepsB[ j ][ b ]+lutStepsG[ j ][ g ]+lutStepsR[ j ][ r ]
	}


	//document.body.innerHTML = "<img src=\""+ toto+tmpArray.join('') +"\" />"
	return tmpArray
}



function preloadImages()
{
	var
		tmpDiv = document.createElement("DIV"),
		bla = ""
	while( imagesToPreloadArray.length )
	{

		imageToPreload = imagesToPreloadArray.shift()
		progressBarLength++
		bla += "<img id='"+ imageToPreload +"' src='img/"+ imageToPreload +"' onload='imagesPreloaded[this.id]=this;progressBarIndex++' />\n"
	}
	tmpDiv.innerHTML = bla
	preloadCacheHandle.appendChild( tmpDiv )
}
function updateMp3Status()
{
	progressBarIndex++
}
function updateProgressBar()
{
	if( fxInitCallbackArray.length )
		setTimeout( fxInitCallbackArray.shift(), 1 )

	imgDataIso = ""
	for( var i=0; i<progressBarLength; i++ )
		imgDataIso += (i<progressBarIndex)?"%44%66%88%44%66%88%44%66%88%44%66%88":"%00%00%00%00%00%00%00%00%00%00%00%00"

	customImageHandle.style.top = "23em"
	customImageHandle.style.height = "2em"
	customImageHandle.src =  buildBmp24Header( progressBarLength*4,4 )+imgDataIso+imgDataIso+imgDataIso+imgDataIso

	if( progressBarIndex==progressBarLength )
		renderAreaHandle.style.background = "#000"
	customImageHandle.style.opacity = (( progressBarIndex!=progressBarLength )?.5:customImageHandle.style.opacity-.0125)

	if( customImageHandle.style.opacity<.01 )
	{
		initInProgress = clearInterval( initInProgress )

		customImageHandle.style.opacity = ""
		customImageHandle.style.top = 0
		customImageHandle.style.height = "48em"

		timeGlobalBegin = timeGlobal = (new Date()).valueOf()
		customImageHandle.src = ""
		if( mp3playerHandle.SetVariable )
		{
			mp3playerHandle.SetVariable( "playMP3", true )
		}
		updateDemo()
	}
}

function initDemo()
{
	var
		tmpArray = renderAreaHandle.getElementsByTagName( '*' )
		scriptsArray = document.getElementsByTagName( 'script' )

	for( var i=0; i<tmpArray.length; i++ )
		if( tmpArray[i].className && tmpArray[i].className=="overlay" )
			overlayHandleArray[ tmpArray[i].id ] = tmpArray[i]

	for( var i=0; i<scriptsArray.length; i++ )
	{
		if( scriptsArray[i].id )
		{
			progressBarLength++
			fxId = scriptsArray[i].id
			eval( "fxUpdateCallbackArray[ '"+ fxId +"' ] = "+ fxId +"_update" )
			eval( "fxInitCallbackArray.push( "+ fxId +"_init )" )
			eval( "fxDestroyCallbackArray[ '"+ fxId +"' ] = window."+ fxId +"_destroy" )
		}
	}
	initInProgress = setInterval( updateProgressBar, 50 )
	updateProgressBar()
	preloadImages()
}





markedTimes = []
function updateDemo()
{
	currentTime = timeGlobal-timeGlobalBegin

	if( mouseButton )
	{
		markedTimes.push( currentTime )
		fadeTimeline += "\n\tpush( ["+ currentTime +",'hole', [ "+ Math.round(16+Math.random()*32) +","+ Math.round(16+Math.random()*32) +" ] ] )"

		mouseButton = 0
	}
	//top .status = Math.floor( currentTime/60000 )+'" '+ (Math.floor( currentTime/1000 )%60 )+"' "+( currentTime%1000 )+" >> "+ markedTimes.join( ", " )


	// update Timelines
	while( timelines[ 'fx' ].length && timelines[ 'fx' ][ 0 ][ 0 ]<=currentTime )
	{
		if( currentFxTimeline && fxDestroyCallbackArray[ currentFxTimeline[1] ] )
			fxDestroyCallbackArray[ currentFxTimeline[1] ]()
		currentFxTimeline = timelines[ 'fx' ].shift()


		if( !timelines[ 'fx' ].length )
		{
			var tmp = document.createElement( 'PRE')
			tmp.innerHTML = fadeTimeline
		//	document.body.appendChild( tmp )
		}
	}


	while( timelines[ 'fade' ].length && timelines[ 'fade' ][ 0 ][ 0 ]<=currentTime )
		currentFadeTimeline = timelines[ 'fade' ].shift()
	if( !currentFadeTimeline[1] )
		currentFadeTimeline[1] = overlayHandleArray['overlayFade'].style.backgroundColor
	if( !currentFadeTimeline[2] )
		currentFadeTimeline[2] = 500


	// update Fade
	if( currentTime>= currentFadeTimeline[0] && currentTime<= currentFadeTimeline[0]+currentFadeTimeline[2] )
	{
		overlayHandleArray['overlayFade'].style.backgroundColor = currentFadeTimeline[1]
		overlayHandleArray['overlayFade'].style.opacity			= .9999-(currentTime-currentFadeTimeline[0])/currentFadeTimeline[2]
	}
	else
		overlayHandleArray['overlayFade'].style.opacity = 0


	// update Overlays
		// timeline
	for( var i=0; i<3; i++ )
	{
		previousOverlayTimelineLength = timelines[ 'overlay'+i ].length
		while( timelines[ 'overlay'+i ].length && timelines[ 'overlay'+i ][ 0 ][ 0 ]<=currentTime )
			currentOverlayTimeline[i] = timelines[ 'overlay'+i ].shift()

		if( !currentOverlayTimeline[i] || !currentOverlayTimeline[i][1] )
		{
			overlayHandleArray['overlay'+i].style.display = "none"
		}
		else
		{
			newOverlay = previousOverlayTimelineLength!=timelines[ 'overlay'+i ].length

			// handle the overlays
			switch( currentOverlayTimeline[i][1] )
			{
				case 'quake':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['void.gif'].src
						}
						else
						{
							var
								tmp = 1+( currentTime-currentOverlayTimeline[i][0] )/32
							if( tmp>64 )
							{
								currentOverlayTimeline[i][1] = ""
								mainHandle.style.top	= "45%"
							}
							else
								mainHandle.style.top	= (45+Math.round(200/tmp*Math.cos(tmp-1))/10)+"%"
						}
					}
					break;
				}
				case 'ribbon+bomb':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['ribbon+bomb.png'].src
							style.left		= 0
							style.top		= "18em"
							style.width		= "64em"
							style.height	= "12em"
						}
						else
						{
							style.left		= (-1+Math.random()*2)+"em"
							style.top		= (17+Math.random()*2)+"em"
						}
					}
					break;
				}
				case 'black_plasma.png':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded[currentOverlayTimeline[i][1]].src
							style.left		= 0
							style.top		= 0
							style.width		= 64*8+"em"
							style.height	= "48em"
						}
						else
						{
							style.left		= -Math.round(3.5+3.5*Math.cos(currentTime/25))*64+"em"
							style.top		= 0
						}
					}
					break;
				}
				case 'scrolling':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['scrolling.gif'].src
							style.left		= "16em"
							style.top		= "48em"
							style.width		= "16em"
							style.height	= "84em"
						}
						else
						{
							//style.left		= -Math.round(3.5+3.5*Math.cos(currentTime/25))*64+"em"
							style.top		= (48-(currentTime-currentOverlayTimeline[i][0])*(84+48)/6000)+"em"
						}
					}
					break;
				}
				case 'hole':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['hole.png'].src
						}
						else
						{
							var
								holeSize	= 64*( 1+(currentTime-currentOverlayTimeline[i][0])/256 )

							if( holeSize>768 )
								currentOverlayTimeline[i][1] = ""
							else
							{
								style.left		= (currentOverlayTimeline[i][2][0]-holeSize/2)+"em"
								style.top		= (currentOverlayTimeline[i][2][1]-holeSize/2)+"em"
								style.width		= style.height		= holeSize+"em"
							}
						}
					}
					break;
				}
				case 'colors':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['colors.png'].src
							style.width		= "64em"
							style.height	= 48*8+"em"
							style.top	=
							style.left	= 0
							if( !currentOverlayTimeline[2] )
								currentOverlayTimeline[2]	= 512
						}
						else
						{
							style.top		= -48*Math.round(3.5+3.5*Math.cos( currentTime/256 ) )+"em"
						}
					}
					break;
				}
				case 'moomin':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['moomin.gif'].src
								z = 4+Math.cos(currentTime/512)
							style.width		= (z*5) +"em"
							style.height	= "48em"
							style.top	=	0
							style.left	= (43-z*4)+"em"
						}
						else
						{
							var
								z = 4+Math.cos(currentTime/512)
							style.width		= (z*5) +"em"
							style.height	= z+"em"
							style.top	=	(45-z/2)+"em"
							style.left	= (43-z*4)+"em"
						}
					}
					break;
				}
				case 'respect':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src	= imagesPreloaded[ "respect.gif" ].src
							style.width		=
							style.height	= "15em"
							style.height	= "15em"
							style.top	= "17.5em"
							style.left	= "24.5em"
						}
						else
						{
						}
					}
					break;
				}
				case 'neja_line_logo':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['neja_line_logo.png'].src
							style.width		= "42em"
							style.height	= "25em"
							style.top	= "11.5em"
							style.left	= "11em"
						}
						else
						{
						}
					}
					break;
				}
				case 'kanji':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['kanji.png'].src
							style.width		= "10em"
							style.height	= "16em"
							style.top	= "16em"
							style.left	= "27em"
						}
						else
						{
						}
					}
					break;
				}
				case 'sorryg':
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded['sorryg.gif'].src
							style.width		= "14em"
							style.height	= "4em"
							style.top	= "43em"
							style.left	= "64em"
						}
						else
						{
							style.left = ( 64-Math.abs(15*Math.sin( Math.PI*(currentTime-currentOverlayTimeline[i][0])/(timelines[ 'overlay'+i ][0][0]-currentOverlayTimeline[i][0]) ) ))+"em"
						}
					}
					break;
				}

				default:
				{
					with( overlayHandleArray['overlay'+i] )
					{
						if( newOverlay )
						{
							src = imagesPreloaded[currentOverlayTimeline[i][1]].src
							style.left		=
							style.top		= 0
							style.width		= "64em"
							style.height	= "48em"
						}
					}
					break;
				}
			}
			overlayHandleArray['overlay'+i].style.display = ""
		}
	}

	// update Fx
	if( !currentFxTimeline )
		currentFxTimeline=['']
	fxName	= currentFxTimeline[1]
	if( fxUpdateCallbackArray[ fxName ] )
	{
		fxUpdateCallbackArray[ fxName ]( currentTime-currentFxTimeline[0], currentFxTimeline[2] )
		customImageHandle.style.display=''
	}
	else
	{
		customImageHandle.style.display='none'
	}



	var
		currentTime = (new Date()).valueOf()
	timeDifference = currentTime-timeGlobal
	//top.document.title = "neja | "+ Math.round( 1000/timeDifference )+" fps"
	setTimeout( updateDemo, 1 )
	timeGlobal = currentTime
}



imagesToPreloadArray = [ "scrolling.gif", "neja_over.gif","ribbon+bomb.png","hole.png","credits.png", "black_plasma.png", 'colors.png', 'moomin.gif', 'respect.gif', 'neja_line_logo.png', 'void.gif' , 'squares.gif', 'kanji.png', 'sorryg.gif' ]
