//  Forms.js
//  JavaScript utilities for forms.
//  Created AW - 2004/04/23 from Form_Utils.js v 2.8, of which this is also a cleanup.
//  CVS version : $Id: Forms.js,v 1.17 2007/01/16 18:11:44 efs Exp $
// (2.8 at time of CVS start)
// Note : modified ex-CVS aw 2007/02/10 : added getRadioValue()

var debug = 0;  // set to 0 for normal run
var msg = "";   // display message
var req_default = " Bitte Feld %s ausfüllen !! "; // "Required field" message, default value
var req_default_en = " Please fill field %s !! ";
var req_default_fr = " Veuillez compléter le champ %s !! ";
var req_default_es = " Por favor, completar el campo %s !! ";

// Define an array with the number of days in each month
// Start with element[0] = 0, so that indexes correspond to month numbers
// Days for February will be checked programmatically
var daysInMonth = new Array (0,31,29,31,30,31,30,31,31,30,31,30,31);

function isBlank(s) {
// return true if blank, else false
    var c = s.match(/\S+/); // any non-blank ?
    if (c == null) return true;
    return false;
}

function isEmpty(e) {
// e is an input element
// return true if blank or empty, else false
   // alert("checking element " + e.name);
   var t = e.type;
   if (t == null) {
     alert("Error : isEmpty() : argument is invalid ! (perhaps multi-value thing ?)");
     return true;
   }
   if (t.match(/^(checkbox|radio)/i)) {
      // for a Radio or Checkbox, test the "checked" attribute
      if (e.checked) {
        // alert("it's checked : " + e.value);
	return false;
      }
      // alert("it's not checked");
      return true;
   }
   if (t.match(/^select/i) != null) {
      // for a SELECT, we have to look at the selected index
      if (e.selectedIndex == -1) {
        return true;
      }
      return false;
   }
   // for all others, we check the value
   var v = e.value;
   if (v.match(/\S+/) == null) {
     // alert("it's empty");
     return true;
   }
   // alert("it's not empty : " + e.value);
   return false;
}

