var xcoordList = new Array(); //Stack of xcoordinates allowing return to original position when return link is followed 
var ycoordList = new Array(); //Stack of xcoordinates allowing return to original position when return link is followed
var configList = new Array();
var queryList = new Array();
var windowNumber = 0
var myTargetId = ""
//Function to act as the default call back to the ajax provider
function updateText(result)
     {
      targetDiv = findElement(myTargetId)
      if(!targetDiv)
        alert("Target div " + myTargetId + " not found")
      try
       {
        targetDiv.innerHTML = result
       }
      catch (e)
       { 
        alert("Could not add result to div");
        alert("result = " + result)
       } 
      returnScroll()
     }
     
function returnScroll()
 {
  xpos = 0
  ypos = 0
  //alert("window number = " + windowNumber)
  if(xcoordList[windowNumber] || ycoordList[windowNumber])
   {
    //get the last form off the stack
    xpos = xcoordList[windowNumber]
    ypos = ycoordList[windowNumber]
    //Remove this element from the array
    xcoordList.pop()
    ycoordList.pop()
   }
   
   //alert("About to scroll window = " + windowNumber)
   window.scrollTo(xpos,ypos) 
 }

function transferAjaxResult(result)
 {
   alert("ajaxRetVal = " + ajaxRetVal)
   ajaxRetVal = result[0]
   alert("ajaxRetVal = " + ajaxRetVal)
 }

function displayQueryForm(target,template,config)
 {
  if(!target)
   target = ""

  if(!template)
   template = ""
   
  if(! x_displayQueryFormAjax)
   {
    alert("displayQueryForm function not exported!")
    return
   }
  
  if(target)
   {
    sajax_target_id = target
    x_displayQueryFormAjax(template,config,'');
   }
  else
   {
    sajax_target_id = ""
    x_displayQueryFormAjax(template,config,fillForm);
   }
 }

//This function will need extending to handle drop down lists
function runQuery(target,sourceforms,config,startRow,qString,returnStart,parentCache,parentQuery,callBack,winInc,parentConfig)
  {
   /*if(target)
    sajax_target_id = target
   else
     sajax_target_id = ""*/
     
   myTargetId = target
   sajax_target_id = ""
   var i
   if(sourceforms)
    {
     joiner = ""
     qString = ""
     sources = sourceforms.split(",")
     for(i = 0; i < sources.length; i++)
      {
       frm = findElement(sources[i])
       //Pick up the query variables from the named forms 
       if (frm)
        qString += joiner + getQueryValues(frm)
       if(qString)
        joiner = ";"  
     }   
    } 
    
   if(!qString)
    {
     return
    } 
   
  joiner = ";"  
  if(startRow) 
   {
    qString = qString.concat(joiner)
    qString = qString.concat("startrow=")
    qString = qString.concat(startRow)

   }
  if(returnStart) 
   {
    qString = qString.concat(joiner)
    qString = qString.concat("returnStart=")
    qString = qString.concat(returnStart)
   }
  
  //Save the scroll coordinates of the current page onto the coordinate stacks
  coords = getScrollCoordinates()
  xcoordList[windowNumber] = coords['x']
  ycoordList[windowNumber] = coords['y']
  if(!winInc)
   winInc = 1;
   
  
  if(winInc > 0)
   {
    //pick up the parent query and config from the stack
    parentQuery = queryList[windowNumber -1]
    parentConfig = configList[windowNumber -1]
   //Save the query onto the query stack
    //This may need to be done earlier - before the qstring is built from the form. 
    //alert("adding " + qString + "to querylist at " + windowNumber)
    queryList[windowNumber] = qString;
    //Save the current config onto the config stack
    configList[windowNumber] = config;
   }
  else
   {
    //alert("Going up window number is " + windowNumber)
    //pick up the parent query and config from the stack
    parentQuery = queryList[windowNumber -3]
    parentConfig = configList[windowNumber -3]
    //alert("Going up window number is " + windowNumber + "parent query for window " + (windowNumber -2) + " is " + parentQuery)
    queryList.pop()
    configList.pop()  
   }
   
   
  windowNumber += winInc
  
  if(!parentCache)
   parentCache = "";
  
  if(!parentConfig)
   parentConfig = "";
    
  //alert("qstring = " + qString)
  //alert ("parentCache = " + parentCache)
  if(! x_handleQueryAjax)
  {
   alert("handleQueryAjax function not exported!")
   return
  }
  
  //Set the call back function - updateText is just an empty function
  if(!callBack)
   callBack = updateText
  x_handleQueryAjax(config,qString,parentCache,parentQuery,parentConfig,callBack);
 }
     
