/* nested logic editor // 2006, Santiago Bustelo / livra.com */

var annoy=true;
function debug(msg){if(annoy){annoy=confirm(msg);};}




function mkSpanPreview(elm){
	var span = document.createElement("span");
	span.className = "preview " + elm.className; //el SPAN es preview + class del elemento
	span.appendChild(document.createTextNode( getText( elm ) ));
	var parentNode = elm.parentNode; 
	parentNode.insertBefore( span, elm )
}

function lockEditor(v){
	var fe=logicForm.elements;
	for(var i=0;i<fe.length;i++){
		if(fe[i].type!="button"){ fe[i].disabled=v;	}
	}

	if(v){
		AddClass(logicForm,'locked');

		//provide SPANS for preview
		var selects = $('logicGroup1').getElementsByTagName("select")
		for (var s = 0; s<selects.length; s++){
			mkSpanPreview(selects[s])
		}
		var inputs = $('logicGroup1').getElementsByTagName("text")
		for (var s = 0; s<inputs.length; s++){
			mkSpanPreview(inputs[s])
		}
		
		KillClass ( $('switch_editor'), "coder" );


	}else{
		KillClass(logicForm,'locked');
		//kill all #logicGroup1 SPANs:
		var spans = $('logicGroup1').getElementsByTagName("span")
		for (var s = spans.length-1; s>-1; s--){
			rmDOM(spans[s])
		}
		
		AddClass ( $('switch_editor'), "coder" );
	
	}
return false;
}


/* LOGIC EDITOR */
var qDB,logicForm;

function initLogicEditor(){
qDB=questDB.questions;logicForm=document.forms["logicform"];
var fe=logicForm.elements;

	//populate logicGroup0Eval1's questions
	var fop = fe["logicGroup0Eval1_question"];
	fop.options.length=0;
	fop.options[fop.options.length]=new Option('Select one...','NULL');

	for(var i=0;i<qDB.length;i++){
	   if(qDB[i]!=null){
	      fop.options[fop.options.length]=new Option(qDB[i].question.name,qDB[i].question.id);
      }
	}//end for
	
	getQuestionOptions(fop) //init logic0 submenus

addEvent(logicForm,"submit",preProcessLogic,false);

setvis('logicGroup0',0);

//$('logic_source').value=$('logicasXML_new').value
logicViewSource(0);
setvis('setNewLogic',1)

//if( ! (HasClass(logicForm,'locked') ) ){ lockEditor (false); }
lockEditor( (HasClass(logicForm,'locked') ) )
// coder();
}


function coder(){
	lockEditor(false); 
	AddClass ( $('switch_editor'), "coder" );
}


function getQuestionOptions(what){
if(what.selectedIndex==-1){what.selectedIndex=0;};
//	if(! what[what.selectedIndex] ){ return false; }

	var qid=(what[what.selectedIndex].value);
	var fe=logicForm.elements;
	var baseid = what.id.substring(0,what.id.indexOf('_question'));
	var fop = fe[baseid+"_options"];
	fop.options.length=0;
	var qP = resolveCSSpath(what,"<P");

	//remove previous qtype_ classes
	qP.className = qP.className.replace( /^qtype_\w*\b\s*|\s*\bqtype_\w*\b/g, '')

	var qidFound = false;
	if(qid!="NULL"){
		//search for question of ID in qDB
		for(var i=0;i<qDB.length;i++){
		if(qDB[i].question.id==qid){
			//populate question options
			var qiOpts = qDB[i].question.options;
			if(qiOpts&&qiOpts.length>0){
				for(var j=0;j<qiOpts.length;j++){
					fop.options[fop.options.length]=new Option(qiOpts[j].text,qiOpts[j].value);
					};
				};
	
			//set question type as classes of enclosing P	
			var qType = qDB[i].question.type.split(" ").sort()
			//assign new qtype_ class
			AddClass ( qP, "qtype_"+qType.join("_") );
			qidFound = true;
			break;
			}//end found id in qDB
		}//end for
	}else{
	AddClass ( qP, "qtype_null" );
	}


	
	if(!qidFound){
		what.selectedIndex = 0;
		AddClass ( qP, "qtype_null" );
	}

	copyValueToInput(fop);
}

function copyValueToInput(what){
var theInput=( resolveCSSpath(what,"< INPUT") )
var wi = what.selectedIndex
if(wi>-1){
	theInput.value = what[wi].value;
	}else{
	theInput.value = "";
	}
}