function formVerif (f) {
var idx1;                       // general index var
var el;                         // form element
var el_name;                    // element name
var el_value;                   // element value
var el_label;                   // element "display label"
var el_type;                    // element type
var el_idx;                     // element index in form.elements[]
var regmatch = new Array();     // for regexp matches
var b_names = new Array();      // for names of elements that cannot be blank
var b_labels = new Array();     // for the labels to display for those fields
var idx2;                       // index into b_names[] and b_labels
var req_msg = "";               // "Required field" message
var path_labels = new Array();	// collect names of "*GETPATHx" elements
var idx3;			// index into path_labels[]
var path_opts;			// to split values
var path_from;
var path_to;
var el_from;
var el_to;
var path_delete;

	if (f.elements['*JSDEBUG'] != null) debug = f.elements['*JSDEBUG'].value;

        if (debug != 0) alert('==>formVerif(' +f.name + ') ');
        req_msg = req_default; // init "required" message to default
	if (f.elements['*LANG'] != null) {
	  var lan = f.elements['*LANG'].value;
	  var lanmsg;
	  if ((lanmsg = eval("req_default_" + lan)) != null) req_msg = lanmsg;
	  if (debug != 0) alert("message set to : " + req_msg);
	}


// Part 1 : loop through all input elements, and store the names of the required ones
//      For this, we detect the ones that are hidden and whose name ends in "-required".
        idx2 = 0; idx3 = 0;
        for (idx1 = 0 ; idx1 < f.elements.length ; idx1++) {

                el = f.elements[idx1];
                el_type = el.type.toUpperCase();
                el_name = el.name;
                el_label = el.value; // if it exists, it is the label to display

                if (debug != 0) {
                    alert('Element(' + idx1 + ' : ' + el_name + ', type = ' + el_type + "\n");
                }

                if (el_name == "form_required_msg") {
                        // replace default message
                        req_msg = el.value;
                        continue;
                }

                if (el_type == "HIDDEN") {
                        // if there is a "-required" suffix, note the main field name
                        regmatch = el_name.match(/^([A-Za-z0-9.]+(\-\d*)?(\-\w)?)\-required$/i);
                        if (regmatch != null) {
                                if (debug != 0) {
                                    alert('Found required : ' + regmatch[1] + " (" + el_label + ")" + "\n");
                                }
                                b_names[idx2] = regmatch[1];
                                b_labels[idx2] = el_label;
                                idx2++;
				continue;
                        }

			// 2.7 new
                        regmatch = el_name.match(/^(\*GETPATH\d?)$/i);
                        if (regmatch != null) {
                                if (debug != 0) {
                                    alert('Found GETPATHx element : ' + el_name + "\n");
                                }
                                path_labels[idx3] = el_name;
                                idx3++;
				continue;
                        }
			// end 2.7

                }

        } // end for idx1

// Part 2 : loop through b_names[] elements if any, and check if blank
//              v 1.3 : for "select" items, check if selection made
//

        for (idx2 = 0; idx2 < b_names.length; idx2++) {

                el_name = b_names[idx2]; // the stored element name
                el_label = b_labels[idx2]; // the stored element display label if any

                el = f.elements[el_name]; // the element object itself

                if (debug != 0) {
                        alert(' Checking required element : ' + el_name + "\n");
                }

                if (isEmpty(el)) {
                        // display given label if provided, else catch-all message
                        if (debug != 0) {
                                alert(' Replacing =label= in \"' + req_msg + "\"\n"
                                        + ' by \"' + el_label + "\"\n");
                        };

                        if (isBlank(el_label)) {
                                req_msg = req_msg.replace(/%s/gi,"");
                        } else {
                                req_msg = req_msg.replace(/%s/gi, "\"" + el_label + "\"");
                        }
                        alert(req_msg);
                        el.focus();   // let's point to it
                        return false;
                }  // end if isBlank

        } // end for idx2

// new 2.7
// Part 3 : loop through path_labels[] elements if any, and do whatever needs to be done
//

	if (debug != 0) {
		alert(' processing GETPATH elements');
	}

        for (idx3 = 0; idx3 < path_labels.length; idx3++) {

                el_name = path_labels[idx3]; // the stored element name
                el = f.elements[el_name]; // the element object itself
		el_value = el.value; // the stored value

                if (debug != 0) {
                        alert(' processing GETPATH element : ' + el_name + "\n");
                }

		path_delete = 0;
		path_opts = el_value.split(";");
		if (path_opts[2] == "D") { path_delete = 1; }
		path_from = path_opts[0]; path_to = path_opts[1];
		if ((path_from == null) || (path_to == null)) {
			if (debug != 0) { alert("** error in element " + el_name + ", ignored"); }
			continue;
		}
		el_from = f.elements[path_from]; el_to = f.elements[path_to];
		if ((el_from == null) || (el_to == null)) {
			if (debug != 0) { alert("** error in element " + el_name + ", ignored"); }
			continue;
		}
		el_to.value = el_from.value; // this should copy the path
		if (path_delete == 1) {
			if (debug != 0) { alert("deleting element " + el_from.name); }
			// el_from = null;
			// delete f.elements[path_from]; // delete the element
			// f.elements[path_from] = null; // delete the element
			el_from.parentNode.removeChild(el_from);
		}

        } // end for idx3

        if (debug != 0) {
            alert('formVerif(' +f.name + ') ' + "\n" +
                 'End !');
        }

        return true;
}

function pasteVal (parent_field,this_field) {
// Paste the value of the field "this_field" in current window
// to INPUT field "parent_field" in the first form of the parent window.
// Can only be used in a "child" window opened by another window

    if (debug != 0) alert('pasteVal(), sending value of ' + this_field.name + ' to parent field ' + parent_field);

        // get target field info

        var papawin=window.opener;
            // if (debug != 0) alert('papawin-type = ' + typeof(papawin) + ', parent window name = ' + papawin.name);
        var papaform=papawin.document.forms[0];
            // if (debug != 0) alert('papaform-type = ' + typeof(papaform) + ', parent form name = ' + papaform.name);
            // if (debug != 0) alert('target field = ' + papaform.elements['OFILE'].name);

        // Get "value" of the current field, depending on it's type

        var ThisValue = "";
        var ThisType = this_field.type;
        var ThisMatch = ThisType.match(/^SELECT/i); // is it a <SELECT> item ?

        if (ThisMatch == null) {
                // it's not a SELECT, then just take it's "value" property
                ThisValue = this_field.value;
        } else {
                // for a SELECT, we have take the "value" of the selected option
                if (this_field.selectedIndex == -1) {
                        // if there's none, take blank
                        ThisValue = "";
                } else {
                        // else get the value of the selected option
                        ThisValue = this_field.options[this_field.selectedIndex].value;
                }
        }


        papaform.elements[parent_field].value = ThisValue;
        papawin.focus();
        return true;
}

