// ----- purpose of this file -----
// This file contains all kind of javascript functions which are generally
// useful and will save you a lot of aggravation.


// ----- debugging -----
// if you set this var to true, you'll get various alerts telling you what's
// going on as the javascripts attempt to do their thang.  This can be set
// in the window before this javascript is loaded.
if (!window.show_debugging_info) {
  show_debugging_info = false;
}
// if debugging is on, generate an alert with the given message.  Otherwise do nothing
function debug(message) {
  if (show_debugging_info) {
    alert(message);
  }
}
// this will get called when the page first loads so you know that the script
// compiled.  (Sometimes browsers will be incapable even of showing specific
// errors because the entire javascript couldn't be compiled)
debug('andalucienLib.js compiled');



// ----- location control functions -----
// this section enables the page to know much more about its own "location" or
// url, as well as its relationship to other windows, than it would otherwise.
// Knowledge equals power.

// if the window window were to be refreshed, which arguments would we want
// to be submitted again?  That is the meaning of the variable refreshQUeryString
// First of all, it's not always good enough just to call location.reload()
// becuase if the page was the result of a post request, the user will sometimes
// be asked if he/she REALLY wants to reload the page.  Also, if the request that
// generated the page was intended to write something to the database, like adding
// a bookmark, do we really want to refresh and add the same item again? no.
// For this reason we need a way to distinguish between the types of arguments
// that we would want repeated and the other arguments.
//
// This convention is:  arguments starting with "_" will not be "repeated" in
// the refresh.  So we need to build refreshQueryString into a query string
// that repeats all of the passed parameters and their values except the ones
// starting with "_".
var refreshQueryString = "?";

// a list of all argument names:
argNames = new Array();
// an associative array between argument names and their values:
args = new Array();
// an array of "key=value" type strings:
var split_search = location.search.split(/\?|&/);
// loop through split_search to populate argNames and args.
for (var i in split_search) {
  // part before equals sign is key to hash; part after is its value
  var halves = split_search[i].split('=');
  args[halves[0]] = halves[1];
  argNames[i] = halves[0];
  // don't want to repeat arguments starting with '_' by convention
  if (split_search[i].charAt(0) != '_') refreshQueryString += split_search[i] + '&';
}
// for an opera quirk:
if (refreshQueryString.substr(0, 2) == '??') {
  refreshQueryString = refreshQueryString.substr(1);
}

// always repeat the session argument and a random "_rand"
// argument (to defeat IE cache)
omniarg = '&_sessionId=' + args['_sessionId']; // + '&_rand=' + Math.random();

// when activated, this function will reload the content of the window.
function refresh_content() {
  debug('refresh content called');
  window.location = location.pathname + refreshQueryString + omniarg + '&_autorefresh=1';
}


// if the opener has a refresh_Content function, will call it.
function refresh_opener() {
  debug('refresh opener called');
  if (!window.opener) {
    debug('there was no window.opener function');
  }
  else {
    debug('window.opener found');
    if (!window.opener.refresh_content) {
      debug('no refresh content found in window.opener');
    }
    else {
      debug('YES! refresh content found in window.opener');
      opener.location = opener.location.pathname + opener.refreshQueryString + omniarg;
    }
  }
}




// ----- form manipulation -----

// this function sets the default value of virtually any
// form element.  For example, if you had a popup menu of
// months, with options of values 1-12, called "month", in the form
// named "dateForm", and you wanted to set this to the option representing
// June (value 6), you would call:
// setElementDefault("dateForm", "month", 6);
//
// The point of this function is to avoid tricky/crowded server-side ways
// to select a certain default value.  For example, in the case of a popup menu
// you would normally need to put something like "<if (condition)> SELECTED</if>"
// What a pain.  This lets you put all default settings at the bottom of the page
// in one place.
function setElementDefault(formName, elementName, defaultValue) {
  var fullFormName = "document." + formName;
  var theForm = eval(fullFormName);
  if (!theForm) {
	  theForm = getRefToDiv(formName);
  }
  var fullElementName = "theForm." + elementName;	  
  debug("setElement default on "+fullElementName+"; default value is "+defaultValue);
  theElement = eval(fullElementName);
  if (!(theElement)) {
    alert ("setElementDefault() javascript function: "
      + fullElementName +  " is undefined.");
    return;
  }

  if(theElement.type) {
    if (theElement.type == "text" || 
		theElement.type == "textarea" || 
		theElement.type == "hidden" ||
		theElement.type == "password") {
      theElement.value = defaultValue;
    }
    else if (theElement.type.indexOf("select") >= 0) {
      for (var i = 0; i < theElement.options.length; ++i) {
        debug("optionValue="+theElement.options[i].value+" defaultValue="+defaultValue);
        if (theElement.options[i].value == defaultValue) {
          theElement.selectedIndex = i;
        }
      }
    }
    else if (theElement.type == "radio" || theElement.type == "checkbox") {
      debug(theElement.name+": value is "+theElement.value);
      if (theElement.value == defaultValue) {
        theElement.checked = 1;
      }
      else {
        theElement.checked = 0;
      }
    }
    else {
      alert (theElement.type + ": element type of "+elementName+" not supported"
        + " in setElementDefault() javascript function.");
    }
  }
  else {
    if (theElement[0].type == "radio" || theElement[0].type == "checkbox") {
      for(var i = 0; i < theElement.length; ++i) {
        if (theElement[i].value == defaultValue) {
          theElement[i].checked = 1;
        }
        else {
          theElement[i].checked = 0;
        }
      }
    }
    else {
      alert (theElement[0].type + ": element type (in array) of element "
        +elementName+" is not supported"
        + " in setElementDefault() javascript function.");
    }
  }
}


