// JavaScript Document
// MODIFIED 1/31/7 CMW THIS NEEDS PROTOYPE.JS, SO INCLUDE MASTER.JS IN THE CALLING PAGE BEFORE
//INCLUDING THIS
/* CONTENTS

emptyValue - used to validate that values are entered into a field

dspAll/dsp - expandable/collapsible fields

dropDownSubmit - submits a form if the value of the passed dropdown isn't -1

showTab - show/hide tabs for vertical tabs

ajaxDropDown - called from a dropdown inside of a div to replace that content 
                div with the contents of the AJAX call. It is depending on the
                class of one of the parent divs to be "tabContent"
                
setEls - sets this value in the links of other elements on the page to help maintain context 
        for browsing, etc.
        
clearEls - clears this value in case a default must be set

getHTML - AJAX code to grab data for a tab content div

tabExists - passed a value that should correspond to the innerHTML of a subsection tab
    and returns true or false depending on if it is found or not
    
getDefaultTab - gets the default (topmost, non control) tab value in order to retrieve
                the AJAX info
   
contSwitch/contIncr/contDecr - functions to swap divs in a container tag                

set of functions near end for fade-in/fade-out animations
the same source site also has some other nifty effects

*/

// for form validations 
	function emptyValue(fieldName) {
		
		/*get the length of the passed field
		 a length greater than one indicates that there is more than 
		 one element with the same name, which is a radio button 
		 loop through each passed field and also check the type 
		 if it's a select, we have to make sure that at least one option is selected
		 another option is to discount the first index of the option array in the case of that being taken 
		 by informational text. e.g., "Choose an option Below" */
		
		validFlag = false;
		
		for (i=0;i<fieldName.length;i++) {
			
			if((fieldName[i].type == "radio" || fieldName[i].type == "checkbox") && fieldName[i].checked) {
				validFlag = true;
				break;
				}
			
			//the below handles multiple select fields
			//specify single select in the first if clause
			//and change j to 1 in order to make sure that 
			//the second or higher element in a list is selected
			
			if(fieldName[i].type.indexOf("select") > -1) {
			
				for(j=0;j<fieldName[i].options.length;j++){
					
					if(fieldName[i].options[j].selected) {
						validFlag = true;
						break;
						}
					
					}
			
				}
				
			if(fieldName[i].type.indexOf("text") > -1 || fieldName[i].type.indexOf("password") > -1 ) {
			
				if(fieldName[i].value.length){
					
					validFlag = true;
					break;
					
					}
			
				}
			
			}
			
			return validFlag;
		
		}
		
// end field validation 



// for expandable sections

function dsp(contentId,link){
   if(document.getElementById){
   link.innerHTML=link.innerHTML=='+'?'-':'+';
     foc = document.getElementById(contentId);
     foc.style.display=foc.style.display=='block'?'none':'block';
     foc.style.opacity='1.0';
     foc.style.filter="alpha(opacity=100)";
    }
 }  


function dspAll(sourceArray,link,action) {
		
        /* link is in the original code; action added 4/20/7 cmw
        to allow us to specify an action to take - specifically 
        this is to allow all sections to be collapsed in the event
        that the page is swapped out in the container */
        
        /*if action is defined, use that as testLink */
        
		var testLink = action? action : link.innerHTML=='+'?'+':'-';
		
		for(i=0;i < sourceArray.length; i++) {
			var passLink = document.getElementById(sourceArray[i]+'_link');
			
			if(passLink.innerHTML == testLink) {
					dsp(sourceArray[i],passLink);
				}
			
			}
		
        //only change the top link if action was not passed	
		if(!action) {
       	    link.innerHTML=link.innerHTML=='+'?'-':'+';
        }
        //otherwise, make sure that it is a plus sign
        else {
            link.innerHTML="+";
        }

}
	
// end expandable sections

//form submission from a dropdown

function dropDownSubmit(argForm,argValue) {

	if(argValue!=-1) argForm.submit();
}


//next related functions are for showing and hiding the tab sections of the
//mol pages (and any other pages that may use this code)	
//show/hide tabs
//tab is the content
//list is the list of tabs
//els are any links on the page that should have their href or action (in the case of a form) 
//modified with the tab and list hash