function newWinWH (url,wi,hi) {
// open another window, with the url given as document, and dimensions
// given by wi (width) and hi (height)

// Because we can come from within a Star-generated page, we must be careful since
// these pages set the "base href" to "..cgi-bin/starfinder/.."

        var myMsg = "";
        // var myurl = escape(url);
        var myurl = url;
        myurl = myurl.replace(/(\015|\012)/g,""); // strip any CR or LF
        // var myLoc = new Location(myurl);

        // myurl = escape(myurl); // cgi-encode this
        debug == 0 ? debug = 0 : alert('newwinh(), myurl = ' + url);

        var winFeatures =
                  'location=yes,directories=no,toolbar=no,scrollbars=yes,resizable=yes'
                + ',height=' + hi
                + ',width=' + wi;

        debug == 0 ? debug = 0 : alert('newwinh(), opening window, features = ' + winFeatures);

        var frmwin = window.open(myurl,'FrmWin', winFeatures); // open the window with the requested url
        // var frmwin = window.open('','FrmWin', winFeatures); // open the window, blank
        frmwin = window.open('','FrmWin'); // make sure we have a ref.

        // frmwin.location = myurl; // get it to load what we want ?

        myMsg = "";
        myMsg += "location.protocol : ";
        if (frmwin.location.protocol != null) {
                myMsg += frmwin.location.protocol
        } else {
                myMsg += " (null) "
        }

/*      myMsg += "location.host : ";
        if (frmwin.location.host != null) {
                myMsg += frmwin.location.host
        } else {
                myMsg += " (null) "
        } */

        myMsg += "location.pathname : ";
        if (frmwin.location.pathname != null) {
                myMsg += frmwin.location.pathname
        } else {
                myMsg += " (null) "
        }

        myMsg += "location.search : ";
        if (frmwin.location.search != null) {
                myMsg += frmwin.location.search
        } else {
                myMsg += " (null) "
        }

        debug == 0 ? debug = 0 : alert('newwinh(), window name = ' + frmwin.name + "\n" + myMsg);

        // frmwin.location.reload(true); // and again
        frmwin.moveTo(10,10); // small offset to make sure it's distinguishable
        frmwin.focus();

        return false; // we don't want to submit the calling form
}

function openPickWin (url,wi,hi) {
// open another window, with the url given as document, and dimensions
// given by wi (width) and hi (height)
// also create a new var in this window, referring back to the opening window

        var myMsg = "";
        var myurl = url;
        myurl = myurl.replace(/(\015|\012)/g,""); // strip any CR or LF
        debug == 0 ? debug = 0 : alert('openPickWin(), myurl = ' + url);

        var winFeatures =
                  'location=yes,directories=no,toolbar=no,scrollbars=yes,resizable=yes,status=yes'
                + ',height=' + hi
                + ',width=' + wi;

        debug == 0 ? debug = 0 : alert('openPickWin(), opening window, features = ' + winFeatures);

        var pickwin = window.open(myurl,'PickWin', winFeatures); // open the window with the requested url
        pickwin = window.open('','PickWin'); // make sure we have a ref.
        pickwin.win_opener = self; // ??
        pickwin.moveTo(30,30); // small offset to make sure it's distinguishable
        pickwin.focus(); // bring it in front

        return pickwin; // return this window object
}