// This method will basically call setElementDefault a bunch of times.
// If any of the elements in the specified form have fields that match
// a request parameter, attempt to set that field to the value specified
// in the parameter.
function setDefaultsFromArgs (theform) {
  for (var i = 0; i < theform.elements.length; i++) {
    elementName = theform.elements[i].name;
    if (elementName.length == 0) continue;
    defaultValue = args[elementName];
    if (!defaultValue) continue;
    setElementDefault(theform.name, elementName, defaultValue);
  }
}


// if the passed checkbox is now checked,  all the checkboxes in its
// containing form will become checked.  If it is not checked, all other
// checkboxes will become corresondingly unchecked.
function selectall(box, boxName) {
  var yesno = box.checked;
  for(i=0; i < box.form.elements.length; i++) {
	  with (box.form.elements[i]) {
		if (type == 'checkbox') {
		  if (boxName) {
			 if ( name == boxName) {
				checked = yesno; 
			 }
		  }
		  else {
		      checked = yesno;
		  }
		}
	  }
    }
  }

// returns true iff all checkboxes in the specified form are checked
function areAllBoxesChecked(form) {
  for(i=0; i < form.elements.length; i++) {
    if (form.elements[i].type == 'checkbox' && !form.elements[i].checked) {
	    return false;
    }
  }
  return true;
}

// if you set the onsubmit of a form to return this method, it will ensure that this form is 
// only submitted once.
function submitOnce(form) {
	if (defined(form.alreadySubmitted) && form.alreadySubmitted) {
		return false;
	}
	else {
		alreadySubmitted = true;
		return true;
	}
}


// Registers a function to handle all keystrokes.
// The function needs to take 2 arguments:  
//   an integer representing the keystroke number,
//   and a form element that captured the keystroke.
//  The function should return "true" if the keystroke will be handled normally afterwards, false
// to halt the normal result of that keystroke.
function registerKeystrokeHandler(func) {
	window.keystrokeHandler = func;
	var nav = window.Event ? true : false;
	if (nav) {
	   window.captureEvents(Event.KEYDOWN);   window.onkeydown = NetscapeEventHandler_KeyDown;
	} else {
	   document.onkeydown = MicrosoftEventHandler_KeyDown;
	}	
}

function NetscapeEventHandler_KeyDown(e) {
  if (!window.keystrokeHandler) {
	alert("No keystroke handler defined!");
	return true;
  }
  return window.keystrokeHandler(e.which, e.target);
}

function MicrosoftEventHandler_KeyDown() {
  if (!window.keystrokeHandler) {
	alert("No keystroke handler defined!");
	return true;
  }
  return window.keystrokeHandler(event.keyCode, event.srcElement);
}



// ----- popup windows -----
// Opens a popup window to the specified location.  Height and width
// specification is optional and will default to 500x520.
// returns the window handle
function popup(destination, height, width, title) {
  debug ("popup entered: destination="+destination+" height="+height+"width="+width);
  if (!destination) {
    alert('no destination specified');
    return;
  }
  if (!height) {
    height=500;
  }
  if (!width) {
    width=520;
  }
  if (!title) {
  	title = 'andalucien_popup'+Math.round(Math.random()*1000000);
  }
  
  // centering popup window within this browser window
  var w = 480, h = 340;
	if (document.all) {
	   /* the following is only available after onLoad */
	   w = top.document.body.clientWidth;
	   h = top.document.body.clientHeight;
	}
	else if (document.layers) {
	   w = top.window.innerWidth;
	   h = top.window.innerHeight;
	}
	var leftPos = (w-width)/2, topPos = (h-height)/2;
  //alert(h+" "+w+" "+topPos+" "+leftPos);
  debug("title="+title);
  win_attributes = 'width='+width+',height='+height
    +',scrollbars,resizable,top='+topPos+',left='+leftPos;
  var win = window.open(destination, title, win_attributes);
  return win;
}


// --------- dhtml effects -----------