function preProcessLogic(e){   
	if(getvis('logic_editor_div')){
		var ok=parseLogicEditorToSource();
		//debug("parseLogicEditorToSource returned: "+ok )
	}
}





function logicViewSource(v){
if(getvis('logic_source_div')==v && getvis('logic_editor_div')!=v){
	var ok=confirm('You are already working in that mode.\n\nDo you want to restore the conditions defined in the other mode?')
	if(!ok){return false;}
	}

	if(v){//view source: translate logic_editor_div
		var ok=parseLogicEditorToSource();
	}else{//view editor: parse logic_source_div
		var ok=parseLogicSourceToEditor();
	}
	if(ok){
		setvis('logic_editor_div',!v);setvis('logic_source_div',v);
		setvis('assertion_new_h3',!v);
		}
	return false;
}



function tab(L){var t='\n';for(var i=0;i<L;i++){t+="  ";};return t;}

function parseLogicEditorToSource(){
var ok=true;
var source = '<assertion id="'+
	$('assertion_new_id').value +
	'">';
var elm = $('logicGroup1'); //resolveCSSpath( $('logic_editor_div'), 'BLOCKQUOTE' );
source += traverseLogicDOM( elm, 1 );

function traverseLogicDOM( elm, L ){
	var s="";
	var elmH4 =  resolveCSSpath(elm,'H4');
	var elmH4mode = getValue( resolveCSSpath(elm,'H4 SELECT') );
	s += tab(L) + '<group type="'+elmH4mode+'">';
	var children = elm.childNodes;

	for(var i=0;i<children.length;i++){
		var ci = children[i];
		var cn = ci.nodeName;
		if(cn=="P"){//process EVAL
		L++;
		s+= tab(L) +'<eval>';
		L++;
		s+= tab(L) + '<question id="' +
			getValue( resolveCSSpath(ci,'.logic_question') ) + '" />';

		s+= tab(L) + '<comparator type="'+
			getValue( resolveCSSpath(ci,'.logic_comparator') ) +'" />';

		var ciO1 = resolveCSSpath(ci,'.logic_options');
		var ciO1id = "";
		if(ciO1.length>0){ciO1id = getValue( resolveCSSpath(ci,'.logic_options') ); }

		s+= tab(L) + '<answer id="'+ ciO1id +'">'+
			getValue( resolveCSSpath(ci,'.logic_answer') ) +
			'</answer>'

		L--;
		s+= tab(L) + '</eval>'
		L--;
			}else if(cn=="BLOCKQUOTE"){//recursion
			s+= ( traverseLogicDOM(ci,L+1) )
			}
	}//end for i in children

	s += tab(L)+'</group>'
	return s;
}
source += '\n</assertion>'
if(ok){//parse OK, set textarea - how could it go wrong?
	$('logic_source').value=source
	}
return ok;
}


function spot(h,msg){
var msg=msg?msg:'spotted'
h=$(h)
if(annoy){
	AddClass(h,"spot")
	debug(msg)
	KillClass(h,"spot")
	}
	// CSS RULES: .spot{border:1px solid red;padding:2pt;background-color:#ffc}
}


