var matrix = {
    context : {
	isRandom : true,
	streamWord : "",
	fontSize : 16,
	streamSize : 13,
	slideTimers : [],
	randomWord : "",
	opacity : 0.4
    },

    show : function() {
	this.timeClear();
	this.inBase();
	var div = document.getElementById('__matrix__');
	var diff = this.context.streamSize - div.childNodes.length;
	if(diff < 0) {
	    this.deleteSrider(-diff);
	} else {
	    this.makeSrider(diff);
	}
	if(!this.context.slideTimer) {
	    var elms = [];
	    var nodes = [];
	    var cnt = 0
	    var streamDiv = 15;
	    for(var i=0,len=div.childNodes.length;i<len;i++) {
		nodes.push(div.childNodes[i]);
	    }
	    var timeLine = Math.ceil(nodes.length/streamDiv);
	    if(timeLine == 1) {
		this.context.slideTimers.push(setInterval(function(){matrix.slide(nodes), ++cnt}, 10));
		return this;
	    }
	    var last = 1;
	    var slice1 = nodes.slice(0*streamDiv, ((0+1)*streamDiv));
	    this.context.slideTimers.push(window.setInterval(function(){matrix.slide(slice1, ++cnt)}, 10));
	    if(timeLine >= 3) {
		var slice2 = nodes.slice(1*streamDiv, ((1+1)*streamDiv));
		this.context.slideTimers.push(window.setInterval(function(){matrix.slide(slice2, ++cnt)}, 10));
		last = 2;
	    }
	    if(timeLine >= 4) {
		var slice3 = nodes.slice(2*streamDiv, ((2+1)*streamDiv));
		this.context.slideTimers.push(window.setInterval(function(){matrix.slide(slice3, ++cnt)}, 10));
		last = 3;
	    }
	    if(timeLine >= 5) {
		var slice4 = nodes.slice(3*streamDiv, ((3+1)*streamDiv));
		this.context.slideTimers.push(window.setInterval(function(){matrix.slide(slice4, ++cnt)}, 5));
		last = 4;
	    }
	    var slice = nodes.slice(last*streamDiv);
	    this.context.slideTimers.push(setInterval(function(){matrix.slide(slice, ++cnt)}, 10));
	}
	return this;
    },

    makeSrider : function(srideSize) {
	if(!(div = document.getElementById('__matrix__'))) return;
	for(var i=0;i<srideSize;i++) {
	    var slider = document.createElement('div');
	    this.initStream(slider);
	    div.appendChild(slider);
	}
	return this;
    },

    deleteSrider : function(srideSize) {
	if(!(div = document.getElementById('__matrix__'))) return;
	for(var i=0;i<srideSize;i++) {
	    if(div.childNodes[0]) {
		div.removeChild(div.childNodes[0]);
	    }
	}
	return this;
    },

    timeClear : function() {
	if(div = document.getElementById('__matrix__')) {
	    document.body.removeChild(div);
	}
	for(var i=0,len=this.context.slideTimers.length;i<len;i++) {
	    clearInterval(this.context.slideTimers[i]);
	}
	this.context.slideTimers = [];
	return this;
    },

    slide : function(elms, slideIndex) {
	if(!slideIndex || slideIndex > 10000000) slideIndex = 0;
	if(!(div = document.getElementById('__matrix__'))) return;
	var max = parseInt(div.style.height, 10);
	for(var i=0,len=elms.length;i<len;i++) {
	    var top = parseInt(elms[i].style.top, 10) + parseInt(elms[i].getAttribute('__speed'), 10);
	    if((top + parseInt(elms[i].clientHeight, 10)) > max) {
		this.initStream(elms[i]);
		break;
	    }
	    elms[i].style.top = top + 'px';
	    if(!(slideIndex%(parseInt(elms[i].getAttribute('__change'), 10)))) {
		this.changeStream(elms[i]); 
	    }
	}
	return this;
    },

    inBase : function() {
	if(document.getElementById('__matrix__')) return this;
	var e =document.createElement("div");
	e.setAttribute('id', '__matrix__');
	var wid = document.body.scrollWidth;
	var hei = document.body.scrollHeight;
	e.style.cssText = "position:absolute; top:0; left:0; width:"+ wid +"; height: "+ hei +";background-color:black;";
	e.style.cssText += "filter:alpha(opacity="+ (this.context.opacity*100) +"); -moz-opacity:"+ this.context.opacity +"; opacity:"+ this.context.opacity +";";
	document.body.appendChild(e);
	return this;
    },

    initStream : function(elm) {
	var t = ~~(Math.random() * 400) - 600;
	var l = ~~(Math.random() * document.body.scrollWidth);
	var s = ~~(Math.random() * 30) + 20;
	var f = ~~(Math.random() * 10) + this.context.fontSize;
	var c = ~~(Math.random() * 30) + 3;
	var w = ~~(Math.random()*20) + 20;
	elm.innerHTML = "<b>";
	elm.setAttribute('__speed', s);
	elm.setAttribute('__change', c);
	elm.setAttribute('__word', w);
	elm.style.cssText = 'position:absolute; top:'+ t +'px; left:'+ l +';font-size:'+ f +'px;';
	this.changeStream(elm);
	elm.innerHTML += "</b>"
	return this;
    },

    changeStream : function(elm) {
	var stWord = this.getStreamWord(parseInt(elm.getAttribute('__word'), 10));
	var colorPalet = [{color16 : "#333333", rate: 0.1}, {color16:"#006600", rate:0.4}, {color16:"#00cc00", rate:0.4}, {color16:"#ffffff"}];
	elm.innerHTML = "";
	for(var i=0,len=colorPalet.length,odd=stWord.length;i<len;i++) {
	    var r =0;
	    r = ~~(stWord.length*colorPalet[i].rate);
	    if(i==(len-1))r = odd;
	    var e = document.createElement("span");
	    e.style.color = colorPalet[i].color16;
	    e.innerHTML = this.appendBr(stWord.substr((stWord.length-odd), r));
	    odd -= r;
	    elm.appendChild(e);
	}
	return this;
    },

    appendBr : function(str) {
	return (str.split('').join('</br>'))+"</br>";
    },

    getStreamWord : function(randomSize) {
	if(this.context.isRandom) {
	    if(!randomSize) randomSize = ~~(Math.random()*10) + 5;
	    var target = document.body.innerHTML;
	    var max = target.length;
	    if(this.context.randomWord != "") {
		target = this.context.randomWord;
		max = target.length;
	    }
	    return target.substr(~~(Math.random()*max), randomSize);
	}
	this.context.randomWord = "";
	return this.context.streamWord;
    },

    setRandomWord : function(str) {
	this.context.randomWord = str;
	this.context.isRandom = true;
	return this;
    },

    random : function() {
	this.context.randomWord = "";
	this.context.isRandom = true;
	return this;
    },

    setWord : function(str) {
	this.context.randomWord = "";
	this.context.streamWord = str;
	this.context.isRandom = false;
	return this;
    },

    setStreamSize : function(size) {
	this.context.streamSize = size;
	return this;
    },

    setFontSize : function(size) {
	this.context.fontSize = size;
	return this;
    }
}

