var oMatrix;

//***************************************************************************************
//
// Matrix
//
//***************************************************************************************

	//oDebug.bActive = true;

	function initMatrix (nRows, nCols, nLeft, nTop, bInteractive) {
		oMatrix = new Matrix (nRows, nCols, nLeft, nTop, bInteractive);
	}

	function Matrix (nRows, nCols, nLeft, nTop, bInteractive) {
		this.nCols  			= nCols;
		this.nRows  			= nRows;
		this.nElemSize		= 50;
		this.aPageOffset	= new Array(nLeft, nTop);
		this.aMatrix 			= new Array();
		this.oCursorElem	= null;
		this.bMouseActive	= false;
		this.bDone				= true;
		this.bInteractive	= bInteractive;
		this.oOldonMouseMove	= null;
		this.bSuspend			= true;
		this.oUpdateTimeout = null;
		this.aOnLoad				= null;
		this.aActionPos		= [1, 1];
		this.aActions			= [];
		this.bBlendSound  = false;
		this.bScrollSound = false;
		
		for (var i=0; i<this.nRows; i++) {
			this.aMatrix[i] = new Array();
			for (var j=0; j<this.nCols; j++)
				this.aMatrix[i][j] = new MatElem (this, i, j);
		}
		
		this.onPageLoad	= function () {
			this.oLayer = getLayer ('Matrix');
			var cHtml = '';
			for (var i=0; i<this.nRows; i++) {
				for (var j=0; j<this.nCols; j++) 
					cHtml += '<img name="M' + i + '_' + j + '" src="img/d' + this.aMatrix[i][j].nSize + '.gif" width="50" height="50">';
				cHtml += '<br>';
			} 
			cHtml = '<nobr>' + cHtml + '</nobr>';
			this.oLayer.replaceContent (cHtml);
			this.oLayer.moveTo (this.aPageOffset[0], this.aPageOffset[1]);
	
			for (var i=0; i<this.nRows; i++)
				for (var j=0; j<this.nCols; j++) 
					this.aMatrix[i][j].oImg = getDocumentImage ('M' + i + '_' + j);
			this.bSuspend = false;
			this.update();
			
			if (this.aOnLoad != null) {
				setTimeout ('oMatrix.act(oMatrix.aOnLoad)', this.aOnLoad[3]);
				if (this.aActions) setTimeout ('oMatrix.randomAction()', this.aOnLoad[3] + this.nActionTimeout);
			}
			else if (this.aActions)
				setTimeout ('oMatrix.randomAction()', this.nActionTimeout);
		};
		
		this.invalidate = function (bInvalidateAll) {
			var bStartUpdate = (this.bDone);
			this.bDone = false;
			if (bInvalidateAll) {
				for (var i=0; i < this.nRows; i++)
					for (var j=0; j < this.nCols; j++)
						this.aMatrix[i][j].invalidate();
			}
			if (bStartUpdate & !this.bSuspend) this.update();
		};
		
		this.activateMouse = function (bActive) {
			if (this.bInteractive) {
				if (bActive) {
					if (document.layers) this.aOldcaptureEvents = document.captureEvents (Event.MOUSEMOVE);
	// 				this.oOldonMouseMove = document.onmousemove;
					document.onmousemove = Matrix__onMouseMove;
					
					this.bMouseActive = true;
				}
				else {
					if (document.layers) document.captureEvents (this.aOldcaptureEvents);
	//				document.onmousemove = this.oOldonMouseMove;
					this.bMouseActive = false;
					if (this.oCursorElem) this.oCursorElem.onMouseOut();
				}
			}
		};
	
		this.onMouseMove = function (oEvent) {
			var aPos = new Array(oEvent.nLeft - this.aPageOffset[0] - (this.nElemSize/2), oEvent.nTop - this.aPageOffset[1] - (this.nElemSize/2));
			var aCursorPos = new Array(Math.round (aPos[0] / this.nElemSize), Math.round (aPos[1] / this.nElemSize));
			if (this.oCursorElem == null || (aCursorPos[0] != this.oCursorElem.aPos[0] || aCursorPos[1] != this.oCursorElem.aPos[1])) {
				if (this.oCursorElem) {
					this.oCursorElem.onMouseOut();
					this.oCursorElem = null;
				}
				if (aCursorPos[0] >= 0 && aCursorPos[0] < this.nCols && aCursorPos[1] >= 0 && aCursorPos[1] < this.nRows) {
					this.oCursorElem = this.aMatrix[aCursorPos[1]][aCursorPos[0]];
					this.oCursorElem.onMouseOver();
				}
			}											
		};

		this.update	= function () {
			var bChanges = false;
			for (var i=0; i < this.nRows; i++) 
				for (var j=0; j < this.nCols; j++) 
					if (!this.aMatrix[i][j].bDone) bChanges = this.aMatrix[i][j].update() || bChanges; 
	
			this.bDone = !bChanges	
			if (bChanges & !this.bSuspend) this.oUpdateTimeout = setTimeout ('oMatrix.update()', 100);
		};

		this.clear = function (nTop, nLeft, nRows, nCols) {
			for (var i=0; i < Math.min(nRows, this.nRows-nTop) ; i++)
				for (var j=0; j < Math.min(nCols, this.nCols-nLeft); j++) 
					this.aMatrix[nTop + i][nLeft + j].set (0);
		};
		
		this.copy = function (nTop, nLeft, nRows, nCols, nTargetTop, nTargetLeft) {
			for (var i=0; i < nRows; i++)
				for (var j=0; j < nCols; j++) 
					this.aMatrix[nTargetTop + i][nTargetLeft + j].set (this.aMatrix[nTop + i][nLeft + j].nSize);
			// Muß noch verallgemeinert werden, indem der Quellbereich zunächst gesichert wird.		
		};

		this.setChar = function (nTop, nLeft, aCharMatrix) {
			var nRows = aCharMatrix.length;
			var nCols = aCharMatrix[0].length;
			for (var i=0; i < Math.min(nRows, this.nRows-nTop); i++)
				for (var j=0; j < Math.min(nCols, this.nCols-nLeft); j++)
					this.aMatrix[nTop+i][nLeft+j].set (aCharMatrix[i][j]);
		};

		this.setText = function (nTop, nLeft, cText) {
			var nPosLeft = nLeft;
			for (var n=0; n<cText.length; n++) {
				var cChar = cText.substr (n, 1);
				var aCharMatrix = getZeichen (cChar);
				this.setChar (nTop, nPosLeft, aCharMatrix);
				nPosLeft += aCharMatrix[0].length;
			}
		};
		
		this.blendText = function (nTop, nLeft, cText, nSpeed) {
			if (!this.bSuspend) {
				if (this.oTimerBlend == null) this.onBlendStartStop (true);
			
				var aCharMatrix = getZeichen (cText.charAt(0));
				this.clear (nTop, nLeft, aCharMatrix.length, aCharMatrix[0].length);
				this.setChar (nTop, nLeft, aCharMatrix);
				cText = cText.substr(1);
	
				if (cText.length > 0) 
					this.oTimerBlend = setTimeout ('oMatrix.blendText(' + nTop + ',' + nLeft + ',\'' + cText + '\',' + nSpeed + ')', nSpeed);
				else {
					this.oTimerBlend = null;
					this.onBlendStartStop (false);
				}
			}
			else
				this.oTimerBlend = setTimeout ('oMatrix.blendText(' + nTop + ',' + nLeft + ',\'' + cText + '\',' + nSpeed + ')', 1000);
		};

		this.scrollText = function (nTop, cText, nSpeed, nCharCol) {
			if (!this.bSuspend) {
				if (this.oTimerScroll == null) this.onScrollStartStop (true);
				if (nCharCol == null) nCharCol = 0;
				var aCharMatrix = getZeichen (cText.charAt(0));
				this.copy (nTop, 1, this.nRows-nTop, this.nCols-1, nTop, 0);
				for (var i=0; i < Math.min(aCharMatrix.length, this.nRows-nTop); i++) 
					this.aMatrix[nTop + i][this.nCols-1].set (aCharMatrix[i][nCharCol]);
				
				if (nCharCol < aCharMatrix[0].length-1)
					nCharCol++;
				else {
					nCharCol=0;
					cText = cText.substr(1);
				}
				
				if (cText.length > 0) 
					this.oTimerScroll = setTimeout ('oMatrix.scrollText ('+ nTop + ',\'' + cText + '\',' + nSpeed + ',' + nCharCol + ')', nSpeed);
				else {
					this.oTimerScroll = null;	
					this.onScrollStartStop (false);
				}
			}
			else
				this.oTimerScroll = setTimeout ('oMatrix.scrollText ('+ nTop + ',\'' + cText + '\',' + nSpeed + ',' + nCharCol + ')', 1000);			
		};

		this.interruptAnimations = function () {
			clearTimeout (this.oTimerScroll);
			clearTimeout (this.oTimerBlend);
			this.oTimerScroll = null;
			this.oTimerBlend = null;
			this.onBlendStartStop (false);
			this.onScrollStartStop (false);
		};

		this.suspend = function (bSuspend) {
			this.bSuspend = bSuspend;
			if (bSuspend) {
				clearTimeout (this.oUpdateTimeout);
				this.interruptAnimations();
			}
			else {
				for (var i=0; i < this.nRows; i++) 
					for (var j=0; j < this.nCols; j++) 
						this.aMatrix[i][j].nSize = 0;
				this.oUpdateTimeout = setTimeout ('oMatrix.update()', 100);
			}	
		};

		this.onBlendStartStop = function (bStart) {
			if (bStart != this.bBlendSound) {
	//			oDebug.write ('Blend ' + (bStart ? 'start' : 'stop'));
				
				if (oSound){
					bgSound = (bStart ? "fadeIn" : "fadeOut");
					oSound.play("bobbles", "", bgSound);
				}
				this.bBlendSound = bStart;
			}
		};
		
		this.onScrollStartStop = function (bStart) {
			if (bStart != this.bScrollSound) {
	//			oDebug.write ('Scroll ' + (bStart ? 'start' : 'stop'));
	
				if (oSound){
					bgSound = (bStart ? "fadeIn" : "fadeOut");
					oSound.play("bobbles", "", bgSound);
				}
	
				this.bScrollSound = bStart;
			}
		};

		this.act = function (aAction) {
			if (aAction) {
				var cAction = 'this.';
				var cText = aAction[1];
				if (cText.substr(cText.length-2) == ' .') cText = cText.substr(0, cText.length-1);
				switch (aAction[0]) {
					case 1: 
						cAction = cAction + 'scrollText(' + this.aActionPos[0] + ',"' + cText + '",' + aAction[2] + ')';
						break;
					case 2: 
						cAction = cAction + 'blendText(' + this.aActionPos[0] + ',' + this.aActionPos[1] + ',"' + cText + '",' + aAction[2] + ')';
						break;
				}
				eval (cAction);
			}
		};

		this.addAction = function (nType, cText, nSpeed) {
			this.aActions[this.aActions.length] = [nType, cText, nSpeed];
		}
		
		this.randomAction	= function (aActions) {
			if (aActions) this.aActions = aActions;
			var nAction = Math.floor(Math.random()*(this.aActions.length-1));
			var nTime = Math.floor(Math.random()*10) * 3000;
		
			if (!this.bSuspend && !this.oTimerBlend && !this.oTimerScroll) {
	//			oDebug.write ('Matrix.randomAction: ' + cAction);
				this.act (this.aActions[nAction]);
			}
			setTimeout("oMatrix.randomAction()", nTime);
		};

	}

	function Matrix__onMouseMove(e) {
		if (!oMatrix.bSuspend) oMatrix.onMouseMove (new UEvent (window.event ? window.event : e));
		if (oMatrix.oOldonMouseMove) oMatrix.oOldonMouseMove();
	}
	
	