function getValues(DSN,sql,restriction,order,multiple,size,selname,onchange,target,source,classname)
     {
        sajax_target_id = target
        fld = findElement(source) 
        thisVal = fld.value.split("|")
        //sql = "select [full name],ln.id from ([latin names] as ln inner join ranks as r on r.id = ln.rank) inner join [names tree] as nt on nt.member = ln.id where nt.[member of] = || and r.level > 15 order by fullsort"
        if(thisVal[0] && restriction)
         {
          restriction = restriction.split("¬")
          restriction[1] = thisVal[0]
          restriction = restriction.join(" ")
         }
        else
         {
          restriction = ""
         }
         x_sendValues(DSN,sql + " " + restriction + " " + order,multiple,size,selname,onchange,classname,updateText)
		    if(onchange)
		     {
			     eval(onchange.replace(/¬/g,"'"))
		     }
     }


function getValuesArrayCfg(cfg,target,source,addAny)
 {
   if(typeof(addAny) == "undefined")
     addAny = 1
   sajax_target_id = ""
   
   var fld = findElement(source)
   if(!fld)
    {
     alert("The source " + source + " could not be found")
     return
    }
   
   //Pick up the id to use as a restriction value 
   var thisVal 
   //Handle single select drop down
   if(fld.type == "select-one")
    {
     thisVal = fld.value.split("|")
     thisVal = thisVal[0]
    }  
   //Handle multiselect drop down 
   var tmpVal
   if(fld.type == "select-multiple")
    { 
     var sep = ""
     for(i = 0; i < fld.options.length; i++)
       {
         if(fld.options[i].selected)
            {
               tmpVal = fld.options[i].value.split("|")
               thisVal = thisVal + sep + tmpVal[0]
               sep = "|"  
            }
       }
    }
    
    if(! x_sendValuesArrayCfg)
     {
      alert("sendValuesArray function not exported!")
      return
     }
     
   //need to pass cfg name restriction value, target and addAny - the rest can be got from the config 
   x_sendValuesArrayCfg(cfg,thisVal,target,addAny,setSelectOptions)         
 }

function getValuesArray(DSN,sql,restriction,order,target,source,addAny)
     {
       if(typeof(addAny) == "undefined")
        addAny = 1
       sajax_target_id = ""
       var fld = findElement(source)
        if(!fld)
         {
          alert("The source " + source + " could not be found")
          return
         }
        
        //Deal with a single select drop down  
        if(fld.type == "select-one")
        {
         thisVal = fld.value.split("|")
         if(restriction)
          {
           restriction = restriction.split("¬")
           if(thisVal[0])
             restriction[1] = thisVal[0]
           else
             restriction[1] = -99
           restriction = restriction.join("") 
          }
         else
          {
           restriction = ""
          }
         }
         
         if(fld.type == "select-multiple")
          {
           var fullRestriction = ""
           restrictions = Array()
           var cnt = 0
           var orJoiner = ""
           for(i = 0; i < fld.options.length; i++)
            {
             if(fld.options[i].selected)
              {
               thisVal = fld.options[i].value.split("|")
               if(restriction)
                {
                 if(thisVal[0])
                  restrictions[cnt] = thisVal[0]
                 else
                  restrictions[cnt] = -99
                 cnt ++
                }
              }     
            }
           if (restrictions.length > 0)
            {
             restriction = restriction.split("¬")
             restrictField = restriction[0]
             restrictField = restrictField.replace(/where /i,"")
             restriction[1] = restrictions.join(" or " + restrictField)
             restriction = restriction.join("")
            } 
           else
            restriction = ""
          } 
         
         if(! x_sendValuesArray)
          {
           alert("sendValuesArray function not exported!")
           return
          }
         
         //alert ("Using SQL " + sql + " " + restriction + " " + order)
         x_sendValuesArray(DSN,sql + " " + restriction + " " + order,target,addAny,setSelectOptions)
         fld = findElement(target)

        //Make sure the onchange event of the target is fired 
		    if(fld.onchange)
		     {
		       oc = fld.onchange.toString()
           oc = oc.replace("function anonymous()","")
			     eval(oc)
		     }
     }

