
// Library of common JavaScript functions

// ---------------------------------------------------------------------------

function CheckDate(datestr,format,othparams)
{
   /* Validates input date to required format.
      Parameters:
           datestr - date string to validate (mandatory)
           format - date format (optional - defaults to 'dd/mm/yyyy')
           othparams - other parameters, eg. NOALERT to suppress alert message

      Returns: message string (blank if date is valid)
   */

   // return immediately if empty (form-validation should check for mandatory contents)
   if (datestr=='') {return true;}

   // set default parameter values if not passed
   if (typeof format == 'undefined' ) {format='dd/mm/yyyy';}
   if (typeof othparams == 'undefined') {othparams='';}

   var isValid = true;                   // init. return value
   var message = "";                     // init. invalid message
   var year=0,month=0,day=0;
   var showmessage = (othparams.indexOf('NOALERT')<0);
   var dateparts = datestr.split('/');
   var formatparts = format.split('/');

   if (dateparts.length!=3) {message="Invalid date format";}
   if (formatparts.length!=3) {message = "Invalid format specified in code";}

   // Check only valid characters have been entered
  	if (!ValidChars(datestr,'DATE')) {message = "Invalid characters present";}

	if (message=="")
		// ------------
		// split date into components
		year = dateparts[2];

		if (Left(format,2)=='dd') {
			 day   = dateparts[0];
			 month = dateparts[1];
			 year  = dateparts[2];
			}
		else if (Left(format,2)=='mm')
			{
			 day   = dateparts[1];
			 month = dateparts[0];
			 year  = dateparts[2];
			}
		else if (Left(format,2)=='yy')
			{
			 year  = dateparts[0];
			 month = dateparts[1];
			 day   = dateparts[2];
			}
		else
			{message = "Invalid format specified in code";}
		// -----------


   // check for correct no. of days in month
   if (message=="")
   {
      var monthdays=31;         // init. no. of days in month

      if (('4,6,9,11,').indexOf(month.toString()+',')>0) {monthdays=30;}
         // must include trailing comma for searching
      if (month==2)
         { if (year%4==0) {monthdays=29;}   // ie. leap year
           else           {monthdays=28;}
         }
      if (message=="" && (day<1 || day>monthdays)) {message="Invalid day of month";}
   }


	// test for valid month
	if (message=="" && (month<1 || month>12)) {message="Invalid month";}


	// test for valid year
	if (message=="") {

		// is is long or short year format?
		if (format.indexOf('yyyy')>0) {
			if (year<1000 || year>9999) {message="Year should be in 'yyyy' format";}
		}
		else {
			// assume yy format
			if (year<9 || year>99) {message="Year should be in 'yy' format";}
		}
   }


   // show message if appropriate
   if (showmessage && message>" ")
      {alert(message);}

   return message;

}
// end of function CheckDate
// ------------------------------------------------------------------------

function CheckLength(text, min, max){
	// Check text string is of required length.

	// set default lengths if not passed
	min = min || 1;
	max = max || 10000;

	if (text.length < min || text.length > max) {
		return false;
	}

	return true;
}

// end of function CheckLength
// ---------------------------------------------------------------------------

function EmailValid(str) {
	// Validate email address parameter.  Returns validation message if invalid, empty
	//  string if valid.
	// Note: basic client-side checks only are done here.

	var at="@" ;
	var dot="." ;
	var lat=str.indexOf(at) ;       // @ position
	var lstr=str.length ;
	var ldot=str.indexOf(dot) ;     // . position
	var errmess = "" ;              // initialise return value

	if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
		errmess = "'@' must exist (cannot be first/last character)"
	}

	// . must exist and cannot be 1st or last character
	if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
		errmess = "'.' must exist (cannot be first/last character)"
	}

	// spaces not permitted
	if (str.indexOf(" ")!=-1){
		errmess = "Spaces not permitted in email address"
	}

	return errmess ;
}

// end of function EmailValid
// ----------------------------------------------------------------------------

function IsNumeric(num) {
	// Returns true if string contains only valid numeric characters, otherwise returns
	//  false.

	return num.length>0 && (num >=0 || num < 0);
}

// end of function IsNumeric
// ---------------------------------------------------------------------------

function Left(str, n){
   // Returns leftmost n characters from string

   if (n <= 0)
       {return "";}
   else if (n > String(str).length)
       {return str;}
   else
       {return String(str).substring(0,n);}
}
// end of function Left
// ----------------------------------------------------------------------------