function parseLogicSourceToEditor(){
	var theXMLtext = $('logic_source').value
	if(theXMLtext.length<92){//no XML, build default...
			theXMLtext = '<assertion name="" id=""><group type="any"><eval><question id="NULL"/><comparator type="EQ"/><answer id=""></answer></eval></group></assertion>';
/*		theXMLtext = '<assertion name="" id=""><group type="any"><eval><question id="'+qDB[0].question.id+'"/><comparator type="EQ"/><answer id=""></answer></eval></group></assertion>';*/
	}

	var logicXML=( parseXMLstring( theXMLtext ) )
	
	//get to first level and alert if not well-formed
	logicXML = logicXML.getElementsByTagName("assertion")[0];
	if(!logicXML){
		alert('XML syntax error.\n\nClick [code] to restore last XML version.');return false;}

//	$('assertion_new_name').value = logicXML.getAttribute('name');
	$('assertion_new_id').value = logicXML.getAttribute('id');
	
	//make template visible (for further clones)
	setvis('logicGroup0',1);

	//remove previous instances
	if( $('logicGroup1') ){ rmDOM( $('logicGroup1') ); }

	traverseSourceDOM(logicXML,  $('logic_editor_div') )

	function traverseSourceDOM(xml,h){
		for(var i=0;i<xml.childNodes.length;i++){
		var ei = xml.childNodes[i];
		
		switch( ei.nodeName.toLowerCase() ){

			case "group":
			var newGroupID = DOMcloneMake( $('logicGroup0'),h );

				newGroup = $(newGroupID)
				//remove template's P
				var oldP = resolveCSSpath(newGroup,"P");
				rmDOM(oldP)
				
				//set group type (any|all)
				var gtype = ei.getAttribute("type")
				var gtsel = resolveCSSpath(newGroup,"H4 SELECT");
				setValue(gtsel,gtype)
				setGroupAnyOrAll(gtsel)

				//recursion
				traverseSourceDOM(ei,newGroup)
				break;

			case "eval":
				var groupH5 = resolveCSSpath(h,"H5");
				var newP = DOMcloneMake( $('logicGroup0Eval1'), groupH5, "before" );
				var terms = ei.childNodes;
				for(var j=0;j<terms.length;j++){
				var tj=terms[j];
				
				switch( tj.nodeName.toLowerCase() ){
	
					case 'question':
						var tjid = tj.getAttribute('id')
						var pj = resolveCSSpath(newP,".logic_question");
						setValue(pj, tjid)
						getQuestionOptions(pj)
						break;
					case 'comparator':
						var tjtype = tj.getAttribute('type')
						var pj = resolveCSSpath(newP,".logic_comparator");
						setValue(pj, tjtype)
						break;
					case 'answer':
						var tjid = tj.getAttribute('id')
						var tjtext = "";
						if(tj.childNodes.length>0){
							tjtext = tj.firstChild.nodeValue;
							};
						var pj = resolveCSSpath(newP,".logic_options");
						setValue(pj, tjid)
						var pjt = resolveCSSpath(newP,".logic_answer");
						setValue(pjt, tjtext)
						break;
					default :
						break;
					}
				}

				break;
		}
	
		}
	}

	//hide template
	setvis('logicGroup0',0);

	return true;
}


function setGroupAnyOrAll(what){
var bq = resolveCSSpath(what,"<blockquote")
if(getValue(what)=="all"){
	AddClass(bq,"allof");
	}else{
	KillClass(bq,"allof");
	};
}



function addLogicItem(what){
var elm = resolveCSSpath(what,"<BLOCKQUOTE P:last");
if(!elm){
	elm = $('logicGroup0Eval1'); // resolveCSSpath(what,"<blockquote P")
	}
DOMcloneMake(elm,what.parentNode,'before')
return false;
}

function duplicateLogicItem(what){
var elm = resolveCSSpath(what,"<P");
DOMcloneMake(elm)
return false;
}

function rmLogicItem(what){
var elm = resolveCSSpath(what,"<P")
var bq = resolveCSSpath(elm,"<BLOCKQUOTE")
var bqLevel=resolveCSSpath(bq,"<BLOCKQUOTE")
//remove item
rmDOM(elm);
//if there are no sibling Ps, and this is a sub-level,
//recursively delete enclosing blockquotes
while(true){
	var bqhasP=resolveCSSpath(bq,"P")
	var bqLevel=resolveCSSpath(bq,"<BLOCKQUOTE")
	if(!bqhasP&&bqLevel){
		bq2 = resolveCSSpath(bq,"<BLOCKQUOTE")
		rmDOM(bq)
		bq=bq2
		}else{
		break;
		}
	}

return false;
}

function promoteLogicItem(what){

var thep = resolveCSSpath(what,"<p");
//clone logicGroup template at P
	var newdiv=DOMcloneMake( $('logicGroup0'),thep,'before' );
	var newdivP = resolveCSSpath(newdiv,'P')

//copy old P into template
	var newp = $( DOMcloneMake( thep,newdivP,'before' ) );
//remove template's P
	rmDOM(newdivP)
//remove old P
	rmDOM(thep)

setvis(newdiv,1);
return false;
}




function demoteLogicItem(what){
var bq = resolveCSSpath(what,"<BLOCKQUOTE");
//cant demote first level
if ( resolveCSSpath(bq,"<").tagName =="DIV"){ return false; }
var bqPs = bq.getElementsByTagName( 'P' );
for(var i=0;i<bqPs.length;i++){
	DOMcloneMake( bqPs[i],bq,'before' )
	}
rmDOM(bq)
return false;
}







function previewLayout(what){
var vi=what.selectedIndex
	var v=""
	if(vi>-1){
	var v=what[vi].value

		v_split=v.split("|")
		v = v_split[1]

	}	
$('layout_preview').src = "styles/"+v+"/screenshot.png"
}