function setSelectOptions(valueList)
 {
  //valuelist is an array - the first element of which is the name of the select element to be altered, the second is the count of elements in the array
  target = valueList[0][0]
  var cnt = valueList[0][1]
  dest = findElement(target)
  dest.options.length = 0 
  var i
  for(i = 1; i < cnt; i++)
   dest.options[dest.options.length] = new Option(valueList[i][1],valueList[i][0]+'|'+valueList[i][1],'',valueList[0][2])  
  //Fire the onchange event of the destination to allow chaining of comboboxes 
  if (document.createEventObject)
   {
    // dispatch for IE
    var evt = document.createEventObject();
    dest.fireEvent('onchange',evt)
   }
  else
    {
     // dispatch for firefox + others
     var evt = document.createEvent("HTMLEvents");
     evt.initEvent('change', true, true ); // event type,bubbling,cancelable
     dest.dispatchEvent(evt);
    }
  }

function displayResultsTable(target,source,config)
 {
  sajax_target_id = target
  frm = findElement(source)
  qString = getQueryValues(frm)
  x_displayResultsTable(qString,config,'')
 }

function toggleList(divName,fileName,target,multiple,size,selName,onchange)
{
        //Make sure that the list area is visible
        if (document.getElementById) {use_gebi = true}
	      else if (document.all) {use_css = true}
	      else if (document.layers) { use_layers = true; }

	      if (use_gebi) {
			   visible = document.getElementById(divName).style.visibility
			  }
	     else if (use_css) {
			  visible = document.all[divName].style.visibility
			}
	    else if (use_layers) {
			visible = document.layers[divName].visibility
			}
                if(!visible || visible == "hidden")
		{newVal = "visible"}
		else
		{newVal = "hidden"}
		
        if (use_gebi) {
			 document.getElementById(divName).style.visibility = newVal
			 if(newVal == "visible")
			 {
        document.getElementById(divName).style.height = "auto"
 			  document.getElementById(target).style.height = "auto"
			  document.getElementById("toggleButton").value = "Hide List"
			 }
			 else
			 {
                          document.getElementById(divName).style.height = "1px"
 			  document.getElementById(target).style.height = "1px"
			  document.getElementById("toggleButton").value = "Reveal List"
			 }
			}
	else if (use_css) {
			 document.all[divName].style.visibility = newVal
			}
	else if (use_layers) {
			 document.layers[divName].visibility = newVal
			}
        //Fill in the values of the list	
        getValues('A',fileName,target,multiple,size,selName,onchange)	

}


function toggleVisible(divName)
{
        //Make sure that the list area is visible
        if (document.getElementById) {use_gebi = true}
	      else if (document.all) {use_css = true}
	      else if (document.layers) { use_layers = true; }

	      if (use_gebi)
         {
			    visible = document.getElementById(divName).style.visibility
			   }
	      else if (use_css)
         {
			    visible = document.all[divName].style.visibility
			   }
	      else if (use_layers)
         {
			     visible = document.layers[divName].visibility
			   }
       if(!visible || visible == "hidden")
		    {newVal = "visible"}
		   else
		   {newVal = "hidden"}
		
       if (use_gebi)
        {
			   document.getElementById(divName).style.visibility = newVal
			   if(newVal == "visible")
			    {
           document.getElementById(divName).style.height = "auto"
			    }
			   else
			    {
           document.getElementById(divName).style.height = "1px"
			    }
 	 		  }
	     else if (use_css)
        {
			    document.all[divName].style.visibility = newVal
			  }
	     else if (use_layers) 
        {
			   document.layers[divName].visibility = newVal
			  }
}

function findElement(id)
  {
    if (document.getElementById) {use_gebi = true}
	  else if (document.all) {use_css = true}
	  else if (document.layers) { use_layers = true; }
 	  if(use_gebi)
     {
		  fld = document.getElementById(id)
		 }
	  else if(use_css)
     {
		  fld = document.all[id]
		 }
	  else if(use_layers) 
     {
		  fld = document.layers[id]
		 }
		 return fld
		 
  }

function hideIt(elemId,closeId)
 {
  elem = findElement('elemId')
  if(elem)
   elem.style.visibility = 'hidden'
  elem = findElement('closeId')
  if(elem)
   elem.style.visibility = 'hidden' 
 }
 
function showIt(elemId)
 {
  elem = findElement(elemId)
    elem.style.visibility = 'visible' 
 }