//show the tab
function showTab(theTab,listID,contentId,els,ajaxInfo) {

    //loop counter
    var x;
	
	/* changed 9/20/8 CMW to now reference the href - this is what will contain the value passed to the server
    //value of the link
    var linkValue = theTab.innerHTML;
	*/
	
	//value of the link
	//split to remove any full path that the browser prepends
	var linkTokens = theTab.href.split("/");
	var linkValue = linkTokens[linkTokens.length-1]; 
	
    //get the list element
    var listItem = $(listID);
 
    //get list element siblings
    var listSiblings = listItem.parentNode.childNodes;

    //loop through the list siblings, turn all off and turn tab on
    for(x=0;listSiblings[x];x++){
    //skip over classNames that begin with "header", because these are header tabs and should be left alone
        listSiblings[x].className = listSiblings[x].className.indexOf("header")==0?listSiblings[x].className:"inactive";

        //check the order of this tab and save it to be
        //passed to the setEls function so that we can
        //correctly set to molsubsection variable
        
        //changed 3/13/7 cmw to use the text value instead of a number
        //in order to get this to work with journal titles 
        //which are variable in nature
        //if(listSiblings[x].id==listID) tabOrder=x+1;
        if(listSiblings[x].id==listID) {
            tabOrder = linkValue;
        }
    }
    
    listItem.className = "active";
    
    //instantiate object to use AJAX

    var myContentEl = new ContentEl(contentId,ajaxInfo,linkValue);
    
    //call the method to make the AJAX call and update the HTML
    myContentEl.getHTML();
    
    //call function to set appropriate links
    setEls(els,tabOrder);
    
}

function ajaxDropdown(theDropdown,ajaxInfo,subsection){

//declare local vars
    var dropVal,    //value of the dropdown
        contDiv,    //the content div
        myContentEl,//the instance of the ContentEl class
        i,          //counter
        ajaxHash    //hash to hold ajax info
        
//get the content div - it's a parent node of the dropdown with
//a class name of tabContent
    contDiv = theDropdown;
    
    while (contDiv.className !== "tabContent"){
        contDiv = contDiv.parentNode;
    }

//add the name of the dropdown field and its value as a param to
//the AJAX call. Keep in mind that this will have an effect on whatever
//server piece is used to generate the content
    ajaxHash = ajaxInfo;
    ajaxHash.params += ajaxHash.length? "&" + theDropdown.name + "=" + $F(theDropdown) : 
        theDropdown.name + "=" + $F(theDropdown);
    
//instantiate the ContentEl class
    myContentEl = new ContentEl(contDiv,ajaxHash,subsection);
    
//call the getHTML method
    myContentEl.getHTML();

}

//object to hold state info on a content div being updated with Ajax
var ContentEl = Class.create();

ContentEl.prototype = {

    initialize: function(contentId,ajax,linkValue){
        this.contentDiv = $(contentId); //content element
        this.ajax = ajax;               //ajax options defined in getHTML
        this.linkValue = linkValue;     //value of the link that will be used as the subsection
    },

    getHTML: function(){

        //arguments are defined as follows:
        //contendId = id of the target div to be updated
        //ajax is an object
            //contains the following:
            //server: the server of the target request
            //path: the path to the resource
            //paramType:    passThru means to pass the existing URL as one of the params
            //              explicit means to pass only what's listed in params
            //params: any parameters to pass as well as a list sep'd by &'s
        //linkValue = the value of the link that called this. It will be passed to the url
        
        var url,    //proxy page in CF to allow cross domain calls
            hAjax,  //hash of the ajax object
            pars;   //parameters to be passed to the AJAX request
            
        url = '/utils/proxy.cfm';
        
        hAjax = $H(this.ajax);  //this might not be necessary since I'm not using any specific hash functions
    
        pars = "";    
        pars+= "server=" + hAjax.server;
        pars+= "&path=" + hAjax.path;
        pars+= "&linkValue=" + this.linkValue;
        pars+= hAjax.paramtype === "passThru" ? "&url=" + escape(location.href) : "";
        pars+= hAjax.params.length ? "&" + hAjax.params : "";

        //show loading animation
        this.showLoader();
        
        //call AJAX
        var myAjax = new Ajax.Updater(
                    this.contentDiv,
                    url, 
                    {
                        method: 'get', 
                        parameters: pars, 
                        onFailure: this.reportError,
                        evalScripts: true
                        
                    });
        },

       reportError: function() {
           alert('An AJAX error occurred. If you are seeing this, please send an email to admin@nursa.org and accept our apologies in advance.');
        },
        
                       
        showLoader: function() {
            var divHTML;    //HTML for the loading div
                
            divHTML = "<div style = 'font-weight: bold;'>";
            divHTML+= "Loading...<br/><img src = '/images/circle-ball-dark-antialiased.gif'/>";
            divHTML+= "</div>";
        
            //draw the loading div
            this.contentDiv.innerHTML = divHTML;
        }
}; 
    