function doPost(what,pair){
var p=pair?pair.split("="):false;
var theForm=( resolveCSSpath(what,"<FORM") )
if(p){theForm.elements[p[0]].value = p[1];}
theForm.submit();
return false;
}


function initFieldsets(){
//set TEXT of fieldlist options from VALUEs
var theForms=document.forms;
	for(var f=0;f<theForms.length;f++){
		var theForm= theForms[f];
		var felms = theForms[f].elements;
		for (var i=0;i<felms.length;i++){
			if(felms[i].name.indexOf("[]") == felms[i].name.length-2){//es una lista
			var theList = felms[i];
			var theListName = theList.name.substring(0,theList.name.length-2)
				var thformats=getFieldsetFormats(theForm,theList.name)
				for(var j=0;j<theList.options.length;j++){//loop in list OPTIONs
					var thvalues=SplitPipedVars(theList[j].value)
					var thvObj = new Object();
					for(var b=0;b<thvalues.length;b+=2){//parse pairs into thvObj
						thvObj[ thvalues[b] ] = thvalues[b+1]
					}
				ftext = thformats[0];
				ftext = ftext.replace( /\$\$([a-z0-9-_]*)/gi, ' getTextFromValue ( theForm [theListName+\'-$1\'] , thvObj [\'$1\'] ) ' );
				ftext = ftext.replace( /\$([a-z0-9-_]*)/gi, ' thvObj[\'$1\'] ');
				ftext=eval ( ftext );				
				theList[j].text = ftext;
				}//end for j in options
				theList.selectedIndex = -1;
				updateBmod(theForm,theListName)
			}//end es una lista
		}//end for in form
	}//end for in forms
}

function processFieldsets(what,dosubmit){
var dosubmit=dosubmit?dosubmit:false;
	var felms = what.elements;
	for (var i=0;i<felms.length;i++){
		if(felms[i].name.indexOf("[]") == felms[i].name.length-2){//es una lista
			for(var j=0;j<felms[i].options.length;j++){
				felms[i].options[j].selected=true;
			}//end for j in options
		}//end es una lista
	}//end for
if(dosubmit){ 
	what.submit(); }
}

function colExpAll(v){
return false;
}

function gotoAddNewItem(what, survey, step){
	if (what[what.selectedIndex].value < 0) 
		document.location="design_edit.php?s="+ survey +"&step="+ step +"&action=newdescription";
	else		
		document.location="design_edit.php?s="+ survey +"&step="+ step +"&action=newquestion&type="+what[what.selectedIndex].value;
}

function confirmLink(what){return confirm(what.title);}

function getFieldsetFormats(theForm,theField){//return text,value formats
theField=cleanFieldName(theField);
return new Array(theForm[theField+"-textformat"].value,theForm[theField+"-valueformat"].value);
}

function cleanFieldName(theField){
if(theField.indexOf("[]")==theField.length-2){theField=theField.substring(0,theField.length-2);}
return theField;
}

/* fieldset LISTs */
function getFieldlistName(whatname){
	var thn=whatname.split("-");
	var theField=thn[0];var theInput=thn[1];
	return new Array(theField,theInput)
}





function bdo(what){//process fieldset buttons
var theForm=( resolveCSSpath(what,"<FORM") )
var thn=getFieldlistName(what.name);
bdo2(theForm,thn[0],thn[1]);
return false;
}

function keyBadd(what,e){
var k=(e==null?event.keyCode:e.which);// Get the keycode from IE or Mozilla
if(k==13){
	var theForm=( resolveCSSpath(what,"<FORM") );
	var thn=getFieldlistName(what.name);
	bdo2(theForm,thn[0],'tadd',what);
	if(e&&e.preventDefault){e.preventDefault();}else{return false;}//DOM vs IE
	}
}