function getQueryValues(frm,passedJoiner)
{
    var qString = ""
    var joiner = ""
    if(!passedJoiner)
     passedJoiner = ";"
     
    var i
    for(i = 0; i < frm.elements.length; i++)
     {
      if( frm.elements[i].type == "text" || frm.elements[i].type == "textarea" || frm.elements[i].type == "hidden" || frm.elements[i].type == "password")
       {
        if(frm.elements[i].value)
         {
          qString = qString.concat(joiner)
          qString = qString.concat(frm.elements[i].name)
          qString = qString.concat("=")
          qString = qString.concat(frm.elements[i].value)
          joiner = passedJoiner
         }
       } 
      if(frm.elements[i].type == "select-one")
       {
         if(frm.elements[i].value)
          {
           qString = qString.concat(joiner)
           qString = qString.concat(frm.elements[i].name)
           qString = qString.concat("=")
           qString = qString.concat(frm.elements[i].value)
           joiner = passedJoiner
          }
       } 
      if(frm.elements[i].type == "checkbox")
       {
         if(frm.elements[i].checked)
         {
           qString = qString.concat(joiner)
           qString = qString.concat(frm.elements[i].name)
           qString = qString.concat("=")
           qString = qString.concat(frm.elements[i].value)
           joiner = passedJoiner
         }
       }
     }
   return qString
}

function ajaxExecute(funcName,funcParams,require,formId,target,params,callback)
 {
  if(!require)
    require = ""
  if(formId)
   {  
    frm = findElement(formId)
    if(!frm)
     {
       alert("Form " + formId + " not found")
       return
     }
    params = getQueryValues(frm)
   }
  else
    if(!params) params = ""
      
  if(!target)
   target = ""     
  sajax_target_id = target
  
  if(!callback)
   callback = handleExecuteResult
  //alert("params = " + params)
  //alert("formId = " + formId)
  //alert("target = " + target)
   x_ajaxExecute('',funcName,funcParams,params,require,callback)

 }
 
 function handleExecuteResult(result)
  {
    if(sajax_target_id)
     {
      elem = document.getElementById(sajax_target_id)
      if(elem)
       elem.innerHTML = result
     }
  }  

function getScrollCoordinates()
 {
  retval = new Array
  retval["x"] = (document.all)?document.body.scrollLeft:window.pageXOffset
  retval["y"] = (document.all)?document.body.scrollTop:window.pageYOffset
  return retval
 }


function storeOriginalLookupValues(src)
 {
  src.originalText = src.value
  var lookupName = src.id.replace(/_lookup_display/, "")
  var elem = document.getElementById(lookupName)
  if(elem)
   src.originalValue = elem.value
  else
   alert("Cannot find hidden value element " + lookupName)
 }
 
function lookup(inputSrc,outputTargetName,cfgDir)
   {
     //N.B. this is a global variable!!!
     outputTarget = document.getElementById(outputTargetName)
     if(!outputTarget)
      return
     
     var qString = ""
     var frm
     frm = inputSrc.form
     if (frm)
      qString = getQueryValues(frm,"~~")
     
     var id = ""
     id = inputSrc.id.replace(/_lookup_display/,"");
     id = id.replace(/__/g,"||")
     id = id.replace(/_/g,".")
     id = id.replace(/\|\|/g,"_")
     var searchVal = inputSrc.value
     
     if(searchVal)
      {
       //Get the form values to allow parsing of current values into the restriction
       var frm = inputSrc.form
       var qString = ""
       if(frm)
        qString = getQueryValues(frm,"~~")
       x_lookup(searchVal,id,cfgDir,qString,handleLookupResult)
      }
     else
      {
        //Clear out the value
        var resultField = outputTargetName.replace(/_lookup_result/, "")
        var elem = document.getElementById(resultField)
        if(elem)
         elem.value = ""
        //Make sure the record is flagged as changed
      }
   }