function NumericInput(event){
/* Limits input to numeric characters only
Bind function to textbox as follows...
<input type="text" name="aNumberField" onkeydown="numbersonly(event)"/>
*/

    if( !(event.keyCode == 8                                // backspace
        || event.keyCode == 46                              // delete
        || (event.keyCode >= 35 && event.keyCode <= 40)     // arrow keys/home/end
        || (event.keyCode >= 48 && event.keyCode <= 57)     // numbers on keyboard
        || (event.keyCode >= 96 && event.keyCode <= 105))   // number on keypad
        ) {
            event.preventDefault();     // Prevent character input
    }
}

// end of function NumericInput
// ---------------------------------------------------------------------------

function PopupWin(linkname, windowname, width, height, winattr, othparams)
{
// opens popup window with selected target and attributes

if (!window.focus) return true;        // window must be on-top and have focus

//if linkname not a string, assume <A ...> or <AREA ...> object and assign value of object's href property
var href;
if (typeof(linkname) == 'string') href=linkname; else href=linkname.href;

// set default param. values if necessary
if (winattr==null) {winattr='';}
if (othparams==null) {othparams='';}

//center in screen by default
var left = parseInt((screen.availWidth -width) /2);    // integer only required
var top  = parseInt((screen.availHeight-height)/2);
if (othparams.indexOf('TOPLEFT')>-1){left=0; top=0;}

var modalwin=false;
if (winattr.indexOf('modal')>-1){modalwin=true;}


/* Not all browsers interact with JavaScript in the same way to produce modal
windows (eg. IE does not have modal=yes attribute for window.open(), and FireFox
only introduced showModalDialog from verion 3.0 onwards, and some Netscape/Opera
versions do not support modal windows at all).  The best that we can do is to
combine methods.  We don't want to test which browser that the browser itself
claims to be since most Opera browsers claim to be IE.  Instead we test for
support for the showModalDialog method itself to identify which browsers support
it. Combining the code together gives us the following... (Note: location bar is
hidden by default */

if (modalwin && window.showModalDialog)    // showModalDialog method must exist in browser (&& is AND operator)
{
	window.showModalDialog(linkname, windowname,
	 "dialogWidth:"+width+"px; dialogHeight:"+height+"px; dialogTop:"+top
	 +"px; dialogLeft:"+left+"px; status:no; center:yes");

} else {

	window.open(href, windowname,
	 'width='+width+', height='+height+', top='+top+',left='+left
	 +', '+winattr+ ', location=no, status=no, modal=yes');
	}

window.location.reload();  // ensures parent window refreshed when popup closed

return false;
}

// endfunc PopupWin()
// --------------------------------------------------------------------------

function reportArray(errors){
	// Output array elements line-by-line via. alert messagebox

	var msg = "There were some problems...\n";
	var numError;

	for (var i = 0; i<errors.length; i++) {
		numError = i + 1;
		msg += "\n" + numError + ". " + errors[i];
	}

	alert(msg);
}

// end reportArray()
// --------------------------------------------------------------------------

function Right(str, n){
    if (n <= 0)
       {return "";}
    else if (n > String(str).length)
       {return str;}
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}
// end of function Right
// ---------------------------------------------------------------------------

function test(){
   alert("Testing, testing...");
}

// ----------------------------------------------------------------------

function Upper(element){
/* Convert contents of passed element to uppercase.

Sample syntax: <input name="text" type="text" onkeyup="upper(this)" />
(Note: onkeyup is better than onkeydown because it doesn't wait until following
keypress to refresh contents)
*/

element.value = element.value.toUpperCase();
}

// end of function Upper()
// ----------------------------------------------------------------------

function ValidDecimal(str,decpl){
   /* Returns true/false if string has required number of decimal places

   Parameters:
      str: string to validate (mandatory)
      decpl: no. of decimal places (mandatory)
	*/

	retval = false                   // default return value

	if (str.indexOf('.') == -1)
		str += ".";
		var decNum = str.substring(str.indexOf('.')+1, str.length);

		if (decNum.length > decpl)
			{return true}
		else {return false}

	return retval
}

// end ValidDecimal()
// ----------------------------------------------------------------------