function bdo2(theForm,theField,theAction,what){
var what = what?what:false;
	var editsel=theForm[theField+"[]"];

	if(theAction=="bup"){
		MoveSelected(editsel,0);
	}else if(theAction=="bdw"){
		MoveSelected(editsel,1);
	}else if(theAction=="brm"){
		RemoveSelected(editsel);emptyFieldVars(theForm,theField);
	}else if(theAction=="badd"||theAction=="bmod"||theAction=="tadd"){
		var fFormats = getFieldsetFormats(theForm,theField);
		var fvars = fFormats[1].split("|");
		var ftext = fFormats[0];
		var fvalue=new Array();
		for(var i=0;i<fvars.length;i++){//encode values into OPTION
			var fviSSS = fvars[i].lastIndexOf("$");// $id vs. $$id
			var fviName=fvars[i].substring(fviSSS+1);
			var fvinput = theForm.elements [ theField+"-"+fviName ];

			if(fviSSS==0){ //value
				if(theAction=="badd"&&fviName.indexOf('_unique')>-1){
				var fviValue = "";//no duplicamos valores de vars '_unique', como ID_unique, etc
				setValue(fvinput,"");
				}else{
				var fviValue = getValue(fvinput);
				};
			}else{//text
				fviName = "$$" + fviName;
				var fviValue = getText(fvinput);
			};
			fvalue[fvalue.length]=fviName+":"+fviValue;
		};
		fvalue=fvalue.join("|");
		
		ftext = ftext.replace( /\$\$([a-z0-9-_]*)/gi, 'getText(theForm.elements[theField+"-$1"])');
		ftext = ftext.replace( /\$([a-z0-9-_]*)/gi, 'getValue(theForm.elements[theField+"-$1"])');

		ftext=eval ( ftext );

//OK, ready to badd/bmod value
if(theAction!="tadd"){editsel.focus();} //focus select, unless entering text
		if(theAction=="badd"||theAction=="tadd"){
			editsel.options.length++;
			editsel.options[editsel.options.length-1].value=fvalue;
			editsel.options[editsel.options.length-1].text=ftext;
			editsel.selectedIndex=editsel.options.length-1;
		}else if(theAction=="bmod"){
			editsel.options[editsel.selectedIndex].value=fvalue;
			editsel.options[editsel.selectedIndex].text=ftext;
		};

	updateBmod(theForm,theField);
	if(theAction=="tadd"){what.value="";};
	
	}else{//other actions?
		alert("Oops! Could not follow action: "+theAction);
	};
return false;
}//end fn


function gotoIfNewlogic(what){
	var theForm = what.form;
	var theList = getFieldlistName(what.name)[0];
	var theListIx = theForm.elements[ theList+"[]" ].selectedIndex;

	if(theListIx==-1){
		alert('Please select an answer choice to which the new logic should be applied.')
		what.selectedIndex=0
		return false;
	}else{//there is an answer selected in the list

		if(what[what.selectedIndex].value!="new"){
			
			// <!-- S.O.S.
			what.form.elements["addlogictoelement"].value = theList+" : "+theListIx;
			//y posteamos
			processFieldsets(theForm,true)			
			// --> S.O.S.
			
			//a pre-defined logic was selected, nothing to do there
			return false;
		}else{
			//cargamos en el HIDDEN "addlogictoelement" el item al que se quiere agregar nueva logica
			what.form.elements["addlogictoelement"].value = theList+" : "+theListIx;
			//y posteamos
			processFieldsets(theForm,true)
		}

	}
}


function debugFieldlistClick(what){prompt("debug info => selected value:",what[what.selectedIndex].value);}

function getFieldlistClick(what){
	if(what.selectedIndex>-1){
		loadFieldlistItem(what,what.selectedIndex);
	}else{//nothing selected here, empty field vars
		emptyFieldVars(what.form,what.name);
	};
}

function loadFieldlistItem(theList,theItem){
	var EditForm=( resolveCSSpath(theList,"<FORM") );
	var theField=theList.name.substring(0,theList.name.length-2) //cortamos el "[]" del nombre de la lista
	var thvalues=SplitPipedVars(theList[theItem].value)
	for(var b=0;b<thvalues.length;b+=2){//parse pairs into edit fields
		if(EditForm[theField+"-"+thvalues[b]]){//exists edit field for var?
			var fb=EditForm[theField+"-"+thvalues[b]]
			var thfvat=fb.type;
				if(thfvat=="text"||thfvat=="hidden"){//thfvat is text or hidden
					fb.value=thvalues[b+1]
				}else if(thfvat.indexOf("select")>-1){//thfvat is select	
					setSelect(fb,thvalues[b+1])
				}else if(thfvat=="checkbox"){
//					if(annoy)annoy=confirm( thvalues[b] + " >>> " + thvalues[b+1] )
					fb.checked=(thvalues[b+1]==true)?1:0
				}//end thfvat
			}//exists edit field
		}//end for b
	updateBmod(EditForm,theField)
}//end fn

