/* Various utility JS functions by Konrads Smelkovs for WorldSoft, 2004*/


/*  Desc: 	Removes the target key from array and returns the resulting array. Useful for removing strings indexed values 
	Usage:	newArr=spliceArray("key",oldArray,all);
*/

function spliceArray(key,target){
	var retArr=new Array;
	retArr.length=target.length;
	for (var i in target){
		if(i != key){
			retArr[i]=target[i];
		}
	}
	return retArr;
}

function argObject(name,value) {
	this.name=name;
	this.value=value;
	
}

/*

	Desc:	This function makes a "remote call" to an URL, executed the code returned by the URL,
			and calls next function in chain. It is obvious that the URL invoked must follow these conventions.

	Args: 	url - URL for resource to invoke.
			args - 	Is an array of argObject types.
					First element is the name of the function to be invoked.
					The rest will be passed as GET method paramters.
	Example: 
		var call=array();
		call.push(new argObject("nextFunction","nextCall(args1,artg2)");
		call.push(new argObject("returnVar","isfree");
		call.push(new argObject("domain","konrads.ch");
		remoteCall("http://somewhere/checkDomainAvail",call);
	
	Based on AshleyIT.com code
*/

function remoteCall (url,args){
	var n = args[0];
	var head = document.getElementsByTagName('head').item(0);
	 
	var old  = document.getElementById(n.value);
	if (old) {
		head.removeChild(old);
	}
	
	script = document.createElement('script');
	
	script.type = 'text/javascript';
	script.defer = true;
	
	script.id = n.value; // Just call it somehow....
	var text="?";
	for(var i=0;i<args.length;++i){
		text=text + args[i].name + "=" + args[i].value + "&";
	}
	//alert(url+text);
	script.src = url+text;
 	void(head.appendChild(script));
	
}

// ===================================================================
// Author: Matt Kruse <matt@mattkruse.com>
// WWW: http://www.mattkruse.com/
// -------------------------------------------------------------------
// sortSelect(select_object)
//   Pass this function a SELECT object and the options will be sorted
//   by their text (display) values
// -------------------------------------------------------------------
function sortSelect(obj) {
	var o = new Array();
	if (obj.options==null) { return; }
	for (var i=0; i<obj.options.length; i++) {
		o[o.length] = new Option( obj.options[i].text, obj.options[i].value, obj.options[i].defaultSelected, obj.options[i].selected) ;
		}
	if (o.length==0) { return; }
	o = o.sort( 
		function(a,b) { 
			if ((a.text+"") < (b.text+"")) { return -1; }
			if ((a.text+"") > (b.text+"")) { return 1; }
			return 0;
			} 
		);

	for (var i=0; i<o.length; i++) {
		obj.options[i] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
		}
	}
	
function show_props(obj, objName) {
 
 var result = ''; 
 for (var i in obj)
 result += objName + "." + i + " = " + obj[i] + "<br>\n";       
 return result;
}


// -------------------------------------------------------------------
// Name        : cloneObject
// Taken from  : developer.irt.org/script/878.htm 
// Author      : unknwon
// Description : makes a clone of an object instead of a reference
// Usage       : clone = new cloneObject(master);
// -------------------------------------------------------------------

function cloneObject(what) {
    for (i in what) {
        if (typeof what[i] == 'object') {
            this[i] = new cloneObject(what[i]);
        }
        else
            this[i] = what[i];
    }
}
// -------------------------------------------------------------------
// Name        : serialize/_serialize
// Author      : Konrads Smelkovs
// Description : serializes an object
// Usage       : str=serialize(object);
// Limitations : you may not use ;:{} characters in your strings. Newlines might also not work
// -------------------------------------------------------------------