//set the molsubsection variable in the passed list of element Ids
//that way, we can automagically get return to it when the page is launched
//this should be done as a variable, but I don't have time to do it that way now (as always)
function setEls(els,tabOrder){
    
    //split the list into an array and go through it
    var aElList = els.split(",");
    
    //the literal that should be a variable
    var queryVar = "molsubsection";
    
    for(i=0;aElList[i]; i++){
    	//check to see if the element is available
    	if(document.getElementById(aElList[i])){
    	
    	//if so, test to see if it has an href or an action
    	var testEl = document.getElementById(aElList[i]);
    	//replace the molSubsection with the computed values above
    		if(testEl.href){
    			if(testEl.href.toLowerCase().indexOf(queryVar)>=0){
    				testEl.href = stripVar(testEl.href,queryVar);
    				}
    			testEl.href+=(testEl.href.indexOf("?")>=0)?"&"+queryVar+"="+tabOrder:"?"+queryVar+"="+tabOrder;
    			}
    		else if(testEl.action){
    			if(testEl.action.toLowerCase().indexOf(queryVar)>=0){
    				testEl.action = stripVar(testEl.action,queryVar);
    				}
    			testEl.action+=(testEl.action.indexOf("?")>=0)?"&"+queryVar+"="+tabOrder:"?"+queryVar+"="+tabOrder;
    			alert(testEl.action);

    		}
    		
    		else if(testEl.value){
    			testEl.value=tabOrder;
    		}
    
    	}
    }
}

function clearEls(theQueryparam) {

    //get all links - so, this won't currently work on dropdowns, like for orthologs
        /* the below works in FF and IE but not Safari. Thanks, Apple 
    var links = $A(document.getElementsByTagName("a")); //all links

    //loop through all links and strip theQueryparam from them

    links.each (
    function fixLink(theAnchor) {
            theAnchor.href = stripVar(theAnchor.href,theQueryparam);
        }
        );
        */
        
    var links = document.getElementsByTagName("a");
    var i = 0;
    var theAnchor; 
    
    for (i = 0; i < links.length; i=i+1) {
        theAnchor = links[i];
        theAnchor.href = stripVar(theAnchor.href,theQueryparam);
    }
    
}

//takes a url and strips the target query variable
function stripVar(toStrip,target){
	//strip out querystring 
	var parsedHref = toStrip.split("?");
	
	//if there is a query string, run the rest; other wise, return it unchanged
	if(parsedHref.length > 1){
		var parsedQString = parsedHref[1].split("&");
		var i = 0;
		var j = -1;

		//loop parsedQString the array and delete the target, then join it back up again
		for(i=0;parsedQString[i];i++){
			if(parsedQString[i].toLowerCase().indexOf(target.toLowerCase())>=0) j=i;
		}
		
		if(j>=0) parsedQString.splice(j,1);
		
		parsedHref = parsedHref[0]+"?"+parsedQString.join("&");
		
		}
		
	return (parsedHref);
}