function updateBmod(theForm,theField){//disable "modify" button if no item is selected in list
	theField=cleanFieldName(theField);
	theForm[theField+"-bmod"].disabled=!(theForm[theField+"[]"].selectedIndex>-1)
}

function emptyFieldVars(theForm,theField){
	var theField=cleanFieldName(theField)
	var fFormats = getFieldsetFormats(theForm,theField);
	var fvars = fFormats[1].split("|");

	for(var b=0;b<fvars.length;b++){
		var fviSSS = fvars[b].lastIndexOf("$");// $id vs. $$id
		var fviName=fvars[b].substring(fviSSS+1);
		if(fviSSS==0){//dont process $$id
			var fb=theForm[theField+"-"+fviName]
			switch(fb.type){
				case "text"||"hidden":
					fb.value="";
					break;
				case "select-one"||"select-multiple":
					break;
			}//end switch
		var thfvat=fb.type;
			if(thfvat=="text"||thfvat=="hidden"){//thfvat is text or hidden
				fb.value=""
			}else if(thfvat.indexOf("select")>-1){//thfvat is select	
				fb.selectedIndex=-1
			}else if(thfvat=="checkbox"){
				fb.checked=0;
			}//end thfvat
		}//end fviSSS==0
	}//end for b
//	theForm[theField+"-bmod"].disabled=true
}

function SplitPipedVars(thv){
	//input: pipe+: encoded values
	//output: paired array
var r=new Array;
var thvals=thv.split("|")
for(var i=0;i<thvals.length;i++){
	var thvi=thvals[i]
	if(thvi.lastIndexOf("$")==-1){//ignore $$textvars
		var rspix=thvi.indexOf(":")
		if(rspix==-1){alert('Syntax error in value pair declaration: '+thv+'\nFormat must be name1:value1|name2:value2 (...)');}
		r[r.length]=thvi.substring(0,rspix)
		r[r.length]=thvi.substring(rspix+1)
		}//end ignore $$textvars
	}//end for
	return r;
}



/* FORM input/select value fns */

function getValue(fvinput){
var fvinput=$(fvinput);
var fviValue;
	switch(fvinput.type){
	case "text"||"hidden"||"textarea":
		fviValue=fvinput.value
		break;
	case "checkbox":
		fviValue=fvinput.checked?1:0
		break;
	case "radio":
		break;
	case "select-one":
		var sx = fvinput.selectedIndex;
		if(sx<0)return false;
		fviValue=fvinput[sx].value
		break;
	}
return fviValue;
}

function gCheck(what){
o=resolveCSSpath( what, '<LI INPUT' );
o.checked=true;
}

function setValue(s,v){
	switch(s.type){
	case "text"||"hidden"||"textarea":
		s.value=v
		break;
	case "checkbox":
		s.checked=v
		break;
	case "radio":
		break;
	case "select-one":
		setSelect(s,v)
		break;
	}
}

function getText(fvinput){
var fviValue="";
	switch(fvinput.type){
	case "select-one":
		if( fvinput[fvinput.selectedIndex] )
		fviValue=fvinput[fvinput.selectedIndex].text
		break;
	default:
		fviValue=fvinput.value
	}
return fviValue;
}

function getTextFromValue(s,v){
var so=s.options
for(var i=0;i<so.length;i++){
	if(so[i].value==v){return so[i].text;}
	}//end for
}

function setSelect(s,v){//set selectedIndex on s to the one holding value
var so=s.options
for(var i=0;i<so.length;i++){
	if(so[i].value==v){
		s.selectedIndex=i;return;
		}//end if so
	}//end for
//value was not found
if(v==""){	//try again recursively using "0"
	setSelect(s,"0")
	}else{
	s.selectedIndex=-1;
	}
}


/* DOM fns */

function rmDOM(elm){return elm.parentNode.removeChild(elm);}

function parseXMLstring(xmlString){
//Cross Browser Solution from http://nexgenmedia.net/evang/iemozguide/
//var xmlString = "<xml id=\"xmldataisland\"><foo>bar</foo></xml>";
var myDocument;
    if(window.ActiveXObject){
	  // IE, create a new XML document using ActiveX
	  // and use loadXML as a DOM parser.
	  myDocument = new ActiveXObject("Microsoft.XMLDOM")
	  myDocument.async="false";
	  myDocument.loadXML(xmlString);
	}else if(document.implementation.createDocument){
	  // Mozilla, create a new DOMParser
	  var parser = new DOMParser();
	  myDocument = parser.parseFromString(xmlString, "text/xml");
	}else{
	  myDocument=false;
	}
	return myDocument;
}


