var TFX_FADE		= 0;
var TFX_MACHINE		= 1;

var TFXS_IN			= 0;
var TFXS_INWAIT		= 1;
var TFXS_OUT		= 2;
var TFXS_OUTWAIT	= 3;

function TextFX(xHtmlObjID, xText, xDrawType, xSpeed){
	var vRet = {
		HtmlObject:document.getElementById(xHtmlObjID), Text:xText,
		DrawType:xDrawType, Speed:xSpeed, CurrentSnt:'', PadString:'_',
		TextPos:0, CurrentStep:TFXS_OUTWAIT, IncValue:0, IncValue2:0, WaitCount:0,
		nextSentence:function(){
			if(this.Text.Length == this.TextPos) this.TextPos = 0;
			var nIndex = this.Text.indexOf('\r\n', this.TextPos);
			if(nIndex < 0) nIndex = this.Text.Length;
			var xRet = this.Text.substring(this.TextPos, nIndex);
			this.TextPos = nIndex + 2;
			return xRet;
		},
		rotateString:function(xStr){
			if(xStr.length < 2) return xStr;
			var xChar = xStr.charAt(0);
			return xStr.substring(1, xStr.length) + xChar;
		},
		doStepOuter:function(pThis){ if(!pThis) pThis = document.getElementById(xHtmlObjID).pThis; pThis.doStep(); },
		doStep:function(){
			if(this.CurrentStep == TFXS_INWAIT){
				if(this.WaitCount++ > 25) this.CurrentStep = TFXS_OUT;
			}else if(this.CurrentStep == TFXS_OUTWAIT){
				if(this.WaitCount++ > 10){
					this.CurrentStep = TFXS_IN;
					this.CurrentSnt = this.nextSentence();
				}
			}else this.WaitCount = 0;
			switch(this.DrawType){
			case TFX_FADE:
				switch(this.CurrentStep){
				case TFXS_IN:
					if(this.IncValue == 0) this.HtmlObject.innerHTML = this.CurrentSnt;
					this.HtmlObject.style.filter= 'alpha(opacity=' + this.IncValue + ')';
					this.HtmlObject.style.opacity = (this.IncValue / 100);
					this.IncValue += ((100 - this.IncValue) >> 1) + 1;
					if(this.IncValue == 100) this.CurrentStep = TFXS_INWAIT;
					break;
				case TFXS_OUT:
					this.HtmlObject.style.filter= 'alpha(opacity=' + this.IncValue + ')';
					this.HtmlObject.style.opacity = (this.IncValue / 100);
					this.IncValue -= (this.IncValue >> 1) + 1;
					if(this.IncValue == 0) this.CurrentStep = TFXS_OUTWAIT;
					break;
				}
				break;
			case TFX_MACHINE:
				switch(this.CurrentStep){
				case TFXS_IN:
					this.PadString = this.rotateString(this.PadString);
					var vPadLen = this.CurrentSnt.length - ++this.IncValue;
					if(vPadLen > this.PadString.length) vPadLen = this.PadString.length;
					this.HtmlObject.innerHTML = this.CurrentSnt.substring(0, this.IncValue) + (this.IncValue == this.CurrentSnt.length ? ' ' : this.PadString.substring(0, vPadLen));
					if(this.IncValue == this.CurrentSnt.length) this.CurrentStep = TFXS_INWAIT;
					break;
				case TFXS_OUT:
					this.HtmlObject.innerHTML = ''; this.IncValue = 0;
					this.CurrentStep = TFXS_OUTWAIT; this.WaitCount = 0;
					break;
				}				
				break;
			}
		},
		start:function(){
			if(window.event) window.setInterval(this.doStepOuter, this.Speed);
			else window.setInterval(this.doStepOuter, this.Speed, this);
		}
	}
	vRet.HtmlObject.pThis = vRet;
	vRet.start();
	return vRet;
}