//This next set of functions handles the ajax base lookup actions for lookup widgets embedded in a template
//TODO output target should be passed in the response !!!!!!
function handleLookupResult(resp)
 {
  if (resp[0] == 0)
   {
    alert(resp[1])
    return
   }
   
  var width = outputTarget.style.width;
  if(!width)
   width="300px";

  targetListId = outputTarget.id + "_List"
  
  targetText = "<select id=\"" + targetListId + "\" style=\"width: " + width + ";z-index: 3;\" size=\"10\" onkeyup=\"handleLookupTextInput(event)\" onclick=\"setLookupSelection(this)\" onblur=\"setLookupSelection(this)\">"
  
  targetText += "<option selected=\"1\" value=\"\""
             + " onmouseover=\"this.style.backgroundColor =  '#DAEEFE'\""
             + " onmouseout=\"this.style.backgroundColor =  'white'\">No selection</option>"
             
  for(row in resp)
   {
    rowText = resp[row]["VALUE"]
    rowValue = resp[row]["ID"]
    if(rowText)
     {
      targetText += "<option value=\""+ rowValue + "\""
                 + " onmouseover=\"this.style.backgroundColor =  '#DAEEFE'\""
                 + " onmouseout=\"this.style.backgroundColor =  'white'\">"
                 + rowText + "</option>";
     }
   }
  targetText += "</select>"
  outputTarget.innerHTML = targetText;
  //make sure that the box is positioned correctly
  var lookupName = outputTarget.id.replace(/_result/, "_display")
  var elem = document.getElementById(lookupName)
  if(elem)
   {
    var currleft = elem.offsetLeft
    var currtop = elem.offsetTop
    var currheight = elem.offsetHeight
    /*var currleft = 0
    var currtop = 0
    var currheight = elem.offsetHeight
    do
    {
     currleft += elem.offsetLeft
     currtop += elem.offsetTop
    }while(elem = elem.offsetParent)*/
    //This works ok in FF but not in IE 7 - not sure why
    outputTarget.style.left = currleft + "px"
    outputTarget.style.top = (currtop + currheight) + "px"
    //alert("top = " + outputTarget.style.top)
   }

  outputTarget.style.display = "block"
  self.setTimeout("var elem = document.getElementById('" + targetListId + "');elem.focus()",100)
 }

function handleLookupDisplayKeyPress(e,inputSrc,outputTargetName,cfgDir)
 {
   var evtobj = window.event ? window.event : e
   if(evtobj)
    {
     var unicode=evtobj.charCode? evtobj.charCode : evtobj.keyCode
    }
   else
    var unicode = 0

   if(unicode ==13)
    {
     var src = evtobj.target ? evtobj.target : evtobj.srcElement
     //Stop the event bubbling
     if(evtobj.stopPropagation)
      evtobj.stopPropagation()
     else
      evtobj.cancelBubble = true
     if(src.value != "")
      lookup(inputSrc,outputTargetName,cfgDir)
    }
 }
 
function handleLookupTextInput(e)
 {
   var evtobj = window.event ? window.event : e
   if(evtobj)
    {
     var unicode=evtobj.charCode? evtobj.charCode : evtobj.keyCode
    }
   else
    var unicode = 0

   var src = evtobj.target ? evtobj.target : evtobj.srcElement
   
   //Esc key pressed - Close the box and update the values
   //empty out the select box
   if(unicode == 27)
    {
     var resultListContainer = src.parentNode
     var lookupName = resultListContainer.id.replace(/_result/, "_display")
     var displayField = document.getElementById(lookupName)
     displayField.value = displayField.originalText
     resultListContainer.style.display = "none"
    }
    

   //If the enter or tab key is pressed collapse the box
   //Prevent event bubbling if enter is pressed
   if(unicode == 13 || unicode == 9)
    {
     if(evtobj.stopPropagation)
      evtobj.stopPropagation()
     else
      evtobj.cancelBubble = true
     setLookupSelection(src)
     //Make sure that the field displaying the selected value has focus
     var lookupName = src.parentNode.id.replace(/_result/, "_display")
     var displayField = document.getElementById(lookupName)
     displayField.focus()
    }
 }
 
function setLookupSelection(selectedItemList)
 {
  var resultListContainer = selectedItemList.parentNode
  var lookupName = resultListContainer.id.replace(/_result/, "_display")
  var valueName = resultListContainer.id.replace(/_lookup_result/, "")
  //Update the displayed value
  var displayElem = document.getElementById(lookupName)
  if(displayElem)
   {
    if(selectedItemList.value)
     displayElem.value = selectedItemList.options[selectedItemList.selectedIndex].text
    else
     displayElem.value = displayElem.originalText
   }
  else
   alert("could not find " + lookupName)
   
   //Update the hidden stored value
  valueElem = document.getElementById(valueName)
  if(valueElem)
   {
    if(selectedItemList.value)
     valueElem.value = selectedItemList.value
    else
     valueElem.value = displayElem.originalValue
   }
  else
   alert("could not find " + valueName)
  resultListContainer.style.display = "none"
 }