function newPickWin (url,wi,hi,fld,pickurl) {
// open a picklist window (see PickList.js)
// url : the html frameset document for the picklist window.
//	This frameset document must specify 2 frames :
//		- "pick_top" : the frame where the picklist will appear
//		- "pick_bot" : the fixed frame with buttons
// wi,hi = total width & height in pixels of the picklist window
// fld : a ref. to the input field object (of the original form) into which the picklist result must be pasted
// pickurl : the URL to be used to fill the picklist window
//	If not specified, then the frameset document must specify a source url for the pick_top frame

	var savedebug = debug;
	debug = 0;
        debug == 0 ? debug = 0 : alert('==>newPickWin()');

	var botframe = null;
	var topframe = null;
	var pickwin = null;

	// Note : the form window MUST contain a line "var picklist_target;"
	window.picklist_target = fld; // set this top-level var to the target field
	debug == 0 ? debug = 0 : alert("newPickWin() : window.picklist_target type is \"" + typeof(window.picklist_target) + "\"");
	debug == 0 ? debug = 0 : alert("newPickWin() : window.picklist_target is \"" + window.picklist_target.name + "\"");

        var myurl = url;
        myurl = myurl.replace(/(\015|\012)/g,""); // strip any CR or LF

	if (pickurl != null) {
		// if a url is specified for the picklist frame, then load it,
		// else it must be a fixed one, so leave it alone
		window.picklist_url = pickurl; // load the picklist in the top frame
		// alert("newPickWin() : window.picklist_url is \"" + window.picklist_url + "\"");
	}

        var winFeatures =
                  'location=yes,directories=no,toolbar=no,scrollbars=yes,resizable=yes,status=yes'
                + ',height=' + hi
                + ',width=' + wi;

	// debug == 0 ? debug = 0 : alert('newPickWin(), opening window, features = ' + winFeatures);

	var pickwin = window.open(myurl,'PickWin', winFeatures); // open the window with the requested url
        pickwin = window.open('','PickWin'); // make sure we have a ref.
	debug == 0 ? debug = 0 : alert("newPickWin() : pickwin type is \"" + typeof(pickwin) + "\"");
	debug == 0 ? debug = 0 : alert("newPickWin() : pickwin name is \"" + pickwin.name + "\"");

	// get a ref. to the bottom frame (the buttons frame)
	// botframe = pickwin.frames['pick_bot'];
	// debug == 0 ? debug = 0 : alert("newPickWin() : botframe type is \"" + typeof(botframe) + "\"");
	// debug == 0 ? debug = 0 : alert("newPickWin() : botframe name is \"" + botframe.name + "\"");

	// get a ref. to the top frame (the picklist frame)
	// topframe = pickwin.frames['pick_top'];
	// debug == 0 ? debug = 0 : alert("newPickWin() : topframe type is \"" + typeof(topframe) + "\"");
	// debug == 0 ? debug = 0 : alert("newPickWin() : topframe name is \"" + topframe.name + "\"");

        pickwin.moveTo(30,30); // small offset to make sure it's distinguishable
        pickwin.focus(); // bring it in front

        debug == 0 ? debug = 0 : alert('<==newPickWin()');
	debug = savedebug;

        return; // return this window object
}

function checkDate (i) {
        // where i is an input element (like a text box)
        // Check and reformat a date input field value, following the general "Star" rules
        // for European dates.

        var ival = i.value; // the input element's value
        var td = new Date();  // today as a Date
        // alert("checkDate(), today : \n" + "d = " + td.getDate() + "\n"
        //       + "m = " + (td.getMonth() + 1) + "\n" + "y = " + td.getFullYear());

        // somewhat convoluted code to work around IExplorer bug in substr(-x,y)
        var tdd = "00" + td.getDate() + ""; tdd = tdd.substr((tdd.length-2),2);
        var tdm = "00" + (td.getMonth() + 1) + ""; tdm = tdm.substr((tdm.length-2),2);
        var tdy = "0000" + td.getFullYear() + ""; tdy = tdy.substr((tdy.length-4),4);
        var ind, inm, iny;

        // alert("checkDate(), today : \n" + "d = " + tdd + "\n" + "m = " + tdm + "\n" + "y = " + tdy);

        // strip leading & trailing spaces
        ival = ival.replace(/^\s+/,""); ival = ival.replace(/\s+$/,"");

        // Handle different input formats we may receive.
        // ".." and "//" are interpreted as "today" in "0d/0m/yyyy" format

        // We accept (2) :
        //      input form      interpreted as          converted to (3)
        //      dd/mm/yyyy      dd/mm/yyyy              0d/0m/yyyy
        //      d/mm/yyyy       0d/mm/yyyy              0d/0m/yyyy
        //      d/m/yyyy        0d/0m/xxyy              0d/0m/yyyy (1)
        //      d/m/yy          0d/0m/xxyy              0d/0m/yyyy (1)
        //      mm/yyyy         01/mm/yyyy              01/0m/yyyy
        //      m/yyyy          01/0m/yyyy              01/0m/yyyy
        //      ddmmyy          0d/0m/xxyy              0d/0m/yyyy (1)
        //      ddmmyyyy        0d/0m/yyyy              0d/0m/yyyy

        // (1) in 2-digit forms of year, values 01-50 are interpreted as 2001-2050,
        //      values 51-99 as 1951-2000, value 00 as 2000
        // (2) "." is accepted as delimiter instead of "/"
        // (3) output format always uses "/" as delimiter

        // blank or empty is allowed, and replaced by empty
        if (ival == "") {
                i.value = "";
                return;
        }

        // simple case first (today abbreviations)
        if ((ival == "..") || (ival == "//")) {
                i.value = tdd + "/" + tdm + "/" + tdy;
                return;
        }

        // delimited cases :
        var parts = new Array();
        // a) all valid forms with 2 delimiters
        parts = ival.match(/^(\d{1,2})(\/|\.)(\d{1,2})(\/|\.)(\d{4}|\d{2})$/);
        if (parts != null) {
                ind = parts[1]; inm = parts[3]; iny = parts[5];
        } else {
                // b) all valid forms with 1 delimiter
                parts = ival.match(/^(\d{1,2})(\/|\.)(\d{4}|\d{2})$/);
                if (parts != null) {
                        ind = "01"; inm = parts[1]; iny = parts[3];
                } else {
                        // c) ddmmyy or ddmmyyyy only left
                        parts = ival.match(/^(\d\d)(\d\d)(\d{4}|\d{2})$/);
                        if (parts != null) {
                                ind = parts[1]; inm = parts[2]; iny = parts[3];
                        } else {
                                // invalid input
                                i.value = "";
                                i.focus();
                                return;
                        }
                }

        }

        // alert("checkDate(), parsed : " + ind + " / " + inm + " / " + iny);

        // check and reformat year
        if (iny < 1000) {
                if (iny == 0) {
                        iny = 2000;
                } else {
                        iny = iny - 0; // to force numeric
                        iny = (iny > 50 ? iny + 1900 : iny + 2000);
                }
        }

        // check month
        if (( inm < 1 ) || ( inm > 12)) {
                i.value = "";
                i.focus();
                return;
        }

        // check day
        if (( ind < 1 ) || ( ind > daysInMonth[inm] )) {
                i.value = "";
                i.focus();
                return;
        }
        // For February, check day again
        if ( inm == 2) {
                if ( ind > daysInFeb(iny)) {
                        i.value = "";
                        i.focus();
                        return;
                }
        }

        // Now it should be ok, we can reformat the date and proceed
        // somewhat convoluted code to work around IExplorer bug in substr(-x,y)
        ind = "00" + ind + ""; ind = ind.substr((ind.length-2),2);
        inm = "00" + inm + ""; inm = inm.substr((inm.length-2),2);
        iny = "0000" + iny + ""; iny = iny.substr((iny.length-4),4);
        i.value = ind + "/" + inm + "/" + iny + "";
        return;

}