function getRefToDiv(divID) {
	//customised to suit this particular page - DON'T COPY THIS UNLESS YOU KNOW WHAT YOU ARE DOING!!
	if( document.layers ) { return document.layers[divID+'C'].document.layers[divID]; }
	if( document.getElementById ) { return document.getElementById(divID); }
	if( document.all ) { return document.all[divID]; }
	if( document[divID+'C'] ) { return document[divID+'C'].document[divID]; }
	return false;
}

function showDiv(divID_as_a_string) {
	var myReference = getRefToDiv(divID_as_a_string);
	if( !myReference ) { window.alert('Tried to show the div ' + divID_as_a_string + ' but could not find it.'); return; }
	if( myReference.style ) { 
		myReference.style.visibility = 'visible';
		if (myReference.style.display == 'none') {
			myReference.style.display = 'inline';
		}
	} 
	else {
		if (myReference.visibility) { 
			myReference.visibility = 'show'; 
		} 
		else {
			window.alert('Tried to show the div ' + divID_as_a_string + ' but could not find it.'); 
			return; 
		} 
	}
}

function hideDiv(divID_as_a_string) {
	var myReference = getRefToDiv(divID_as_a_string);
	if( !myReference ) { 
		window.alert('Tried to hide the div ' + divID_as_a_string + ' but could not find it.'); 
		return; 
	}
	if( myReference.style ) { 
		myReference.style.visibility = 'hidden'; 
		myReference.style.display = 'none';
	} 
	else {
		if (myReference.visibility) { 
			myReference.visibility = 'hide'; 
		} 
		else {
			window.alert('Tried to hide the div ' + divID_as_a_string + ' but could not find it.'); 
			return; 
		} 
	}
}


function rewriteDiv(divID_as_a_string, newContents) {
	var myReference = getRefToDiv(divID_as_a_string);
	if( !myReference ) { 
		window.alert('Tried to rewrite the div ' + divID_as_a_string + ' but could not find it.'); 
		return;
	}
	if ( myReference.innerHTML != undefined ) { 
		myReference.innerHTML = newContents; 
	} 
	else {
		if( myReference.document && myReference.document != window.document ) {
			myReference.document.open();
			myReference.document.write(newContents);
			myReference.document.close();
		} 
		else {
			window.alert('Your browser does not allow the contents to be re-written: ' + myReference.innerHTML); 
			return; 
		}
    }
}



// returns an object with 4 attributes, 
//"left", "top", "width", and "height", all in numeric pixel representation
function getElementPosition(elemID) {
    var offsetTrail = document.getElementById(elemID);
	if (!offsetTrail) {
		alert("No such element "+elemID);
		return null;
	}
	var w = offsetTrail.clientWidth;
	var h = offsetTrail.clientHeight;
	//alert("elemID="+elemID+", offsetTrail="+offsetTrail+", w="+h+", h="+h);
    var offsetLeft = 0;
    var offsetTop = 0;
    while (offsetTrail) {
        offsetLeft += offsetTrail.offsetLeft;
        offsetTop += offsetTrail.offsetTop;
        offsetTrail = offsetTrail.offsetParent;
    }
    if (navigator.userAgent.indexOf("Mac") != -1 && 
        typeof document.body.leftMargin != "undefined") {
        offsetLeft += document.body.leftMargin;
        offsetTop += document.body.topMargin;
    }
	
    return {left:offsetLeft, top:offsetTop, width:w, height:h};
}




// ------------- coookies ----------------

function setCookie(myname, myvalue) {
	var mycookie = myname + "=" + escape(myvalue);
	var myexpires = new Date();
	myexpires.setTime(myexpires.getTime() + 365*24*60*60*1000);
	mycookie = mycookie + "; expires=" + myexpires.toGMTString();
	document.cookie = mycookie;
}

function getCookie(myname) {
	var mycookie = document.cookie;
	var myname = myname + "=";
	var mystart = mycookie.indexOf(myname);
	if (mystart < 0) {return null;}
	var myend = document.cookie.indexOf(";", mystart);
	if (myend < 0){myend = mycookie.length;}
	return unescape(mycookie.substring(mystart + myname.length, myend));
}


// ------ StringBuffer -----------
function StringBuffer() { 
   this.buffer = []; 
 } 

 StringBuffer.prototype.append = function append(string) { 
   this.buffer.push(string); 
   return this; 
 }; 

 StringBuffer.prototype.toString = function toString() { 
   return this.buffer.join(""); 
 }; 
 
 
 // ----- ie ------
window.ie = window.Event ? false : true;
function getPageYOffset() {
	if (ie) return document.body.scrollTop;
	else return window.pageYOffset;
}
function getPageXOffset() {
	if (ie) return document.body.scrollLeft;
	else return window.pageXOffset;
}
function getInnerWidth() {
	if (ie) return document.body.clientWidth;
	else return window.innerWidth;
}
function getInnerHeight() {
	if (ie) return document.body.clientHeight;
	else return window.innerHeight;	
}

