var monthnames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
	daynames = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];
	
function Ajax( command, subcommand, data, success, failure, sync, datatype )
{
	if ( data == null )
		data = { };
		
	data.command = command;
	data.subcommand = subcommand;
	data.securitytoken = $("#securitytoken").val();
	data.lochref = location.href;

	var callbackurl = unescape( $("#callbackurl").val() );

	if ( !$.isFunction( success ) )
		success = function() { };

	if ( !$.isFunction( failure ) )
		failure =	
			function( XMLHttpRequest, textStatus, errorThrown )
			{
				//alert( "Server failure (" + textStatus + "), please try again!" );
			};

	$.ajax( 
		{
			type: "POST",
			url: callbackurl,
			dataType: (typeof( datatype ) == "undefined" ? "xml" : datatype),
			async: (typeof( sync ) == "undefined" ? true : !sync),
			data: data, 
			success: success,
			error: failure
		} );	
}

function AjaxGetRows( xml )
{
	var rows = [],
		fieldnames = [],
		fieldtypes = [],
		fields = $(xml).find( "fields item" );

	fields.each( 
		function()
		{
			var	name = $(this).attr( "name" ),
				type = $(this).attr( "type" );
				
			fieldnames.push( name );
			switch ( type )
			{
				case "Int32": case "Int16": case "Int64": case "Int8":
					fieldtypes.push( "Int" );
					break;
					
				default:
					fieldtypes.push( type );
					break;
			}
		}
	);
	
	$(xml).find( "r" ).each(
		function()
		{
			var o = { },
				row = $(this);
				
			for ( var i = 0 ; i < fieldnames.length ; i++ )
			{
				var fieldname = fieldnames[ i ],
					val = $(this).find( fieldname ).text()
					
				switch ( fieldtypes[ i ] )
				{
					default: // eg "String"
						o[ fieldname ] = val;
						break;
						
					case "DateTime":
						val = $.trim( val );
						o[ fieldname ] = (val == null || val == "" ? null : new Date( val ));
						break;
						
					case "Int":
						o[ fieldname ] = parseInt( val );
						break;
						
					case "Boolean":
						o[ fieldname ] = (val == "True");
						break;
				}
			}
			
			rows.push( o );
		}
	);
	
	return rows;
}

function JoinData( object1, object2 ) // modifies object1
{
	for ( var key in object2 ) 
		object1[ key ] = object2[ key ];
	
	return object1;
}

function SaveKey( object, key, val )
{
	if ( val != null && val != "" )
		object[ key ] = val;
}

function TextAreaResize( textarea )
{
	var val = textarea.val();
		
	var rows = 1;
	var b = val.match( /\n/g );
	if ( b != null && b.length > 1 )
		rows = b.length + 1;
		
	if ( rows < (val.length / 65) + 1 )
		rows = (val.length / 65) + 1;

	textarea.attr( "rows", rows );
}

function IsNull( a, b )
{
	return (a == null ? b : a);
}

function DateControl( name, val, withnulls )
{
	function StringWriter()
	{
		var s = "";
		this.Write = function( n ) { s += n; }
		this.toString = function() { return s; }
	}

	if ( typeof( withnulls ) != "boolean" )
		withnulls = false;

	var d = new Date( val );
	var day = d.getDate();
	var month = d.getMonth();
	var year = d.getFullYear();
	
	var s = new StringWriter();
	
	s.Write( "<select id=day" + name + " name=day" + name + ">" 
			+ (withnulls ? "<option></option>" : "" ) );
	for ( var i = 1 ; i <= 31 ; i++ )
		s.Write( "<option " + (val != null && day == i ? "selected ":"") 
							+ "value=" + i + ">" + i + "</option>" );
	s.Write( "</select>" );
	
	var m = monthnames;
	s.Write( "<select id=month" + name + " name=month" + name + ">"
			+ (withnulls ? "<option></option>"  : "") );
	for ( var i = 0 ; i < 12 ; i++ )
		s.Write( "<option " + (val != null && month == i ? "selected ":"")
							+ "value=" + i + ">" + m[ i ] + "</option>" );
	s.Write( "</select>" );
	
	s.Write( "<select name=year" + name + " id=year" + name + ">"
		+ (withnulls ? "<option></option>" : "") );
	for ( var y = 1999 ; y < 2020 ; y++ )
		s.Write( "<option value=" + y
			+ (year == y ? " selected" : "")
			+ ">" + y + "</option>" );
	s.Write( "</select>" );
	
	return s.toString();
}