function serialize(obj){
	sObj= new Object;
	if(isArray(obj)){
		sObj.s="!Array";
	}else{
	sObj.s="!Object";
	}
	_serialize(obj,sObj);
	return sObj.s;
}
function _serialize(obj,sObj){
	sObj.s+="{ ";
	for (var i in obj){
		if((typeof obj[i]=="object")){
			index=i;
			if(typeof(i)=="string"){
				index=i;
			}
			sObj.s+=index + " => " + (isArray(obj[i]) ? "array" : typeof(obj[i])) + " : ";
			_serialize(obj[i],sObj);	
		}
		else{
			index=i;
			if(typeof(i)=="string"){
				index=i;
			}
			sObj.s+=index + " => "+typeof(obj[i])+" : "+obj[i] + ";";
		}
	}
	sObj.s+=" }";
}
function isArray(obj){
	//if(obj.length)
		if(obj.length>=0)
			return true;
	return false
}
// -------------------------------------------------------------------
// Name        : deserialize
// Author      : Konrads Smelkovs
// Description : deserializes an object after it has been serialized.
// Usage       : myobj=deserialize(str);
// Limitations : Understands only the following types: string,object,number
// -------------------------------------------------------------------
function deserialize(s,obj){
	var ml=false;
	re=/\!(\w+)\{/;
	rm=s.match(re);
	if(!obj && rm){
		switch (rm[1]){
			case "Array":
				obj=new Array;
				break;
		}
	}
	if(!obj){
				obj = new Object;
		}
	re = /([\"\w]+?)\s=>\s(\w+?)\s:\s(.+?);/;
	
		res=s.match(re);  // 1 and 2
		if(!res){
			return obj;
		}
		switch(res[2]){
			case "array" :
				obj[res[1]]=new Array;
			case "object":
				if(!obj[res[1]]){
					obj[res[1]]=new Object;
				}
				ml=matchlevel(s.slice(s.indexOf(":")+2))+s.indexOf(":")+2;
				var x=s.slice(s.indexOf(":")+2,ml);
				deserialize(x,obj[res[1]]);
				break;
			default:
				obj[res[1]]=res[3];
				if(res[2]=="number"){
					obj[res[1]]=parseInt(res[3]);
				break;
			}
		}

		var x;
		if(ml){
			x=s.slice(ml);
		}
		else{
			x=s.slice(s.indexOf(";")+1);
		}
	deserialize(x,obj);
	return obj;
}

function matchlevel(str){
	 var brackets=0;
	 var i=str.indexOf("{");
	do{
		if(str[i]=="{"){
			brackets++;
		}
		if(str[i]=="}"){
			brackets--;
		}
		i++;
	}
	while(i<str.length && brackets!=0);
	return i;
	
}
// -------------------------------------------------------------------
// Name        : getCookie/setCookie/deleteCookie
// Author      : Crispy(?)
// Description : Fetches and stores cookies
// Usage       : see below
// Taken from  : http://www.webreference.com/js/column8/
// -------------------------------------------------------------------

/*
   name - name of the cookie
   value - value of the cookie
   [expires] - expiration date of the cookie
     (defaults to end of current session)
   [path] - path for which the cookie is valid
     (defaults to path of calling document)
   [domain] - domain for which the cookie is valid
     (defaults to domain of calling document)
   [secure] - Boolean value indicating if the cookie transmission requires
     a secure transmission
   * an argument defaults when it is assigned null as a placeholder
   * a null placeholder is not required for trailing omitted arguments
*/

function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
      ((expires) ? "; expires=" + expires.toGMTString() : "") +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}

/*
  name - name of the desired cookie
  return string containing value of specified cookie or null
  if cookie does not exist
*/

function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else
    begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1)
    end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}


/*
   name - name of the cookie
   [path] - path of the cookie (must be same as path used to create cookie)
   [domain] - domain of the cookie (must be same as domain used to
     create cookie)
   path and domain default if assigned null or omitted if no explicit
     argument proceeds
*/

