/// returns true if the email address is in the proper form.  
/// Doesn't check if it's actually a real account.
///
/// boolean Validate_Email_Address( email_address ) 

function Validate_String(string, return_invalid_chars)
{
    valid_chars = '1234567890-_.^~abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    invalid_chars = '';
    
    if(string == null || string == '')
    return(true);
    
    //For every character on the string.
    for(index = 0; index < string.length; index++)
    {
        _char = string.substr(index, 1);
        
        //Is it a valid character?
        if(valid_chars.indexOf(_char) == -1)
        {
            //If not, is it already on the list of invalid characters?
            if(invalid_chars.indexOf(_char) == -1)
            {
                //If it's not, add it.
                if(invalid_chars == '')
                	invalid_chars += _char;
                else
                	invalid_chars += ', ' + _char;
            }
        }
    }
    
    //If the string does not contain invalid characters, the function will return true.
    //If it does, it will either return false or a list of the invalid characters used
    //in the string, depending on the value of the second parameter.
    if(return_invalid_chars == true && invalid_chars != '')
    {
        last_comma = invalid_chars.lastIndexOf(',');
        
        if(last_comma != -1)
        invalid_chars = invalid_chars.substr(0, $last_comma) +
        ' and ' + invalid_chars.substr(last_comma + 1, invalid_chars.length);
        
        return(invalid_chars);
    }
    else
    	return(invalid_chars == '');
}


function Validate_Email_Address(email_address)
{
    //Assumes that valid email addresses consist of user_name@domain.tld
    at = email_address.indexOf('@');
    dot = email_address.indexOf('.');
    
    if(	at == -1 ||
    	dot == -1 ||
    	dot == 0 ||
    	dot == email_address.length - 1
    ) {
    	return(false);
    }
    
    ///you can have dots before the '@' ( e.g.: user.name@domain.tld )
    if( dot <= at + 1 )
    {
    	dot = email_address.lastIndexOf('.');
    	if( dot <= at + 1 ) return(false);
    }
    
    user_name = email_address.substr(0, at);
    domain_name = email_address.substr(at + 1, email_address.length);
    
    if(
    	Validate_String(user_name) === false ||
    	Validate_String(domain_name) === false
    )
    	return(false);
    
    return(true);
}



/// returns true if a given string consists of only digits and/or decimals.
///
/// @TODO <s>add ltrim/rtrim</s>, first-position negative-symbol checking, and a limit of a single decimal point.
function Is_Numeric( sText )
{
	var ValidChars = "0123456789.";
	var IsNumber=true;
	var Char;
	
	if( !sText || sText == '' ) return false;

	for (i = 0; i < sText.length && IsNumber == true; i++) 
	{ 
		Char = sText.charAt(i); 

		if (ValidChars.indexOf(Char) == -1) 
		{
			IsNumber = false;
		}
	}

	return IsNumber;
}

/// a really stupid wrapper!
function Array_Remove( myArray, killIndice )
{
	try {
		delete myArray[killIndice];
	} catch( e ) {}
}



///////////////////////////////////////////////////////////////////////////
/// Trim functions from http://www.apriori-it.co.uk/Trim.asp 
///////////////////////////////////////////////////////////////////////////
function Trim(TRIM_VALUE)
{
	if(TRIM_VALUE.length < 1)
	{
		return"";
	}
	
	TRIM_VALUE = RTrim(TRIM_VALUE);
	TRIM_VALUE = LTrim(TRIM_VALUE);
	
	if(TRIM_VALUE=="")
	{
		return "";
	}
	else
	{
		return TRIM_VALUE;
	}
} //End Function

function RTrim(VALUE)
{
	var w_space = String.fromCharCode(32);
	var v_length = VALUE.length;
	var strTemp = "";

	if(v_length < 0)
	{
		return"";
	}
	
	var iTemp = v_length -1;

	while(iTemp > -1)
	{
		if(VALUE.charAt(iTemp) == w_space)
		{
			//ignore
		}
		else
		{
			strTemp = VALUE.substring(0,iTemp +1);
			break;
		}
		
		iTemp = iTemp-1;
	} //End While
	
	return strTemp;
} //End Function

function LTrim(VALUE)
{
	var w_space = String.fromCharCode(32);
	
	if(v_length < 1)
	{
		return"";
	}
	
	var v_length = VALUE.length;
	var strTemp = "";

	var iTemp = 0;

	while(iTemp < v_length)
	{
		if(VALUE.charAt(iTemp) == w_space)
		{
			//ignore
		}
		else
		{
			strTemp = VALUE.substring(iTemp,v_length);
			break;
		}
		
		iTemp = iTemp + 1;
	} //End While
	
	return strTemp;
} //End Function
///////////////////////////////////////////////////////////////////////////