//***************************************************************************************
//
// MatElem (MatrixElement)
//
//***************************************************************************************
function MatElem (oMatrix, nRow, nCol) {
	this.oMatrix 		= oMatrix;
	this.aPos 			= new Array (nCol, nRow);
	this.oImg 			= null;
	this.nSize			= 0;
	this.bMouseOver	= false;
	this.bDone			= true;
	
	this.onMouseOver = function () {
		this.bMouseOver = true;
		this.invalidate();
	};

	this.onMouseOut	= function () {
		this.bMouseOver = false;
		this.invalidate();
	};
	
	this.invalidate	= function () {
		this.bDone = false;
		if (this.oMatrix.bDone) this.oMatrix.invalidate();
	}

	this.update = function () {
		if (this.oImg) {
			var cSrc = this.oImg.src;
			var nSize = 0 + eval (cSrc.substr(cSrc.length-5, 1));
			var nBestSize = (this.bMouseOver ? 7 : this.nSize);
			if (nSize != nBestSize) {
				nSize = (nSize > nBestSize ? Math.max(0, nSize-1) : Math.min(15, nSize+1));
	//			if (this.bMouseOver && oSound) oSound.playMouse (nSize);
		
				cSrc = cSrc.substr(0, cSrc.length-5) + nSize + '.gif';
				this.oImg.src = cSrc;
				if (this.bDone && nSize != nBestSize) this.invalidate();
			}	
			else
				this.bDone = true;	
		}	
		return (!this.bDone);
	};
	
	this.set = function (nSize) {
		if (nSize != this.nSize) {
			this.nSize = nSize;
			this.invalidate();
		}
	};

}	
	
	
function getDocumentImage (cImageName) {
	var oImg = document.images[cImageName];
	if (oImg == null && document.layers) 
		for (var i=0; i<document.layers.length; i++) {
			oImg = document.layers[i].document.images[cImageName];
			if (oImg != null) return (oImg);
		}
	return (oImg);
}