function tabExists(tabName) {

//declare local vars

var arTheUls,       //ul items with a class of "tabs", which hold the tabs
    theEl;          //the returned element if found, or null if not
    
//get all ULs with a class of tabs, go through the anchor tags (which are tabs)
//and check for an innerHTML that equals the tab name
    arTheUls = document.getElementsByClassName("tabs");
    theEl = arTheUls.detect(
        function (theUl) {
            var arTheAs,//the anchor tags
                theEl;  //the element if found, null if not
                
            arTheAs = $A(theUl.getElementsByTagName("a"));
            theEl = arTheAs.detect(
                function (theA) {
                    return theA.innerHTML.toLowerCase() === tabName.toLowerCase();
                }
            )
            return theEl;
        }
    );

    return theEl;

}

function getDefaultTab(theQueryparam) {

//declare local vars

var arTheUls,       //ul items with a class of "tabs", which hold the tabs
    arTheAs,        //array of anchor tags in the UL
    theEl,          //test anchor element
    i;              //counter
    

//get all ULs with a class of tabs, go through the anchor tags (which are tabs)
//and check for an innerHTML that equals the tab name
    arTheUls = document.getElementsByClassName("tabs");
    
    for(i = 0; i < arTheUls.length; i = i + 1) {
    
        arTheAs = $A(arTheUls[i].getElementsByTagName("a"));
        theEl = arTheAs.detect(
                function (theA) {
                    //return an element that doesn't have popup.png,
                    //which is a help popup
                    return theA.innerHTML.toLowerCase().indexOf("popup.png") === -1 ? true : false;
                }
            )
        //if something was found, return it
        if(theEl) {
            //clear any other references to a selected tab first
            clearEls(theQueryparam);
            return theEl.innerHTML;
        }
    }
    
    //default return
    return "";

}

function clickTab(theSubsection) {

//declare local vars

var arTheUls,       //ul items with a class of "tabs", which hold the tabs
    arTheAs,        //array of anchor tags in the UL
    theEl,          //test anchor element
    i,j;              //counters
    

//get all ULs with a class of tabs, go through the anchor tags (which are tabs)
//and check for an innerHTML that equals the tab name
    arTheUls = document.getElementsByClassName("tabs");
    
    for(i = 0; i < arTheUls.length; i = i + 1) {
    
        arTheAs = arTheUls[i].getElementsByTagName("a");
        
        for(j=0; j < arTheAs.length; j=j+1) {
        //10/2/8 changing this because it's matching on too many results (AR matches all elements beginning with AR) not sure why indexOf 
        //was used instead of ===
           //  if(arTheAs[j].innerHTML.toLowerCase().indexOf(theSubsection.toLowerCase()) > -1) {
             if(arTheAs[j].innerHTML.toLowerCase() === theSubsection.toLowerCase()) {
                arTheAs[j].onclick();
             }  
        }
    }
    
}


//main function to swap divs for a container tag
function contSwitch(theContainerId, theDivId ,theLink, theArray, masterLink) {
    var theDiv = $("container_"+theContainerId+"_"+theDivId);       //target div
    var theContainer = theDiv.parentNode;                           //target div's parent
    var i = 0;                                                      //counter
    var childDivs = $A(theContainer.getElementsByTagName("div"));
    var theLinks = $A(theLink.parentNode.getElementsByTagName("a"));
    
    //collapse all sections if applicable
    if(theArray) {
        dspAll(theArray,masterLink,"-");
    }
    
    //loop through the child divs, fade if it isn't the selected one, and appear if it is
    childDivs.each( function (theLoopedDiv) {
        if(theLoopedDiv === theDiv) {
            new Effect.Appear(theLoopedDiv, {duration: .25});
        }
        else {
            new Effect.Fade(theLoopedDiv, {duration: .25});
        }
        
    }); 
    
    //now loop through control links and remove class from all except for the one that was passed
    //making it bold and non-underlined
    theLinks.each( function(theLoopedLink) {
        if(theLoopedLink === theLink) {
            theLoopedLink.className = "selected";
        }
        else {
            theLoopedLink.className = "";
        }
    });
}

//submits a form after an AJAX load

function getAJAXFormSubmit(theForm) {

	theForm.onsubmit();

}