function deleteCookie(name, path, domain) {
  if (getCookie(name)) {
    document.cookie = name + "=" +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}
// -------------------------------------------------------------------
// Name        : sprintf aka Poor man's sprintf that does only %s
// Author      : Konrads Smelkovs <smelkovs@worldsoft.ch>
// Description : prints to a string;
// Usage       : see below
// -------------------------------------------------------------------
function sprintf(){
	if(arguments.length<2){
		return "sprintf usage: sprintf('string %s...',var1...)";
	}
	str=arguments[0];
	re = /%s/;
	for(var i=1;i<arguments.length;++i){
		str=str.replace(re,arguments[i]);
	}
	return str; 
	
}


// -------------------------------------------------------------------
// Name        : _sprintf
// Author      : Jan! (?)
// Description : prints to a string;
// Usage       : see below
// Taken from  : http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
// -------------------------------------------------------------------

function _sprintf()
		{
			if (!arguments || arguments.length < 1 || !RegExp)
			{
				return;
			}
			var str = arguments[0];
			var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
			var a = b = [], numSubstitutions = 0, numMatches = 0;
			while (a = re.exec(str))
			{
				var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
				var pPrecision = a[5], pType = a[6], rightPart = a[7];
				
				//alert(a + '\n' + [a[0], leftpart, pPad, pJustify, pMinLength, pPrecision);

				numMatches++;
				if (pType == '%')
				{
					subst = '%';
				}
				else
				{
					numSubstitutions++;
					if (numSubstitutions >= arguments.length)
					{
						alert('Error! Not enough function arguments (' + (arguments.length - 1) + ', excluding the string)\nfor the number of substitution parameters in string (' + numSubstitutions + ' so far).');
					}
					var param = arguments[numSubstitutions];
					var pad = '';
					       if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
					  else if (pPad) pad = pPad;
					var justifyRight = true;
					       if (pJustify && pJustify === "-") justifyRight = false;
					var minLength = -1;
					       if (pMinLength) minLength = parseInt(pMinLength);
					var precision = -1;
					       if (pPrecision && pType == 'f') precision = parseInt(pPrecision.substring(1));
					var subst = param;
					       if (pType == 'b') subst = parseInt(param).toString(2);
					  else if (pType == 'c') subst = String.fromCharCode(parseInt(param));
					  else if (pType == 'd') subst = parseInt(param) ? parseInt(param) : 0;
					  else if (pType == 'u') subst = Math.abs(param);
					  else if (pType == 'f') subst = (precision > -1) ? Math.round(parseFloat(param) * Math.pow(10, precision)) / Math.pow(10, precision): parseFloat(param);
					  else if (pType == 'o') subst = parseInt(param).toString(8);
					  else if (pType == 's') subst = param;
					  else if (pType == 'x') subst = ('' + parseInt(param).toString(16)).toLowerCase();
					  else if (pType == 'X') subst = ('' + parseInt(param).toString(16)).toUpperCase();
				}
				str = leftpart + subst + rightPart;
			}
			return str;
		}
function FormatNumber(Number,Decimals,Separator)
{
 // **********************************************************
 // Placed in the public domain by Affordable Production Tools
 // March 21, 1998
 // Web site: http://www.aptools.com/
 //
 // November 24, 1998 -- Error which allowed a null value
 // to remain null fixed. Now forces value to 0.
 //
 // October 28, 2001 -- Modified to provide leading 0 for fractional number
 // less than 1.
 //
 // This function accepts a number to format and number
 // specifying the number of decimal places to format to. May
 // optionally use a separator other than '.' if specified.
 //
 // If no decimals are specified, the function defaults to
 // two decimal places. If no number is passed, the function
 // defaults to 0. Decimal separator defaults to '.' .
 //
 // If the number passed is too large to format as a decimal
 // number (e.g.: 1.23e+25), or if the conversion process
 // results in such a number, the original number is returned
 // unchanged.
 // **********************************************************
 Number += ""          // Force argument to string.
 Decimals += ""        // Force argument to string.
 Separator += ""       // Force argument to string.
 if((Separator == "") || (Separator.length > 1))
  Separator = "."
 if(Number.length == 0)
  Number = "0"
 var OriginalNumber = Number  // Save for number too large.
 var Sign = 1
 var Pad = ""
 var Count = 0
 // If no number passed, force number to 0.
 if(parseFloat(Number)){
  Number = parseFloat(Number)} else {
  Number = 0}
 // If no decimals passed, default decimals to 2.
 if((parseInt(Decimals,10)) || (parseInt(Decimals,10) == 0)){
  Decimals = parseInt(Decimals,10)} else {
  Decimals = 2}
 if(Number < 0)
 {
  Sign = -1         // Remember sign of Number.
  Number *= Sign    // Force absolute value of Number.
 }
 if(Decimals < 0)
  Decimals *= -1    // Force absolute value of Decimals.
 // Next, convert number to rounded integer and force to string value.
 // (Number contains 1 extra digit used to force rounding)
 Number = "" + Math.floor(Number * Math.pow(10,Decimals + 1) + 5)
 if((Number.substring(1,2) == '.')||((Number + '')=='NaN'))
  return(OriginalNumber) // Number too large to format as specified.
 // If length of Number is less than number of decimals requested +1,
 // pad with zeros to requested length.
 if(Number.length < Decimals +1) // Construct pad string.
 {
  for(Count = Number.length; Count <= Decimals; Count++)
   Pad += "0"
 }
 Number = Pad + Number // Pad number as needed.
 if(Decimals == 0){
  // Drop extra digit -- Decimal portion is formatted.
  Number = Number.substring(0, Number.length -1)} else {
  // Or, format number with decimal point and drop extra decimal digit.
 Number = Number.substring(0,Number.length - Decimals -1) +
          Separator +
          Number.substring(Number.length - Decimals -1,
          Number.length -1)}
 if((Number == "") || (parseFloat(Number) < 1))
  Number="0"+Number // Force leading 0 for |Number| less than 1.
 if(Sign == -1)
  Number = "-" + Number  // Set sign of number.
 return(Number)
}

function in_array(what,where){
	for(var i in where){
		if(where[i]==what){
			return true;
		}
	}
	return false;
}

function value_index(value,where){
	for(var i in where){
		if(where[i]==value){
			return i;
		}
	}
	return -1;
}



// Copyright © 2003 by David Tam, Ph.D.  http://www.ComputationalNeuralSystems.com/
//   You may copy, modify and/or distribute it under the terms of the GNU General Public License.
//   See http://www.gnu.org/licenses/gpl.html for terms and conditions

// Javascript to compute elapsed time between "Start" and "Finish" button clicks
function timestamp_class(this_current_time, this_start_time, this_end_time, this_time_difference) { 
		this.this_current_time = this_current_time;
		this.this_start_time = this_start_time;
		this.this_end_time = this_end_time;
		this.this_time_difference = this_time_difference;
		this.GetCurrentTime = GetCurrentTime;
		this.StartTiming = StartTiming;
		this.EndTiming = EndTiming;
	}

//Get current time from date timestamp
function GetCurrentTime() {
    var my_current_timestamp;
    my_current_timestamp = new Date();		//stamp current date & time
    return my_current_timestamp.getTime();
    }

//Stamp current time as start time and reset display textbox
function StartTiming() {
    this.this_start_time = GetCurrentTime();	//stamp current time
    //document.TimeDisplayForm.TimeDisplayBox.value = 0;	//init textbox display to zero
    }

//Stamp current time as stop time, compute elapsed time difference and display in textbox
function EndTiming() {
    this.this_end_time = GetCurrentTime();		//stamp current time
    this.this_time_difference = (this.this_end_time - this.this_start_time) / 1000;	//compute elapsed time
    //document.TimeDisplayForm.TimeDisplayBox.value = this.this_time_difference;	//set elapsed time in display box
    }

var time_object = new timestamp_class(0, 0, 0, 0);	//create new time object and initialize it