//event handlers
//from http://www.scottandrew.com/weblog/articles/cbs-events
function addEvent(obj,evType,fn,useCapture){if(obj.addEventListener){obj.addEventListener(evType,fn,useCapture);return true;}else if(obj.attachEvent){var r=obj.attachEvent("on"+evType,fn);return r;}else{window.status="Handler could not be attached";};} 
function removeEvent(obj,evType,fn,useCapture){if(obj.removeEventListener){obj.removeEventListener(evType,fn,useCapture);return true;}else if(obj.detachEvent){var r=obj.detachEvent("on"+evType,fn);return r;}else{window.status="Handler could not be removed";};}


function setvis(l,v){$(l).style.display = v?"":"none";}
function getvis(l){return !($(l).style.display=="none");}


function resolveCSSpath(e,c){
var e=$(e);
c=c.split(" ");

for(var i=0;i<c.length;i++){
	var cis = c[i].split(":")
	var num = cis[1]?cis[1]:"0"
	var ci=cis[0]

	if(ci=="<"){
		e=e.parentNode;
	}else if(ci.charAt(0)=="#"){
		e=document.getElementById( ci.substring(1) );
		if(!e){return false;};
	}else if(ci.charAt(0)=="."){
	var a=e.childNodes;var t=ci.substring(1);var d=false;
		for(var b=0;b<a.length;b++){
		if(HasClass(a[b],t)){d=a[b];break;};
		};
		if(d){e=d;}else{return false;};
	}else if(ci.charAt(0)=="<"){
		e=FindTagClassUp(e.parentNode,ci.substring(1),"BODY");
		if(!e){return false;};
	}else{
	var a = e.getElementsByTagName( ci.toLowerCase() );
		if(a.length>0){
			if(num=="0"){e=a[0];
			}else if(num=="last"||num>a.length){
			e=a[a.length-1]
			}else{
			e=a[num]
			}
		}else{
			var a = document.getElementsByName(ci);
			if( a[0] ){ e=a[0]; }else{return false;};
		};
	};
	};
	return e;
};

function FindTagClassUp(elm,tcsearch,tclimit){

var tc=(tcsearch+".").split(".");tc[0]=tc[0].toUpperCase();
if(!tclimit){tclimit="BODY";};
var tz=(tclimit+".").split(".");tz[0]=tz[0].toUpperCase();
	while(n=elm.nodeName){
		if(tc[0]==""||n==tc[0]){
			if(tc[1]==""||HasClass(elm,tc[1])){return elm;};};
		if(tz[0]==""||n==tz[0]){
			if(tz[1]==""||HasClass(elm,tz[1])){return false;};};
		elm=elm.parentNode;
	};
	//dump("CANNOT GET NODENAME: ",elm);
	return false;
};



function DOMcloneMake(molde,donde,posicion){
var parentobj = molde.parentNode;
var copia=molde.cloneNode(true);
var mid=molde.id
var mida = mid.replace(/(\d+)/gi, "|$1|").split("|")
//loop until we find an unused ID
var midaz= Number(mida[mida.length-2]);var newid;
while(true){
	mida[mida.length-2] = midaz++;
	newid = mida.join("")
	if(!document.getElementById(newid)){
	break;
	}
	}
//assign new IDs to clone's ID & children elements
//copia.id=newid
grepIDs(copia,new RegExp(mid, "gi"),newid)

		function grepIDs(e,oldid,newid){
		if(e.id){ 
			e.oldid = e.id;
			e.id = e.id.replace(oldid,newid); }
		if(e.name){ e.name = e.name.replace(oldid,newid); }
		if(e.type&&e.id!=""){//set VALUEs of form items with ID
			setValue( e, getValue(e.oldid) )
			}
		//gonna find childnodes
		var kids=e.childNodes
		if(kids){//recursion for child nodes
				for(var i=0;i<kids.length;i++){
				grepIDs(kids[i],oldid,newid)
				}//end for
			}//end if kids
		}//end grepIDs
//add element to document

KillClass(copia,"first")

var donde=donde?donde:parentobj
var posicion=posicion?posicion:'after'
if(posicion=='after'){
donde.appendChild(copia)
}else if(posicion=='before'){
donde.parentNode.insertBefore(copia,donde)
}
//parentobj.insertBefore(copia,molde.nextSibling);
	/*Element.hide(copia)
	new Effect.Appear(copia);*/
/*if( $(newid) ){
	Element.hide($(newid))
	new Effect.Appear($(newid));
}*/

return newid;
}