/// Based on code by:  Brian Swalwell (found via google)
///
/// Modified heavily by Ben McGraw on how it outputs so that it's actually useful (alerts, indeed.)
/// the original script also accepted "12-12" as a valid zip and had some processing redundancy.
/// 
/// takes a given input string to check for zip-formatting (either 5 or 5-4)
/// returns false if it's invalid, 5 if it's a shortform zip, or 10 if it's zip+4 (10 because it'd be 10 chars of zipstring.)
/// remember, non-zero integers eval to true, so it's like getting booleans with a chaser of extra knowledge.  Whee.
///
/// anyways, this doesn't validate that the zip actually exists, only that it's correctly formatted for 
function Validate_Zipcode( strZip ) {

	if( !strZip )
		return false;

	var field = Trim(strZip);
	
	var valid = "0123456789-";
	var hyphencount = 0;

	if( field.length!=5 && field.length!=10 ) 
	{
		return false;
	}

	for( var i=0; i < field.length; i++ ) 
	{
		temp = "" + field.substring(i, i+1);
		if( temp == "-" ) hyphencount++;
		
		if( valid.indexOf( temp ) == "-1" ) 
		{
			return false;
		}
	}

	if( (hyphencount > 1) || ((field.length==10) && ""+field.charAt(5)!="-") ) 
	{
		return false;
	}

	if( (field.length == 5) && (hyphencount > 0) )
	{	
		return false;
	}
	
	/// 5 if it's shortform, 10 if it's longform.
	return field.length;
}

/// Like Validate_Zipcode, but only for short-form (5 number) zipcodes.
///
function Validate_Zipcode_Short( strZip )
{
	return (Validate_Zipcode(strZip) == 5);
}




/**
 * Removes duplicates in the array 'a'
 * @author Johan Känngård, http://dev.kanngard.net
 * @author Ben McGraw (just changed name to conform to standards.)
 */
function Array_Unique(a) {
	tmp = new Array(0);
	for(i=0;i<a.length;i++){
		if(!Array_Contains(tmp, a[i])){
			tmp.length+=1;
			tmp[tmp.length-1]=a[i];
		}
	}
	
	return tmp;
}

/**
 * Returns true if 's' is contained in the array 'a'
 * @author Johan Känngård, http://dev.kanngard.net
 * @author Ben McGraw (just changed name to conform to standards.)
 */
function Array_Contains(a, e) {
	for(j=0;j<a.length;j++)if(a[j]==e)return true;
	return false;
}

function Array_Dump_String( myArray, myLbl )
{ 
	var txt = '';
	var lbl = ""+myLbl;

	if( myArray && myArray.length )
	{
		for( var i in myArray )
		{
			txt += lbl+"['"+i+"']	=> '"+myArray[i]+"'\n";		
		}
	}
	
	return txt;
}


/// Return everything before the final slash on the current page's url.
///
function Location_Split( ) 
{
	// convert window.location to a string before copying so we don't copy 
	// the object and cause accidental reloading.
	var myUrl = ""+window.location;
	
	if( myUrl )
	{
		arChunks = myUrl.split( '/' );
		
		myUrl = '';
		
		for( var i = 0; i<(arChunks.length-1); i++ )
		{
			myUrl += arChunks[i] + "/";
		}
		
		return myUrl;
	}
	
	return "";
}

/// returns the value of an xml subnode in a given node.  If there are multiple
/// children with that name, returns only the first one.  If the name is
/// invalid, or if the xmlNode is invalid, returns an empty string after 
/// complaining.
///
/// Just a convenience function, really.
///
/// @author Ben McGraw
function fetch_XML_value( myCurNode, tehName )
{
	var myval = "";
	try {
		myval = myCurNode.getElementsByTagName(tehName)[0].childNodes[0].nodeValue;
	}
	catch( e )
	{
		//Log( "fetch_XML_value('"+myCurNode+"','"+tehName+"'): " + e );
		return "";
	}

	return myval;
}

/// crossbrowser select-node fetchy!
///
/// @author Ben McGraw
function getSelectValue( selectNode )
{
	return selectNode.options[selectNode.selectedIndex].value
}



function Validate_Phone( phoneNumberTxt )
{
	/// return true if there are at least 10 digits in the string, otherwise false.
}

function Validate_Credit_Card_Number( ccNumberTxt )
{
	/// return true if there are at least 15 digits in the string and no [A-Z,a-z], otherwise false.
}

function print_r( mysteryObj )
{
	for( var i in mysteryObj )
	{
		alert( "in me: '"+i+"'");
	}
}

var __GRS_override = 1;


/// following three functions based on code from http://psacake.com/web/ei.asp
///
/// @TODO add a global array that makes sure the random strings are unique per page.  Strictly speaking, 
/// that might be silly overkill since the odds against are astronomical.
///
function GenerateRandomString() {
    
    if (parseInt(navigator.appVersion) <= 3) { 
        __GRS_override++;
        return "old"+__GRS_override; 
    }
    
    var length=8;
    var sPassword = "";
    
    var noPunction = true;
    
	length = Math.random(); 

	length = parseInt(length * 100);
	length = (length % 7) + 6
    
    
    for (i=0; i < length; i++) {
    
        numI = getRandomNum();
        if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } }
        
        sPassword = sPassword + String.fromCharCode(numI);
    }
    
    return sPassword;
}

function getRandomNum() {
        
    // between 0 - 1
    var rndNum = Math.random()

    // rndNum from 0 - 1000    
    rndNum = parseInt(rndNum * 1000);

    // rndNum from 33 - 127        
    rndNum = (rndNum % 94) + 33;
            
    return rndNum;
}

function checkPunc(num) {
    
    if ((num >=33) && (num <=47)) { return true; }
    if ((num >=58) && (num <=64)) { return true; }    
    if ((num >=91) && (num <=96)) { return true; }
    if ((num >=123) && (num <=126)) { return true; }
    
    return false;
}

