/**
 * @namespace mom.jscss
 * @author patcla   
 */

/** @id JsCSS */
function JsCSS(){
	
	// methods
	this.processAnchors			= ProcessAnchors;
	this.processImages			= ProcessImages; 
	this.processDivs			= ProcessDivs; 
	this.processLists			= ProcessLists; 
	this.processTables			= ProcessTables; 
	this.processForms			= ProcessForms; 
	this.init					= Init;
	this.processExternal		= ProcessExternal;
	this.markAsProcessed		= MarkAsProcessed;
	this.getElementArray		= GetElementArray;
	
	// params
	this.namespace				= 'js';	
	this.runflag				= 'run'; // flag to signify that processing has taken place 
	this.useexternalmethods		= true; // use built in methods only
	this.i						= 0;
	this.version				= 1.1;
	
/**
 * Object, returns an array of HTML objects 
 * @id JsCSS.GetElementArray
 * @alias GetElementArray
 * @memberOf JsCSS
 * @param {String} element id
 * @param {String} html tag
 * @return {Array}
 */	
	/** @id JsCSS.GetElementArray */
	function GetElementArray(id,tag,shallow){
		var els = new Array;
		if (shallow){
			els[0] = ( document.getElementById(id) ) ? document.getElementById(id) : ( document.forms[id] ) ? document.forms[id] : (document.frames[id]) ? document.frames[id] : null ;
		} else if (id && document.getElementById(id)) {
			els = document.getElementById(id).getElementsByTagName(tag);
			if (window.loader) loader.logger.log('JSCSS: processing '+els.length+' '+tag+' elements in ['+ id +']');
		} else {
			els = document.getElementsByTagName(tag);
			if (window.loader) loader.logger.log('JSCSS: processing '+els.length+' '+tag+' elements in [document]');
		}		
		return els;	
	}
	
	/** @id JsCSS.MarkAsProcessed */
	function MarkAsProcessed(el,mthd){
		var activeNS = this.namespace +':'+ mthd; 
		var inactiveNS = this.namespace + this.runflag+':'+ mthd; 
		el.className = el.className.replace(activeNS,inactiveNS);
	}

	/** @id JsCSS.ProcessExternal */
	function ProcessExternal(el){
		if (!this.useexternalmethods){return;} // disable external comands
		el = (typeof el == 'object') ? el : document.getElementById(el);
		if (!el){return;}
		var tempArray = new Array;
		var tempName = new String;
		if (el.className.match(this.namespace+':')){
			var classnames = el.className.split(' ');
			for (var i = 0; i < classnames.length ; i++){
				if (classnames[i].match(this.namespace+':')) {
					tempArray = classnames[i].substring(this.namespace.length+1).split('_');
					tempArray.push(''); // add an empty entry so it has at least two		
					try {
						if (tempArray[0] && eval('window.'+tempArray[0]) && eval('window.'+tempArray[0]+'.jscss') ){
							eval('window.'+tempArray[0]+'.jscss')(el,tempArray[1].replace(/'/g,"\'"));
							jscss.markAsProcessed(el,tempArray[0]);
						} else {
							if (window.logger) {logger.log('JSCSS: could not attach window.' + tempArray[0] + ' because it does not exist, or does not have a '+ tempArray[0] +'.jscss() method');}
						}
					} catch (e){
						if (window.logger) {logger.error(e,'JSCSS: problem attaching function, check window.'+ tempArray[0] +'();' );}
					}

				}
			}
		}
	}


	/** @id JsCSS.Init */
	function Init(opts){
		//TODO: build init method
	}

	/** @id JsCSS.ProcessAnchors */
	function ProcessAnchors(id,shallow){
		var els,tempid;
		var els = this.getElementArray(id,'A');
		// not marking anchor tags as processed, as they may need to be done again
		// in the quickinfolite
		for (var i =0;i<els.length;i++){
			if (els[i].className.match(this.namespace+':')){
				/* exmalpe builtin method */
				if (els[i].className.match(this.namespace+':external')){
					AttachExternal(els[i]);
				}
				if (els[i].className.match(this.namespace+':false')){
					el.onclick = el.onkeypress = function(){return false;};
				}
				jscss.processExternal(els[i]);
			}
		}	
		
		function AttachExternal(el){
			if (!el.title || el.title == ''){
				el.title = 'Opens in a new window'; 
			} else {
				el.title+= ': opens in a new window'; 
			}
			el.onclick = el.onkeypress = function(){window.open(this.href)};
		}	
			
	}
	

	/** @id JsCSS.ProcessImages */
	function ProcessImages(id,shallow){
		var tempid;
		var els = this.getElementArray(id,'IMG');
		for (var i =0;i<els.length;i++){
			if (els[i].className.match(this.namespace+':')){
				if (els[i].className.match(this.namespace+':roll')){
					AttachRoll(els[i]);
				}
				jscss.processExternal(els[i]);
			}
		}

		/** @id JsCSS.ProcessImages.AttachRoll */
		function AttachRoll(el){
			el.onfocus = el.onmouseover= function (){this.src=this.src.replace(/_1/,'_2')}; 
			el.onblur = el.onmouseout = function (){this.src=this.src.replace(/_2/,'_1')};
		}
	}

	/** @id JsCSS.ProcessDivs */
	function ProcessDivs(id,shallow){
		var tempid;
		var els = this.getElementArray(id,'DIV',shallow);
		if (!els){return;}
		for (var i =0;i<els.length;i++){
			if (els[i].className.match(this.namespace+':')){
				jscss.processExternal(els[i]);
			}
		}				
	}

	/** @id JsCSS.ProcessLists */
	function ProcessLists(id,shallow){
		
		var uls = this.getElementArray(id,'UL',shallow); ;
		var ols = this.getElementArray(id,'OL',shallow) ;
		var dls = this.getElementArray(id,'DL',shallow) ;
		
		if (uls && uls.length){InterrogateList(uls,this.namespace);}
		if (ols && ols.length){InterrogateList(ols,this.namespace);}
		if (dls && dls.length){InterrogateList(dls,this.namespace);}		
		
		function InterrogateList(els,namespace) {
			var tempid,subels;
			for (var i = 0;i<els.length;i++){
				if (!els[i] || !els[i].tagName){continue;}
				if (window.logger && i==0) logger.log('JSCSS: testing list types '+ els[0].tagName );
				
				jscss.processExternal(els[i]);
				
				subels = els[i].getElementsByTagName('LI');
				if (subels && subels.length) {InterrogateListItems(subels,namespace);}
				subels = els[i].getElementsByTagName('DD');
				if (subels && subels.length) {InterrogateListItems(subels,namespace);}
				subels = els[i].getElementsByTagName('DT');
				if (subels && subels.length) {InterrogateListItems(subels,namespace);}
			}

			function InterrogateListItems(subels,namespace){
				for (var ii = 0;ii<subels.length;ii++){
					if (subels[ii].className.match(namespace+':')){
						if (subels[ii].className.match(namespace+':menu')){
							AttachMenu(subels[ii],namespace);
						}
						jscss.processExternal(subels[ii]);
					}				
				}	
				
				// anchor attachments Menu
				function AttachMenu(el,namespace){
					jscss.markAsProcessed(el,'menu');
					if (window.logger) logger.log('JSCSS: menu found at '+ el.tagName );
					el.className = el.className.replace(/stage/,''); // remove stage (i.e close menu)
					var a = el.getElementsByTagName('A')[0];
					if (a){
						a.listItem = el;
						if (a.href == '') {a.href = '#';};
						a.onclick = a.onkeypress = function(){
							// toggles menu by adding/removing 'stage' from the list item class name
							if (this.listItem.className.match('stage')) {
								this.listItem.className = this.listItem.className.replace(/stage/,'').replace(/  /,' ');
								if (window.transition){
									transition.dropFirstChildClose(this.listItem,'ul');
								}
							} else {
								this.listItem.className+= ' stage';	
								if (window.transition){
									transition.dropFirstChild(this.listItem,'ul','auto',1,20);
								}
							}
							this.blur();
							return false;
						}
					}
				}						
								
			}

										
		}
		
	}	
	
	/** @id JsCSS.ProcessTables */
	function ProcessTables(id,shallow){
		var els = this.getElementArray(id,'TABLE',shallow) ;	
		if (!els){return;}
		for (var i =0;i<els.length;i++){
			if (els[i].className.match(this.namespace+':alternaterows')){
				AttachAlternateRows(els[i]);
			}
			if (els[i].className.match(this.namespace+':')){
				jscss.processExternal(els[i]);
			}
		}		
		
		/** @id JsCSS.ProcessTables.AttachAlternateRows */
		function AttachAlternateRows(el){
			jscss.markAsProcessed(el,'alternaterows');
			var root = (el.getElementsByTagName('TBODY')) ? el.getElementsByTagName('TBODY')[0] : el ;
			var node = root.getElementsByTagName('TR')[0];
			var odd = true;
			while (node){
				if (node && (node.type != 1) && node.tagName == 'TR'){
					if (!node.getElementsByTagName('TD')) {odd=true;}// set all TH rows as odd
					node.className+= (odd) ? ' odd' : ' even';	
					odd = !odd;
				}
				node = (node.nextSibling) ? node.nextSibling : null;
			}
		}		
				
	}	
	/** @id JsCSS.ProcessForms */
	function ProcessForms(id,shallow){
		var els = this.getElementArray(id,'FORM',shallow) ;	
		if (!els){return;}
		for (var i =0;i<els.length;i++){
			if (els[i].className.match(this.namespace+':')){
				jscss.processExternal(els[i]);
			}
		}						
	}	
	
}

var jscss = new JsCSS;

if ( window.loader && window.jscss ){
	function initJsCss(){
		// example process everything (not neccessarily a good idea)
		jscss.processAnchors();
		jscss.processImages();
		jscss.processDivs();
		jscss.processLists();
		jscss.processTables();
		jscss.processForms();
	}	
	window.loader.oncontentready(initJsCss);
}
