var editor = new function () {
	this.recursive	= true;
	this.errorCL	= "error";
	this.jsErrorCL	= "errorJS";
	this.nToggledCL	= "notToggled";
	this.ToggledCL	= "Toggled";
	
	this.normalBG	= "FFFFFF";
	this.errorBG	= "FF0000";
	this.helpBG		= "0000FF";
	
	this.fadeTime	= 1000;
	this.fadeSteps	= 100;
		
	this.aniActive	= false;
		
	this.init = function () {
		var imgs = document.getElementsByTagName("img");
		for ( var c = 0; c < imgs.length; c++ ) {
			var elmID = imgs[c].id;
			if ( elmID.match(/^errorimg-/) ) {
				var re = /^errorimg-(.*)/;
				re.exec(elmID);
				var curID = RegExp.$1;
				imgs[c].onclick = new function( curID ) { return function() { editor.toggleMsg( curID ) } }( curID );
				
				var row = document.getElementById("row-" + curID);
				row.className = editor.jsErrorCL + " " + editor.nToggledCL;
				row.style.backgroundColor = "#" + editor.normalBG;
								
				if ( editor.recursive ) {
					for (var node in row.childNodes) {
						if ( row.childNodes[node].className == editor.errorCL ) {
							row.childNodes[node].className = editor.jsErrorCL;
						}
					}
				}
			}
		}
	}
		
	this.toggleMsg = function ( rowID ) {
		var row = document.getElementById("row-" + rowID);
		var inp = document.getElementById("input-" + rowID);
		var msg = document.getElementById("errormsg-" + rowID);
		
		if ( (msg.style.display == "none") || (msg.style.display == "") ) {
			var cl = row.className;
			cl = cl.replace(eval('/'+editor.nToggledCL+'/'), editor.ToggledCL);
			row.className = cl;
			this.animateElm(rowID, 1, cl);
			if ( inp ) inp.focus();
		} else {
			var cl = row.className;
			cl = cl.replace(eval('/'+editor.ToggledCL+'/'), editor.nToggledCL);
			this.animateElm(rowID, 0, cl);
			if ( inp ) inp.focus();
		} 	
	}
	
	// main function to process the fade request //
	this.colorFade = function (id,element,start,end,steps,speed) {
  		var startrgb,endrgb,er,eg,eb,step,rint,gint,bint,step;
  		var target = document.getElementById(id);
  		steps = steps || 20;
  		speed = speed || 20;
  		clearInterval(target.timer);
  		endrgb = this.colorConv(end);
  		er = endrgb[0];
  		eg = endrgb[1];
		eb = endrgb[2];
  		if(!target.r) {
			startrgb = this.colorConv(start);
			r = startrgb[0];
			g = startrgb[1];
			b = startrgb[2];
			target.r = r;
			target.g = g;
			target.b = b;
		}
		rint = Math.round(Math.abs(target.r-er)/steps);
		gint = Math.round(Math.abs(target.g-eg)/steps);
		bint = Math.round(Math.abs(target.b-eb)/steps);
		if(rint == 0) { rint = 1 }
		if(gint == 0) { gint = 1 }
		if(bint == 0) { bint = 1 }
		target.step = 1;
		target.timer = setInterval( function() { editor.animateColor(id,element,steps,er,eg,eb,rint,gint,bint) }, speed);
	}

	// incrementally close the gap between the two colors //
	this.animateColor = function (id,element,steps,er,eg,eb,rint,gint,bint) {
		var target = document.getElementById(id);
		var color;
		if(target.step <= steps) {
			var r = target.r;
			var g = target.g;
			var b = target.b;
			if(r >= er) {
				r = r - rint;
			} else {
				r = parseInt(r) + parseInt(rint);
			}
			if(g >= eg) {
				g = g - gint;
			} else {
				g = parseInt(g) + parseInt(gint);
    		}
			if(b >= eb) {
				b = b - bint;
			} else {
				b = parseInt(b) + parseInt(bint);
			}
			color = 'rgb(' + r + ',' + g + ',' + b + ')';
			if(element == 'background') {
				target.style.backgroundColor = color;
			} else if(element == 'border') {
				target.style.borderColor = color;
			} else {
				target.style.color = color;
			}
			target.r = r;
			target.g = g;
			target.b = b;
			target.step = target.step + 1;
		} else {
			clearInterval(target.timer);
			color = 'rgb(' + er + ',' + eg + ',' + eb + ')';
			if(element == 'background') {
				target.style.backgroundColor = color;
			} else if(element == 'border') {
				target.style.borderColor = color;
			} else {
				target.style.color = color;
			}
		}
	}

	// convert the color to rgb from hex //
	this.colorConv = function (color) {
		var rgb = [parseInt(color.substring(0,2),16), 
		parseInt(color.substring(2,4),16), 
		parseInt(color.substring(4,6),16)];
		return rgb;
	}
	
	this.animateElm = function (rowID, direction, cl) {
		var row = document.getElementById("row-" + rowID);
		var msg = document.getElementById("errormsg-" + rowID);
		
		var height = ( (msg.offsetHeight == 0) || (msg.offsetHeight > parseInt(msg.style.height)) ? parseInt(msg.style.height) : msg.offsetHeight );	
	    
	    //speed for each frame
	    var sSpeed = Math.round(editor.fadeTime / (height * 1.2));
	    var fSpeed = Math.round(editor.fadeTime / editor.fadeSteps);
	    var timer = 0;
	    
	    if ( (direction == 1) && (!this.aniActive) ) {
	    	this.aniActive = !this.aniActive;
	    	this.colorFade("row-" + rowID, "background", editor.normalBG, editor.errorBG, editor.fadeSteps, fSpeed);
	        for(i = 0; i <= height; i++) {
	            setTimeout("editor.changeSize(" + i + ",0," + height + ",'" + rowID + "','" + cl + "')",(timer * sSpeed));
	            timer++;
	        }
	    } else if ( (direction == 0) && (!this.aniActive) ) {
	    	this.aniActive = !this.aniActive;
	    	this.colorFade("row-" + rowID, "background", editor.errorBG, editor.normalBG, editor.fadeSteps, fSpeed);
	        for(i = height; i >= 0; i--) {
	            setTimeout("editor.changeSize(" + i + "," + height + ",0,'" + rowID + "','"  + cl + "')",(timer * sSpeed));
	            timer++;
	        }
	    }
	}

	this.changeSize = function (val, startVal, endVal, rowID, cl) {
		var row = document.getElementById("row-" + rowID);
		var msg = document.getElementById("errormsg-" + rowID);
		
		if ( val != endVal ) {
			msg.style.display = "block";
			msg.style.overflow = "hidden";
		}
		
	    msg.style.height = val + "px";
	    
	    if ( val == endVal ) {
	    	this.aniActive = !this.aniActive;
	    	
	    	if ( endVal == 0 ) {
	    		msg.style.display = "none";
	    		msg.style.height = startVal + "px";
	    		row.className = cl;
	    	} else if ( endVal > 0 ) {
	    		row.className = cl;
	    		msg.style.display = "block";
	    	}
	    }
	} 
}

window.onload = editor.init;