function DateControlRead( id )
{
	var eday = $("#day" + id).val(),
		emonth = $("#month" + id).val(),
		eyear = $("#year" + id).val();
	
	if ( eday == "" && emonth == "" && eyear == "" )
		return null;
		
	emonth = parseInt( emonth );
	
	if ( eday == "" )
		eday = 1;
	if ( isNaN( emonth ) )
		emonth = 0;
	if ( eyear == "" )
		eyear = (new Date()).getFullYear();
		
	return (emonth + 1) + "/" + eday + "/" + eyear;
}

function TimeControl( name, val )
{
	var d = new Date( val );
	
	d.setSeconds( d.getSeconds() + 29 );
	
	var h = d.getHours(),
		m = d.getMinutes();
		
	var ampm = "am";
	
	if ( h >= 12 ) ampm = "pm";
	if ( h > 12 ) h-= 12;

	var s = "<select id=\"" + name + "h\" name=\"" + name + "h\">";
	for ( var i = 0 ; i <= 12 ; i++ )
		s += "<option" + (h == i ? " selected=\"selected\"" : "") + ">" + i + "</option>";
	s+= "</select>" +
		"<select id=\"" + name + "m\" name=\"" + name + "m\">";
	for ( var i = 0 ; i < 10 ; i += 5 )
		s += "<option" + (m == i ? " selected=\"selected\"" : "") + ">0" + i + "</option>";
	for ( var i = 10 ; i < 59 ; i += 5 )
		s += "<option" + (m == i ? " selected=\"selected\"" : "") + ">" + i + "</option>";
	s += "</select>" +
		"<select id=\"" + name + "a\" name=\"" + name + "a\">" +
			"<option value=\"0\"" + (ampm == "am" ? " selected=\"selected\"" : "") + ">am</option>" +
			"<option value=\"1\"" + (ampm == "pm" ? " selected=\"selected\"" : "") + ">pm</option>" +
		"</select>";
		
	return s;
}

function TimeControlRead( name )
{
	var h = parseInt( $("#" + name + "h").val() ),
		m = parseInt( $("#" + name + "m").val() ),
		a = parseInt( $("#" + name + "a").val() ),
		d = new Date();
		
	if ( h == 12 ) 
	    h = 0;
		
	d.setHours( a > 0 ? h + 12 : h );
	d.setMinutes( m );
		
	return d;
}

function ValidEmail( email )
{
    if ( email == null || $.trim( email ) == "" )
        return false;

	email = email.toLowerCase();

    var at = email.indexOf( "@" );

    // must contain @ sign internally, and only one of them 
    if ( at <= 0 || at >= (email.length - 1) || email.indexOf( "@", at + 1 ) > - 1 )
		return false;

	var domain = email.substr( at + 1 );

    // @ must be followed at some point by a period, but not right away
    if ( domain.substr( 1 ).indexOf( "." ) < 0 )
        return false;

	var invalidChars = "\/\"'\\ ;:?!()[]\{\}^|";
	
	for ( var i = 0; i < invalidChars.length ; i++) 
		if ( email.indexOf( invalidChars.charAt( i ), 0 ) > -1)
			return false;
			
	for ( var i = 0; i < email.length ; i++ ) 
		if ( email.charCodeAt( i ) > 127 )
			return false;

	if ( email.indexOf( "@." ) > -1 || email.indexOf( ".@" ) > -1 || email.indexOf( ".." ) > -1 ) 
		return false;

	var suffix = email.substring( email.lastIndexOf( "." ) + 1 ),
		found = false;
		
	if ( suffix.length > 2 )
	{
		var allowed = [ "com", "net", "org", "edu", "int", "mil", "gov", "arpa", "biz", "aero", "name", "coop", "info", "pro", "museum" ]; 
		
		for ( var i = 0 ; i < allowed.length ; i++ )
			found |= (suffix == allowed[ i ]);
			
		if ( !found )
			return false;
	}

    return true;
}