function ValidChars(string,mode,decpl,message){
/* Checks string for permitted characters as indicated by mode.

Parameters:
	string - string being validated (mandatory)
   mode - determines character list against which string characters are checked
    (mandatory, not empty)
    (Note: If mode not recognised, mode becomes permitted char. list)
   decpl - no. of decimal places (for numeric type only - default to 0 - optional)
   message - message to display if invalid (optional)
*/

	// set default values for non-passed parameters
	if (typeof decpl == 'undefined' ) {decpl = 0;}
	if (typeof message == 'undefined' ) {message = "";}

   var validchars = '';                   // permitted character list
   var alphalist = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; // default alpha list
   var numlist = '0123456789';            // default integer list
   var result = true;                     // init. as all chars. ok
   mode = mode.toUpperCase();             // for consistency
   num_mode = (Left(mode,3)=='NUM') ? true:false;  // number mode - eg. NUMBER, NUMERIC

   if (num_mode)
      {validchars = numlist+'.-';}
   else if (mode == 'ALPHA')
      {validchars = alphalist;}
   else if (mode =='ALPHANUMERIC')
      {validchars = numlist+alphalist;}
   else if (mode == 'INTEGER')
      {validchars = numlist;}
   else if (mode == 'DATE')
      {validchars = numlist+'/';}
   else
      {validchars = mode;}      // assume valid chars passed as parameter


   if (string.length == 0)
      {result = true;}          // assume we don't validate empty strings
   else {
      //  test string consists of valid characters listed above
      for (i = 0; i < string.length && result == true; i++)
         {
         strChar = string.charAt(i);

         if (validchars.indexOf(strChar) == -1)
            {
            result = false;
            }
         }
      }

	/* Check for correct no. of decimal places.
	Note: this could be a separate function, but as string would still have to be
	checked for numeric characters only, it might as well be included within this
	function. */
	if (result==true && num_mode && decpl>0){
		pointpos = string.indexOf('.'); 		// get decimal point position

		if (pointpos == -1)
			{result = false; message = "Value must include decimal point";}
		else {
		   if (string.substr(pointpos+1).length == decpl)  // get string length after dec.pt.
		   	{result = true ;}
		   else
		   	{result = false; message="Invalid no. of decimal places";}
		   }
		}

   if (result==false){
      // set default message if necessary
      if (message == ""){
   		message = "Invalid character(s) present";
   	}

   	alert(message);
	}

   return result;
}

// end of function ValidChars
// ---------------------------------------------------------------------------


function WinSize(winwidth,winheight,othparams){
   /* Resizes window to specified dimensions, and moves window to specified location.
   Note: this function must be called AFTER <body> tag, as window must already be
   defined.

   Sample syntax:
   <script>
      winsize(900,600,'CENTER')
   </script>*/

   // set default param. values if necessary
   if (othparams==null) {othparams='';}

   /* Note: resizeTo does not work in Internet Explorer, so to make function as
   cross-platform as possible, specify top/left/width/height coordinates.
   self.resizeTo(winwidth,winheight); */

   var left=0
   var top =0

   if (othparams.indexOf('CENTER')>-1)
   {
      left = parseInt((screen.availWidth  - winwidth) /2);    // integer only required
      top  = parseInt((screen.availHeight - winheight)/2);
   }

   /* Note: dialogHeight property applies only to windows that are created by
   using the showModalDialog method and the showModelessDialog method. */
   if (navigator.appName=="Microsoft Internet Explorer") {
      window.dialogHeight = winheight+'px';
      window.dialogWidth  = winwidth +'px';

      window.dialogHeight = winheight
      window.dialogWidth  = winwidth
      window.dialogTop    = top
      window.dialogLeft   = left

   }
   else {

          window.moveTo(left,top);
          window.resizeTo(winwidth,winheight);
   }
}

// end of function WinSize()
// ---------------------------------------------------------------------------

function WinSize_old(winwidth, winheight, othparams)
{
   /* Resizes window to specified dimensions, and moves window to specified location.
   Note: this function must be called AFTER <body> tag, as window must already be
   defined.

   Sample syntax:
   <script>
      winsize(900,600,'CENTER')
   </script>
   */

   // set default param. values if necessary
   if (othparams==null) {othparams='';}

   self.resizeTo(winwidth,winheight);

   /*if (othparams.indexOf('CENTER')>-1)
   {
      var left = parseInt((screen.availWidth  - winwidth) /2);    // integer only required
      var top  = parseInt((screen.availHeight - winheight)/2);

      self.moveTo(left,top);
   }*/
}

// end of function WinSize_old()
// ---------------------------------------------------------------------------