//prototype $ function
function $(){var elements = new Array();for(var i=0;i<arguments.length;i++){var element=arguments[i];if(typeof element=='string'){element = document.getElementById(element);};if(arguments.length==1){return element;};elements.push(element);};return elements;}

//*** This code is copyright 2002-2003 by Gavin Kistner and Refinery; www.refinery.com
//*** It is covered under the license viewable at http://phrogz.net/JS/_ReuseLicense.txt
function AddClass(obj,cName){KillClass(obj,cName);return obj&&(obj.className+=(obj.className.length>0?' ':'')+cName);}
function KillClass(obj,cName){return obj&&(obj.className=obj.className.replace(new RegExp("^"+cName+"\\b\\s*|\\s*\\b"+cName+"\\b",'g'),''));}
function HasClass(obj,cName){return(!obj||!obj.className)?false:(new RegExp("\\b"+cName+"\\b")).test(obj.className);}

/* SELECT fns*/

/*********************************************
* RemoveSelected - Removes all selected\
* options from sel
*********************************************/
function RemoveSelected(sel){
	var sl = sel.selectedIndex;

	if (sl != -1){
	for(var i=0; i<sel.options.length; i++){
		if (sel.options[i].selected){
		sel.options[i] = null;
		i--;
		}//end is selected
	}//end for
	}else{/*no items selected*/
	}//end if
}//end fn

/*********************************************
* MoveSelected - Moves the selected item in
* a select based upon option:
* 0 - Move selected option up one
* 1 - Move selected option down one
* 2 - Move selected option to top
* 3 - Move selected option to bottom
*********************************************/
function MoveSelected(sel,option){
var sl = sel.selectedIndex;
var txt;
var val;

if (sl != -1 && sel.options[sl].value > ""){
txt = sel.options[sl].text;
val = sel[sl].value;
switch(option){
case 0: // moves an option up in the select
if (sel[sl].value > "" && sl > 0){
sel[sl].text = sel[sl-1].text;
sel[sl].value = sel[sl-1].value;
sel[sl-1].text = txt;
sel[sl-1].value = val;
sel.selectedIndex--;
}
break;
case 1: // moves an option down in the select
if (sl < sel.length-1 && sel[sl+1].value > ""){
sel[sl].text = sel[sl+1].text;
sel[sl].value = sel[sl+1].value;
sel[sl+1].text = txt;
sel[sl+1].value = val;
sel.selectedIndex++;
}
break;
case 2: // moves an option to top of select
if (sel[sl].value > "" && sl > 0){
sel.options[sl] = null; // delete our selection
sel.options.length++; // add a new option at the end
// reorder all entries from bottom to top
for (var i = sel.options.length - 2;i >= 0 ;i--){
sel.options[i+1].text = sel.options[i].text;
sel.options[i+1].value= sel.options[i].value;
}
sel.options[0].text = txt;
sel.options[0].value= val;
sel.selectedIndex=0;
}
break;
case 3: // moves an option to bottom of select
if (sl < sel.length-1 && sel[sl+1].value > ""){
sel.options[sl] = null; // delete our selection
sel.options.length++;
sel.options[sel.length-1].text = txt;
sel.options[sel.length-1].value= val;
sel.selectedIndex=sel.length-1;
}
break;
}
}
//else // no item selected
}

/*********************************************
* TradeSelected - Swaps selected items from
* one select to another
* from - Select to trade from
* to - Select to trade to
* allow_dups - Allows duplicate values in to
* if the from selected item value already
* exists in to options
* remove_from - Removes add item from from when 
* added to to
*********************************************/
function TradeSelected(from,to,allow_dups,remove_from){
var sl = from.selectedIndex;
var txt;
var val;

if (sl != -1 && from.options[sl].value > ""){
txt = from.options[sl].text;
val = from[sl].value;
if (!allow_dups){
for(i = 0; i < to.options.length; i++){
if (to.options[i].value==val){
//alert('The select item already exists');
return;
}
}
}
// copys to to at the end
to.options.length++
to.options[to.options.length-1].value=val;
to.options[to.options.length-1].text=txt;

// removes from from
if (remove_from)
from.options[sl] = null;
}
else{
//alert('Please select an item');
}

}