function daysInFeb (year) {
        // February has 29 days in any year evenly divisible by four,
        // EXCEPT for centurial years which are not also divisible by 400.
        return (  ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}

function cookie2Field (cookiename,formname,fieldname) {
// get the value of a cookie and paste it into a form field
// alert("cookie2Field()");
var f = document.forms[formname];
var sid = f.elements[fieldname];
sid.value = getCookieVal(cookiename);
// alert("cookie is : " + sid.value);
return true;
}

function getCookieVal (name) {
  var cname = name;
  var lname = cname.length;
  var allcookies = document.cookie;
  if (allcookies == "") return null;
  var start = allcookies.indexOf(cname + '=');
  if (start == -1) return null;
  start += lname + 1; // skip name and = sign
  var end = allcookies.indexOf(';',start); // get the first following ; or end of string
  if (end == -1) end = allcookies.length;
  return allcookies.substring(start,end);
}

function setCookiesLink (linktxt) {
// scans link text for "::name::" sequences.
// Each time such a sequence is found, it is replaced by the value of the cookie
// who's name is "name" (or "" if not found).
// When all replacements have been made, the modified link is "called".
//  alert("setCookiesLink(" + linktxt + ")");
  var cname;
  var cvalue;
  var rest = linktxt;
  var first = 0;
  var limit = rest.length;
  var dest = "";
  var re = /::(\w+)::/g; // regexp to search for embedded cookie names
  while ((found = re.exec(rest)) != null) {
    cname = found[1]; // the "name" part
    dest += rest.substring(first,found.index);
    first = re.lastIndex;
    // alert("dest1=" + dest + "\ncname=" + cname + "\nfirst=" + first );
    cvalue = getCookieVal(cname); // get the cookie or null
    if (cvalue == null) cvalue = "";
    dest += cvalue;
    // alert("dest2 : " + dest);
  }
  dest += rest.substring(first,limit);
  // alert("new link : " + dest);
  window.location = dest;
}

function formSubmit (lfform,lfaction) {
  if (lfaction == "main-submit") {
    lfform.elements['*ACTION'].value = "main-submit";
    if (formVerif(lfform)) lfform.submit();
    // return false;
  }
  if (lfaction == "main-cancel") {
    lfform.elements['*ACTION'].value = "main-cancel";
    lfform.submit();
  }
  if (lfaction == "ok-more") {
    lfform.elements['*ACTION'].value = "ok-more";
    lfform.submit();
  }
  if (lfaction == "ok-cancel") {
    lfform.elements['*ACTION'].value = "ok-cancel";
    lfform.submit();
  }
// alert("*ACTION set to " + lfform.elements['*ACTION'].value);
  return "";
}

function vfSubmit (lfform) {
// use for <a href='javascript:vfSubmit(f);'> (as last in expression)
    if (formVerif(lfform)) lfform.submit();
    // return null;
}


function MiraSearchSubmit (ff,fwin) {
// submit a web4 search form as a web4 fastlink, in a Mira (and starlog4) context
// If there is a second parameter, take it as the name of the window to open,
// else use 'new_win'
// Since this is a web4/starlog4 context, we assume that the search form already contains
// 2 hidden parameters :
// <input type="hidden" name="wdir" value="starweb-webapps-subdirectory-path">
// <input type="hidden" name="wsess" value="starweb-webapps-session-file-path">
// Other form parameters (the search elements) should be submitted automatically by the form,
// to be interpreted by Star Web4.
// Star Web 4 also fgures out itself the type of input element, and handles them
// appropriately.
// In other words, do we need to do anything here, other than opening it in a new window ?
var theform = ff;
var winname = fwin;
if (winname == null) winname = 'new_win';
var fast_url = "";
var fast_root = "/scripts/starlog.pl";
var fast_sess = "path=";
var fast_report = "format=WLINK";
var fast_searches = "";
var sel_idx;
var sel_option;
var srch_label = "";
var srch_text1 = "";
var srch_text2 = "";
var srch_text3 = "";
var srch_text4 = "";
var elem;

var newwin_features = 'location=yes,directories=no,toolbar=yes,scrollbars=yes,resizable=yes'
                + ',height=400,width=800';

  if (debug != 0) {
    alert('opening new window for URL : "' + fast_url + '"');
  }

// open the target window if it does not already exist; else we get a reference to the existing one
  var newwin = window.open('',winname,newwin_features);

  theform.target = newwin.name;
  theform.action = "/scripts/starlog4.pl";
  theform.submit();
  newwin.focus();
  return false;

}

function starlog_remove (domain) {
  var doc=window.document;
  var cname = 'starlog';
  var allcookies=doc.cookie;
  var start = allcookies.indexOf('starlog=');
  if (start == -1) {
	// alert("No starlog cookie found");
	return;
  }
  var cdomain = '';
  if (domain != null) cdomain = domain;
  var date = new Date();
  date.setTime(date.getTime()+(-1*24*60*60*1000)); // set to "yesterday"
  var cexpires = "; cexpires=" + date.toGMTString();
  var newcookie = cname + "=" + cexpires + "; path=/";
  if (cdomain != '') newcookie += '; domain=' + cdomain;
  doc.cookie = newcookie;
  // alert("starlog cookie removed");
  return;
}

function cookieRemove (cookiename,domain) {
  var doc=window.document;
  if (cookiename == null) {
    // alert("No cookie name supplied");
    return;
  }
  var cname = cookiename;
  var allcookies=doc.cookie;
  var start = allcookies.indexOf(cname+'=');
  if (start == -1) {
	// alert("cookie " + cname + " not found");
	return;
  }
  var cdomain = '';
  if (domain != null) cdomain = domain;
  var date = new Date();
  date.setTime(date.getTime()+(-1*24*60*60*1000)); // set to "yesterday"
  var cexpires = "; cexpires=" + date.toGMTString();
  var newcookie = cname + "=" + cexpires + "; path=/";
  if (cdomain != '') newcookie += '; domain=' + cdomain;
  doc.cookie = newcookie;
  // alert("cookie " + cname + " removed");
  return;
}

function show_id (_theId) {
// argument is a string containing the id of the target element
  var thisElement = document.getElementById( _theId );
  if (thisElement == null) return;
  thisElement.style.display = "block";
  return;
}

function hide_id (_theId) {
// argument is a string containing the id of the target element
  var thisElement = document.getElementById( _theId );
  if (thisElement == null) return;
  thisElement.style.display = "none";
}

function toggleshow_id (_theId) {
// argument is a string containing the id of the target element
  var thisElement = document.getElementById( _theId );
  if (thisElement == null) return;
  if (thisElement.style.display == "none") {
    thisElement.style.display = "block";
  } else {
    thisElement.style.display = "none";
  }
  return;
}

function popupSelectWindow (frm,tgtname,listreg,baseurl) {
// Used in Ska "attribute persons to rooms" function
// This function requires a "var SelectWindowTargetField;" declaration in the
// document loaded in the SelectWindow that it opens
// frm : the form object containing the target field
// tgtname : the name of the target field in frm
// listreg : a regexp string representing the names of the elements in frm where
//		we should pick up already-filled values
// baseurl : the base URL to which we paste our results before we use it
//		to open the SelectWindow (a Star search+report page)
  var targetfield=frm.elements[tgtname]; // where we paste results
  var lreg = new RegExp(listreg);
  // alert("search regexp is /" + lreg.source + "/");
  var names = '';
  var idx1;
  for (idx1 = 0 ; idx1 < frm.elements.length ; idx1++) {
	  el = frm.elements[idx1];
	  // el_type = el.type.toUpperCase();
	  el_name = el.name;
	  // alert("field : " + el_name + "match result : " + el_name.match(lreg));
	  if (el_name.match(lreg) != null) { // if it matches
		  names += el.value;
		  // alert("field " + el_name + " matches\n" + "names is now : " + names);
	  }
  }
  var winurl = baseurl + escape(names);
  // alert("going to open window, url = " + winurl);
  var SelectWindow = window.open(winurl,'Popupfenster','width=650,height=700,resizable=yes,scrollbars=yes');
  // let the SelectWindow know where it should paste back results
  SelectWindow.SelectWindowTargetField = targetfield;
  SelectWindow.focus();
}
function popupSelectWindow2 (frm,tgtname,listreg,baseurl) {
// 2007/01/16 aw : modified version op popupSelectWindow() :
//	instead of collecting one large string and appending it to the URL,
//	each collected element becomes now a &X1=string&X2=string etc...
// This also means that the base URL should not end in "&search1=".
// This is because the string was becoming too long for a single Star search
// expression.
// Used in Ska "attribute persons to rooms" function
// This function requires a "var SelectWindowTargetField;" declaration in the
// document loaded in the SelectWindow that it opens
// frm : the form object containing the target field
// tgtname : the name of the target field in frm
// listreg : a regexp string representing the names of the elements in frm where
//		we should pick up already-filled values
// baseurl : the base URL to which we paste our results before we use it
//		to open the SelectWindow (a Star search+report page)
  var targetfield=frm.elements[tgtname]; // where we paste results
  var lreg = new RegExp(listreg);
  // alert("search regexp is /" + lreg.source + "/");
  var names = '';
  var idx1;
  var idx2 = 1;
  var searchParam = '';
  var collectSearches = '';
  for (idx1 = 0 ; idx1 < frm.elements.length ; idx1++) {
	  el = frm.elements[idx1];
	  // el_type = el.type.toUpperCase();
	  el_name = el.name;
	  // alert("field : " + el_name + "match result : " + el_name.match(lreg));
	  if (el_name.match(lreg) != null) { // if it matches
		  searchParam = '&x' + idx2 + '=';
		  searchParam += escape(el.value);
		  idx2++;
		  collectSearches += searchParam;
		  // alert("field " + el_name + " matches\n" + "names is now : " + names);
	  }
  }
  var winurl = baseurl + collectSearches;
  // alert("going to open window, url = " + winurl);
  var SelectWindow = window.open(winurl,'Popupfenster','width=650,height=700,resizable=yes,scrollbars=yes');
  // let the SelectWindow know where it should paste back results
  SelectWindow.SelectWindowTargetField = targetfield;
  SelectWindow.focus();
}

function pasteFromSelectWindow (unique) {
// This function requires a "var SelectWindowTargetField;" declaration in the
// document where it is used (in the SelectWindow).
  // if unique is 1, then only one value gets pasted
  var oneOnly = false;
  if (unique == 1) OneOnly = true;
  var targetfield = window.SelectWindowTargetField;
  var thisform=window.document.forms['__form']; // this is the form in this frame window
  var text=""; // initialise text to paste
  var allterms = thisform.elements['TERM']; // this is the array of 'BEM' inputs
  if (allterms.length == null) { // for single checkbox
	  if (allterms.checked) {
		  text = text + allterms.value;
	  }
  } else {
	var term;
	for (i=0; i<allterms.length; i++) {
	  term = allterms[i];
	  if (term.checked) {
		  text = text + ";" + term.value;
		  if (oneOnly) break;
	  }
	}
  }
  text = text.replace(/^\;/,""); // remove leading ';'
  targetfield.value = targetfield.value + text + ";";
  window.close();
  return true;
}

function getCheckboxValues(f,n,j) {
// scan the form f for all checkbox inputs with name n
// keep only the ones that are in the checked state
// join their values into a string, separating them by string j
// return this string
  var text=""; // initialise text to return
  var allchecks = f.elements[n]; // this is the array of inputs?
  if (allchecks.length == null) {
  // if single checkbox
	  if (allchecks.checked) {
		  text = allchecks.value;
	  }
	  return text;
  }
  // else we have an array of checkboxes
  var check;
  for (i=0; i<allchecks.length; i++) {
	check = allchecks[i];
	if (check.checked) {
		if (text != "") {
		  text = text + j;
		}
		text = text + check.value;
	}
  }
  return text;
}

function getRadioValue(f,n) {
// get the valoue of a Radio Button element
// args : form object, name of radio button
  var theRadio = f.elements[n];
  if (theRadio.length == null) {
	return;
  }
  for (var i=0; i<theRadio.length; i++) {
	if (theRadio[i].checked) {
	  return theRadio[i].value;
	  break;
	}
  }
  return;
}
function sprintf()
{
/*
======================================================================
 sprintf()
======================================================================
 Purpose : format a string

 Author  : Antoine Hurkmans, January 2002
 Modified : A. Warnier , 2005/06
----------------------------------------------------------------------
 Parameters :
 you may figure this one out yourself (hint: www.php.net/sprintf)
----------------------------------------------------------------------
 Returns : a formatted string
----------------------------------------------------------------------
 Revision History :
 05-06-2005 AW - added tests for undefined aMatch[] elements
 12-Feb-02 AH  - Added support for alternate padding char
 05-Feb-02 AH  - Fixed bug in display of decimal part for floats
 28-Jan-02 AH  - Initial Version
======================================================================
*/
	var iCount, iPadLength, aMatch, iMatchIndex = 1;
	var bAlignLeft, sPad, iWidth, iPrecision, sType;


	var aArgs = sprintf.arguments;
	if (aArgs.length < 2) return '';

	var sFormat = aArgs[0];
	var re = /%(-)?(0| |'.)?(\d+)?(\.\d*)?([bcdfosxX]{1})/; //'
	while (re.test(sFormat))
	{
		aMatch = re.exec(sFormat);
		if (aMatch[1] == null) aMatch[1] = '';
		if (aMatch[2] == null) aMatch[2] = '';
		if (aMatch[3] == null) aMatch[3] = '';
		if (aMatch[4] == null) aMatch[4] = '';
		bAlignLeft = (aMatch[1] == '-');
		sPad = (aMatch[2] == '' ? ' ' : aMatch[2]);
		if (sPad.substring(0, 1) == "'") sPad = sPad.substring(1);
		iWidth = (aMatch[3] > 0 ? parseInt(aMatch[3]) : 0);
		iPrecision = (aMatch[4].length > 1 ? parseInt(aMatch[4].substring(1)) : 6);
		sType = aMatch[5];
		mArgument = (aArgs[iMatchIndex] != null ? aArgs[iMatchIndex] : '');
		++iMatchIndex;
		if (mArgument.toString().length)
		{
			if ('fbcdoxX'.indexOf(sType) != -1 && isNaN(mArgument)) mArgument = 0;
			switch (sType)
			{
				case 'f':	// floats
					var iPower = Math.pow(10, iPrecision);
					mArgument = (Math.round(parseFloat(mArgument) * iPower) / iPower).toString();
					var aFloatParts = mArgument.split('.');
					if (iPrecision > 0)
					{
						if (aFloatParts.length == 1) aFloatParts[1] = '';
						// pad with zeroes to precision
						for (iCount = aFloatParts[1].length; iCount < iPrecision; iCount++)
							aFloatParts[1] += '0';
						mArgument = aFloatParts[0] + '.' + aFloatParts[1];
					}
					else mArgument = aFloatParts[0];

					iPadLength = aFloatParts[0].length;
					break;
				case 'b':	// binary
					mArgument = parseInt(mArgument).toString(2);
					iPadLength = mArgument.length;
					break;
				case 'c':	// character
					mArgument = String.fromCharCode(parseInt(mArgument));
					break;
				case 'd':	// decimal
					mArgument = mArgument.toString();
					iPadLength = mArgument.length;
					break;
				case 'o':	// octal
					mArgument = parseInt(mArgument).toString(8);
					iPadLength = mArgument.length;
					break;
				case 'x':	// hexadecimal (lowercase)
					mArgument = parseInt(mArgument).toString(16);
					iPadLength = mArgument.length;
					break;
				case 'X':	// hexadecimal (uppercase)
					mArgument = parseInt(mArgument).toString(16).toUpperCase();
					iPadLength = mArgument.length;
					break;
				default:	// strings
					mArgument = mArgument.toString();
					iPadLength = mArgument.length;
			}

			if ('fbdoxX'.indexOf(sType) != -1)
			{
				// pad with padding-char to width
				if (bAlignLeft)
					for (iCount = iPadLength; iCount < iWidth; iCount++)
						mArgument += sPad;
				else
					for (iCount = iPadLength; iCount < iWidth; iCount++)
						mArgument = sPad + mArgument;
			}
		}
		sFormat = sFormat.replace(re, mArgument);
	}
	return sFormat;
}