//increment the page display
function contIncr(theContainerId, theLink, theArray, masterLink) {
    var selDiv = 0;     //which div should we go to?
    var selLink = "";   //which link is selected?
    var nextLink = "";  //what is the next link?
    var linkSibs = $A(theLink.parentNode.getElementsByTagName("a"));    //siblings of the link
    
    
    //get the currently selected link
    selLink = linkSibs.find( function(aLink) {
        return aLink.className === "selected";
    });
    
    //add 1 to this, casting it (as much as Javascript will allow us to do so) to a number so that we 
    //add and not concatenate
    //this will get us the ability to parse the ID of the div
    selDiv = +selLink.innerHTML+1;
    
    //get the next link based on the above
    nextLink = linkSibs.find( function(aLink) {
        return +aLink.innerHTML === selDiv
    });
    
    //if there is a div corresponding to the next link, send the info to contSwitch
    if( $("container_"+theContainerId+"_"+selDiv)) {
        contSwitch(theContainerId,selDiv,nextLink, theArray, masterLink);
    }
    else {
        return false;
    }
}

//decrement the page display
function contDecr(theContainerId, theLink, theArray, masterLink) {
    var selDiv = 0;     //which div should we go to?
    var selLink = "";   //which link is selected?
    var nextLink = "";  //what is the next link?
    var linkSibs = $A(theLink.parentNode.getElementsByTagName("a"));    //siblings of the link
    
    
    //get the currently selected link
    selLink = linkSibs.find( function(aLink) {
        return aLink.className === "selected";
    });
    
    //add 1 to this, casting it (as much as Javascript will allow us to do so) to a number so that we 
    //add and not concatenate
    //this will get us the ability to parse the ID of the div
    selDiv = +selLink.innerHTML-1;
    
    //get the next link based on the above
    nextLink = linkSibs.find( function(aLink) {
        return +aLink.innerHTML === selDiv
    });
    
    //if there is a div corresponding to the next link, send the info to contSwitch
    if( $("container_"+theContainerId+"_"+selDiv)) {
        contSwitch(theContainerId,selDiv,nextLink, theArray, masterLink);
    }
    else {
        return false;
    }
}


/* 

Example Javascript Animation Techniques by Hesido.com;
4 different, reusable examples

*/


function fadeBGColMem(theElem,theOldCol,theNewCol) {
	if (!theElem.currentbgRGB) theElem.currentbgRGB = theOldCol; //if no mem is set, set it first;
	doBGFadeMem(theElem,theElem.currentbgRGB,theNewCol,4,20,1);
	}

function fadeBGColRestore(theElem,theOldCol,theNewCol) {
	if (!theElem.currentbgRGB) return;	//avoid error if mouseout an element occurs before the mosueover
										//(e.g. the pointer already in the object when onload)
	doBGFadeMem(theElem,theElem.currentbgRGB,theOldCol,12,20,1);
	}


//*******************

function doBGFadeMem(elem,startRGB,endRGB,steps,intervals,powr) {
//BG Fader with Memory by www.hesido.com
	if (elem.bgFadeMemInt) window.clearInterval(elem.bgFadeMemInt);
	var actStep = 0;
	elem.bgFadeMemInt = window.setInterval(
		function() {
			elem.currentbgRGB = [
				easeInOut(startRGB[0],endRGB[0],steps,actStep,powr),
				easeInOut(startRGB[1],endRGB[1],steps,actStep,powr),
				easeInOut(startRGB[2],endRGB[2],steps,actStep,powr)
				];
			elem.style.backgroundColor = "rgb("+
				elem.currentbgRGB[0]+","+
				elem.currentbgRGB[1]+","+
				elem.currentbgRGB[2]+")";
			actStep++;
			if (actStep > steps) window.clearInterval(elem.bgFadeMemInt);
		}
		,intervals)
}


//*******************

function easeInOut(minValue,maxValue,totalSteps,actualStep,powr) {
//Generic Animation Step Value Generator By www.hesido.com
	var delta = maxValue - minValue;
	var stepp = minValue+(Math.pow(((1 / totalSteps)*actualStep),powr)*delta);
	return Math.ceil(stepp)
}

