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 ValidEmail( email )
{
    if ( email == null || $.trim( email ) == "" )
        return false;

	email = email.toLowerCase();

    var at = email.indexOf( "@" ),
		i;

    // 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 ( i = 0; i < invalidChars.length ; i++) 
		if ( email.indexOf( invalidChars.charAt( i ), 0 ) > -1)
			return false;
			
	for ( 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 ( i = 0 ; i < allowed.length ; i++ )
			found |= (suffix == allowed[ i ]);
			
		if ( !found )
			return false;
	}

    return true;
}

function delay( f )
{
    setTimeout( f, 0 );
}

function alertDialog( message, after )
{
	$( "#alert" ).remove();
	$( "body" ).append( "<div id=\"alert\">" + message + "</div>" );
	$( "#alert" ).dialog(
		{
			buttons:
			{
				"Ok": function() { $(this).dialog( "close" ); }
			},
			modal: true,
			title: "Alert!",
			width: "auto",
			close: function() { $(this).remove(); if ( after != undefined ) after(); }
		}
	);
}

function confirmDialog( message, success, failure )
{
	$( "#alert" ).remove();
	$( "body" ).append( "<div id=\"alert\">" + message + "</div>" );
	$( "#alert" ).dialog(
		{
			buttons:
			{
				"Yes": function() { $(this).dialog( "close" ); if ( success != undefined ) success(); },
				"No": function() { $(this).dialog( "close" ); if ( failure != undefined ) failure(); }
			},
			modal: true,
			width: "auto",
			title: "Please Confirm!",
			close: function() { $(this).remove(); }
		}
	);
}

