//
// AJAX.JS
//

///////////////////////////////////////////////////////////////////////////
////////////////////////////////// NOTE ///////////////////////////////////

/* All new requests should have connection and server timeout checks in the onreadystate or before the call to the request. The two case and a template are given below

ONREADYSTATE CASE: here is a template
		//The only variable here is fActionToTake
		//fActionToTake should have the request function with the parameters
		//for example it could be fActionToTake=function(){request_move_documents(sDest,sList);}
		//note that fActionToTake is in three places in the code below
		if(xhrConn.status==200){
			var sResponseText=xhrConn.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				request_reauthenticate(gsAuthKey, gsUserId, fActionToTake); //one retry
			}else{ 
				fActionToTake();
			}
	    }else if(xhrConn.status==0){ //user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect(fActionToTake),1000);}); //one retry after 1 second
		}else if(xhrConn.status==500){ //server error
			server_error_alert();
		}
		
		
		//On the SERVER side the following block should be included
		session_start();
		$sUserID = $_SESSION['userid'];
		if ($sUserID == '') {
		// no userid in cookie
		// no login
		// do not operate!
		echo('failure:no session');
		exit();
		} else if(!session_is_active($sUserID, session_id())){
		echo('failure:no session');
		exit();
		}



BEFORE CALL TO REQUEST CASE: here is template
Inside the calling function, replace request_* with request_check_server_and_conn(function(){request_*})
OR (in the case of checking connection only) request_check_conn(function(){request_*})

Example: wherever request_send_password(sEmail) is called, it was replaced with
request_check_server_and_conn(function(){request_send_password(sEmail)})

No server side action is needed here
*/
//////////////////////////////////// END NOTE /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

var uploader;

// Method #1
// the following method is supposed to work trasparently by providing an XMLHttpRequest function
// by running only if the browser is IE, and then only if this version of IE 
// does not natively support one (so no browser detect & conditionals are required at all)
// so we can just call "foo = new XMLHttpRequest();" directly

/*@cc_on @if (@_win32 && @_jscript_version >= 5) if (!window.XMLHttpRequest)
window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP') }
@end @*/


// Method #2 - CURRENTLY IN USE
// the following is a single function to use instead of calling "foo = new XMLHttpRequest();" directly
// and should return the right object depending on browser's abilities
// but it does not test those abilities, just assumes based on browser version
function get_new_xmlhttp_object() {
    var new_xhr;

  if (is.ie6) {
    new_xhr = new ActiveXObject("MSXML2.XMLHTTP.3.0");
  } else {
    new_xhr = new XMLHttpRequest();
  }

  return (new_xhr);
}

// Method #3
// the following is a single function to use instead of calling "foo = new XMLHttpRequest();" directly
// but it does test for what the browser provides, then uses it
function get_xml_http_object() {
    // I got this one from Microsoft MSDN
  var xmlHttp = null;
  if (window.XMLHttpRequest) {
      // If IE7, Mozilla, Safari, and so on: Use native object.
      xmlHttp = new XMLHttpRequest();
  } else {
	  if (window.ActiveXObject) {
	      // ...otherwise, use the ActiveX control for IE5.x and IE6.
	      xmlHttp = new ActiveXObject('MSXML2.XMLHTTP.3.0');
	  }
  }

  return (xmlHttp);
}


function xml_is_ok(oXML) {
  var sXMLIsOK;
  
  sXMLIsOK = 0;
  
  // removed check for positive number of child nodes
  // reponse functions are prepared for empty recordsets
  // was: if ((oXML != null) && (typeof oXML != 'string') && (oXML.documentElement != null) && (oXML.documentElement.childNodes.length > 0)) {
  if ((oXML != null) && (typeof oXML != 'string') && (oXML.documentElement != null)) {
    sXMLIsOK = 1;
  }
  // alert('in xml_is_ok: ' + sXMLIsOK);  
  
  return sXMLIsOK;
}


function request_move_documents(sDest,sList) {
    // move the given list of docs into the given folder
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/move_documents.php';
    // post join info (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'dest='+ escape_plus(sDest) +'&list='+ escape_plus(sList) +'&gid='+ gsGroupId +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    // debug_message("in request_join_group sURL: " + sURL);
    // debug_message("in request_join_group sRequestBody: " + sRequestBody);
    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    xhrJoin.onreadystatechange = function() {
	if (xhrJoin.readyState == 4) {
	    if(xhrJoin.status==200){
			var sResponseText=xhrJoin.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_move_documents');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_move_documents(sDest,sList);}); //one retry	
			}else{ 
				// debug_message("in request_join_group xhrJoin.responseText: " + xhrJoin.responseText);
			    move_documents_response(xhrJoin.responseText);
			    // with the user's id and that groupid comes back in the session response
			}
	    }else if(xhrJoin.status==0){ //user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
	    	setTimeout(function(){request_reconnect(function(){request_move_documents(sDest,sList);});},1000); //one retry after 1 second	
		}else if(xhrJoin.status==500){ //server error
			server_error_alert();
		}
		
	}
    };
    xhrJoin.send(sRequestBody);
} // end function request_move_documents

function request_create_folder(sFolderName, sLevel) {
    // for new folder requests
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/create_folder.php';
    // post join info (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'name='+ escape_plus(sFolderName) +'&level='+ escape_plus(sLevel) +'&groupid='+ escape_plus(gsGroupId) +'&first='+ escape_plus(gsFirst) +'&last='+ escape_plus(gsLast) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    marquee_show_timed('Creating new folder...', 10000);
    xhrJoin.onreadystatechange = function() {
	if (xhrJoin.readyState == 4) {
	   if(xhrJoin.status==200){
			var sResponseText=xhrJoin.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_create_folder');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_create_folder(sFolderName, sLevel);}); // one retry
			}else{  
				
			    create_folder_response(xhrJoin.responseText, sLevel);

		    }
	    }else if(xhrJoin.status==0){ //user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect(function(){request_create_folder(sFolderName, sLevel);});},1000); //one retry after 1 second	
		}else if(xhrJoin.status==500){ //server error
			server_error_alert();
		}
	}
    };
    xhrJoin.send(sRequestBody);
} // end function request_create_folder

function request_rename_folder(sFolderName, sId, sContainerId) {
    // for rename folder requests
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/rename_folder.php';
    // post join info (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'name='+ escape_plus(sFolderName) +'&docid='+ escape_plus(sId) +'&first='+ escape_plus(gsFirst) +'&last='+ escape_plus(gsLast) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    xhrJoin.onreadystatechange = function() {
		if (xhrJoin.readyState == 4) {
		    if(xhrJoin.status==200){
			var sResponseText=xhrJoin.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_rename_folder');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_rename_folder(sFolderName, sId, sContainerId);}); // one retry	
				}else{ 
					rename_folder_response(xhrJoin.responseText, sContainerId);
				}
		    }else if(xhrJoin.status==0){ //user has no connection
		    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
				setTimeout(function(){request_reconnect(function(){request_rename_folder(sFolderName, sId, sContainerId);});},1000); //one retry after 1 second	
			}else if(xhrJoin.status==500){ //server error
				server_error_alert();
			}
		}
    };
    xhrJoin.send(sRequestBody);
} 

function request_session_cache() {
    // get the session cache for the logged-in user
    // call this every 5 minutes or so
    
    // call the php page to get the session cache for this userid
    
    var xhrCache;
    var sURL;
    
    xhrCache = get_new_xmlhttp_object();
    
    sURL = '/get_session_cache.php';
    sRequestBody = 'packnumber=' + gsPackNumber + '&ago=' + get_seconds_ago();
    
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';
    
    // alert('in request_session_cache \n sURL: ' + sURL +' sRequestBody='+ sRequestBody);
    xhrCache.open("POST", sURL, true);
    xhrCache.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrCache.setRequestHeader("Content-Length", sRequestBody.length);
    xhrCache.onreadystatechange = function() {
	if (xhrCache.readyState == 4) {
	    // later create a js function to unpack the data THEN pop the new records on the screen for the current view
	    if (xhrCache.status == 200) {
	    	if (xhrCache.responseText == 'failure:no session'){ // session has timed out
		    marquee_show_timed('Lost session. Reconnecting...', 15000);
		    report_phpsessid('request_session_cache');
		    request_reauthenticate(gsAuthKey, gsUserId, function(){request_session_cache();}); // one retry
	    	} else {
		    unpack_session_cache_data(xhrCache.responseText, gsGroupId);  // process the session cache data
		    gbConnLossRetry = false;	
		}
	    } else if (xhrCache.status == 0) { // user has no connection 
		setTimeout(function(){marquee_show_timed('Connection lost. Attempting to reconnect...', 15000);},10000);
		//setTimeout(function(){request_reconnect(function(){request_session_cache();});},1000); // one retry after 1 second
		setTimeout(function(){request_reconnect(function(){request_session_cache();});},15000); // one retry after 15 seconds
	    } else if (xhrCache.status == 500) { // server error
		// was (this is overkill for every checkin, when the next one may reconnect): server_error_alert(); 
		marquee_show_timed('Lost contact with server. Attempting to reconnect...', 60000);
	    }
	}
    };
    xhrCache.send(sRequestBody);
}

function request_send_password(sEmail) {
    var xhr;
    var sURL;
    
    xhr = get_new_xmlhttp_object();
    
    sURL = "/send_password.xml";
    sRequestBody = "email=" + escape_plus(sEmail);
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sRequestBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    send_password_response(xhr.responseText);
	    request_queue_pickup('wiggio.com', '');
	}
    };
    xhr.send(sRequestBody);
}

function request_new_user_password_save(sPassword, sFirst, sLast) {
    var xhr;
    var sURL;
    var sResult;
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click

    xhr = get_new_xmlhttp_object();
    
    sURL = "/password_save.php";
    sRequestBody = 'password=' + escape_plus(sPassword) + '&first=' + escape_plus(sFirst) + '&last=' + escape_plus(sLast) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sRequestBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
		if(xhr.status==200){
			var sResponseText=xhr.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
	    		marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
			report_phpsessid('request_new_user_password_save');
	    		request_reauthenticate(gsAuthKey, gsUserId, function(){request_new_user_password_save(sPassword, sFirst, sLast);}); // one retry
			}else{ 
			    sResult = unpack_session_cache_data(xhr.responseText, 'users', 'edit', gsUserId);
			    new_user_password_save_response(sResult);
		    }
      	}else if(xhr.status==0){ //user has no connection
  			marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect( function(){request_new_user_password_save(sPassword, sFirst, sLast);});},1000); //one retry after 1 second	
		}else if(xhr.status==500){ //server error
			server_error_alert();
			gsSavingPassword=0;
		}
		
	}
    };
    xhr.send(sRequestBody);
}

function send_test_message(sType) {
    // send a test message to the logged-in user's email or text device
  var xhrSend;
  var sURL;
   
  xhrSend = get_new_xmlhttp_object();

  sURL = "/send_test_message.xml";
  sRequestBody = "type=" + sType;
  // alert("in logout\nsURL: " + sURL);
  xhrSend.open("POST", sURL, true);
  xhrSend.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhrSend.setRequestHeader("Content-Length", sRequestBody.length);
  xhrSend.onreadystatechange = function() {
    if (xhrSend.readyState == 4) {
	show_message_sent(sType);  // tell the user "we have just sent a message to..."
    }
  };
  xhrSend.send(sRequestBody);
}

function request_log_out() {
    // called only from log_out() in login.js
    
    //xhrOut = new XMLHttpRequest();
    xhrOut = get_new_xmlhttp_object();
    
    sURL = "/logout.xml";
    // alert("in logout\nsURL: " + sURL);
    xhrOut.open("GET", sURL, true);
    xhrOut.onreadystatechange = function() {
	if (xhrOut.readyState == 4) {
	    log_out_response();
	}
    };
    xhrOut.send("");
}
function request_authentication(sUsername, sPassword, sRemember, sInviteId, sInviteConfCode, sInviteGroupName, sInviteGroupPassword) {
    // for login requests
    // SELECT requests that require no static template
    
    var xhrAuth;
    var sURL, sRequestBody;
    /*
    if (0 && sBrowserIsIE) {
	xhrAuth = new ActiveXObject("MSXML2.XMLHTTP.3.0");
    } else {
	xhrAuth = new XMLHttpRequest();
    }
    */
        
    xhrAuth = get_new_xmlhttp_object();
    
    sURL = "/login.php";
    // post login info (rather than get) so the transition to https for auth will be easy
    sRequestBody = "username=" + escape_plus(sUsername) + "&password=" + escape_plus(sPassword) + "&remember=" + escape_plus(sRemember) + "&invite_group_name=" + escape_plus(sInviteGroupName) + "&invite_group_password=" + escape_plus(sInviteGroupPassword) + "&invite_id=" + escape_plus(sInviteId) + "&invite_conf_code=" + escape_plus(sInviteConfCode) + "&fbid=" + escape_plus(gsFbId);
    
    debug_message('gsFbid in request_authentication(): ' + gsFbId);
    

    //alert("in request_authentication\nsURL: " + sURL);
    debug_message("in request_authentication\nsRequestBody: " + sRequestBody);
    xhrAuth.open("POST", sURL, true);
    xhrAuth.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    // xhrAuth.setRequestHeader("Content-Length", sRequestBody.length);
    
       
    xhrAuth.onreadystatechange = function() {
	if (xhrAuth.readyState == 4) {
	    // perhaps a successful authentication will set the cookie
	    // debug_message('In authentication_response: xhrAuth.responseText= |'+ xhrAuth.responseText +'|');
	    // if (is.ie7) {
	    // authentication_response(xhrAuth.responseBody);
	    // } else {
	        var oDate = new Date();
		gsEndServerLogin = oDate.getTime();
		authentication_response(xhrAuth.responseText);
	    // }
		if ((sInviteId != '') || (sInviteGroupName != '')) { // assume that an invite email was queued
		request_queue_pickup('wiggiomail.com', 'mail');
	    }
	}
    };
    var oDate = new Date();
    gsStartServerLogin = oDate.getTime();
    xhrAuth.send(sRequestBody);
}

function request_reauthenticate(sAuthKey, sUserId, fActionToTake) {

    var xhrAuth;
    var sURL, sRequestBody;
    
    if (0 && sBrowserIsIE) {
	xhrAuth = new ActiveXObject("MSXML2.XMLHTTP.3.0");
    } else {
	xhrAuth = new XMLHttpRequest();
    }
    xhrAuth = get_new_xmlhttp_object();
    
    sURL = "/reauthenticate.php";
    // post info (rather than get) so the transition to https for auth will be easy
    sRequestBody = "authKey=" + escape_plus(sAuthKey) + "&userId=" + escape_plus(sUserId);
    xhrAuth.open("POST", sURL, true);
    xhrAuth.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    // xhrAuth.setRequestHeader("Content-Length", sRequestBody.length);
    xhrAuth.onreadystatechange = function() {
	if (xhrAuth.readyState == 4) {
	    if (xhrAuth.status == 200) {
		reauthenticate_response(xhrAuth.responseText, fActionToTake);
		// MOVED into reauthenticate_response; dtd 20100405 take the original action ONLY if the reauthentication was successful (otherwise an infinite reauth loop is enabled): fActionToTake();
	    } else if (xhrAuth.status == 0) { // user has no connection
		marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
		// setTimeout(function(){request_reconnect(fActionToTake)}, 1000); // one retry after 1 second
		setTimeout(function(){request_reconnect(fActionToTake)}, 15000); // one retry after 15 seconds
	    } else if (xhrAuth.status == 500) { // server error
		server_error_alert();
	    }
	}
    };
    xhrAuth.send(sRequestBody);

}

function request_make_admin(sGroupId, sUserId, sAction) {
  // for elevating a user to admin priviledge
  
  var xhrJoin;
  var sURL, sRequestBody;
  
  xhrJoin = get_new_xmlhttp_object();

  var ago = get_seconds_ago();  // get the time since the users last mouse or key click

  sURL = '/make_admin.php';
  // post join info (rather than get) so the transistion to https for auth will be easy
  sRequestBody = 'groupid='+ escape_plus(sGroupId) +'&newadminid='+ escape_plus(sUserId) +'&action='+ escape_plus(sAction) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
  // add the max record id blocks to the request and forget them
  sRequestBody += '&maxblocks=' + gsMaxBlocks;
  gsMaxBlocks = '';

  xhrJoin.open('POST', sURL, true);
  xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
  xhrJoin.onreadystatechange = function() {
    if (xhrJoin.readyState == 4) {
		if(xhrJoin.status==200){
			var sResponseText=xhrJoin.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_make_admin');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_make_admin(sGroupId, sUserId, sAction);}); // one retry
			}else{ 
			    unpack_session_cache_data(xhrJoin.responseText, 'user_group', 'add', '');
			    make_admin_response(xhrJoin.responseText, sUserId, sAction); 
				
			// pass the userid to the response function so we can pop the change if it succeeded
			}
    	}else if(xhrJoin.status==0){ //user has no connection
    		marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect( function(){request_make_admin(sGroupId, sUserId, sAction);});},1000); //one retry after 1 second	
		}else if(xhrJoin.status==500){ //server error
			server_error_alert();
		}
    }
  };
  xhrJoin.send(sRequestBody);
} // end function request_make_admin

function request_unjoin_group(sGroupId, sUserId, sAction) {
  // for group UNjoin requests
  
  var xhrJoin;
  var sURL, sRequestBody;
  
  xhrJoin = get_new_xmlhttp_object();

  var ago = get_seconds_ago();  // get the time since the users last mouse or key click

  //alert('about to do server request for group_unjoin.php ...');

  sURL = '/group_unjoin.php';
  // post join info (rather than get) so the transistion to https for auth will be easy
  sRequestBody = 'groupid='+ escape_plus(sGroupId) +'&unjoinuserid='+ escape_plus(sUserId) +'&action='+ escape_plus(sAction) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
  // add the max record id blocks to the request and forget them
  sRequestBody += '&maxblocks=' + gsMaxBlocks;
  gsMaxBlocks = '';
  // alert("in request_authentication\nsURL: " + sURL);
  // alert("in request_authentication\nsRequestBody: " + sRequestBody);
  xhrJoin.open('POST', sURL, true);
  xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
  xhrJoin.onreadystatechange = function() {
    if (xhrJoin.readyState == 4) {
    	if(xhrJoin.status==200){
			var sResponseText=xhrJoin.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_unjoin_group');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_unjoin_group(sGroupId, sUserId, sAction);}); // one retry
			}else{ 
				if (sAction == 'unjoin') {
				    unjoin_group_response(xhrJoin.responseText, sGroupId);
				    // pass in the groupId so we know which group to remove from gaTable
				} else { // sAction == 'remove_member'
				    remove_member_response(xhrJoin.responseText, sUserId);
				}
			}
	    }else if(xhrJoin.status==0){ //user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect( function(){request_unjoin_group(sGroupId, sUserId, sAction);});},1000); //one retry after 1 second	
		}else if(xhrJoin.status==500){ //server error
			server_error_alert();
		}
		
    }
  };
  xhrJoin.send(sRequestBody);
} // end function request_unjoin_group

gsSessIdReported = 0;
function report_phpsessid(sFunctionName) {
    js_report_warning('ajax.js', sFunctionName, 'request failure due to lost session; session cookie: ' + readCookie('PHPSESSID'));
    gsSessIdReported = 1;
}

function request_join_group(sGroupname, sPassword, sFirst, sLast, sEmail, sNotifSubj, sNotifBody) {
    // for group join requests
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/group_join.php';
    // post join info (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'groupname='+ escape_plus(sGroupname) +'&password='+ escape_plus(sPassword) +'&first='+ escape_plus(sFirst) +'&last='+ escape_plus(sLast) +'&email='+ escape_plus(sEmail) +'&notifsubj='+ escape_plus(sNotifSubj) +'&notifbody='+ escape_plus(sNotifBody) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    // debug_message("in request_join_group sURL: " + sURL);
    // debug_message("in request_join_group sRequestBody: " + sRequestBody);
    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    xhrJoin.onreadystatechange = function() {
	if (xhrJoin.readyState == 4) {
	    if (xhrJoin.status == 200) {
		var sResponseText = xhrJoin.responseText;
		if ((sResponseText == 'failure:no session') || (sResponseText == '\nfailure:no session')) {
		    marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
		    report_phpsessid('request_group_join');
		    request_reauthenticate(gsAuthKey, gsUserId, function(){request_join_group(sGroupname, sPassword, sFirst, sLast, sEmail, sNotifSubj, sNotifBody);}); // one retry
		} else {
		    // debug_message("in request_join_group xhrJoin.responseText: " + xhrJoin.responseText);
		    join_group_response(xhrJoin.responseText, sGroupname);
		    // pass in the groupId so we can recognize if a user_group
		    // with the user's id and that groupid comes back in the session response
		    request_queue_pickup('wiggiomail.com', 'both');
		}
	    } else if (xhrJoin.status == 0) { // user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
		setTimeout(function(){request_reconnect( function(){request_join_group(sGroupname, sPassword, sFirst, sLast, sEmail, sNotifSubj, sNotifBody);});},1000); // one retry after 1 second
	    } else if (xhrJoin.status == 500) { // server error
		server_error_alert();
	    }
	}
    };
    xhrJoin.send(sRequestBody);
} // end function request_join_group

function request_group_invite(sInviteId, sAction, sFirst, sLast, sNotifSubj, sNotifBody) {
    // for group join requests
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/group_join.php';
    // post join info (rather than get) so the transition to https for auth will be easy
    sRequestBody = 'inviteid='+ escape_plus(sInviteId) +'&action='+ escape_plus(sAction) +'&first='+ escape_plus(sFirst) +'&last='+ escape_plus(sLast) +'&notifsubj='+ escape_plus(sNotifSubj) +'&notifbody='+ escape_plus(sNotifBody) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    // debug_message("in request_join_group sURL: " + sURL);
    // debug_message("in request_join_group sRequestBody: " + sRequestBody);
    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    xhrJoin.onreadystatechange = function() {
	if (xhrJoin.readyState == 4) {
	    if (xhrJoin.status == 200) {
		var sResponseText = xhrJoin.responseText;
		if ((sResponseText == 'failure:no session') || (sResponseText == '\nfailure:no session')) {
		    marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
		    report_phpsessid('request_group_invite');
		    request_reauthenticate(gsAuthKey, gsUserId, function(){request_group_invite(sInviteId, sAction, sFirst, sLast, sNotifSubj, sNotifBody);}); // one retry
		} else { 
		    // debug_message("in request_join_group xhrJoin.responseText: " + xhrJoin.responseText);
		    if (sAction == 'accept') {
			join_group_response(xhrJoin.responseText, gaTable['invites'][sInviteId]['groupname']);
			request_queue_pickup('wiggiomail.com', 'both');
		    } else { // sAction == 'refuse'
			unpack_session_cache_data(xhrJoin.responseText, 'user_group', 'add', '0');
		    }
		    // pass in the groupId so we can recognize if a user_group
		    // with the user's id and that groupid comes back in the session response
		}
	    } else if(xhrJoin.status == 0) { // user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
		setTimeout(function(){request_reconnect( function(){request_group_invite(sInviteId, sAction, sFirst, sLast, sNotifSubj, sNotifBody);});},1000); //one retry after 1 second
	    } else if (xhrJoin.status == 500) { // server error
		server_error_alert();
	    }
	}
    };
    xhrJoin.send(sRequestBody);
} // end function request_join_group




function request_reinvite_group() {
    // for group invite requests
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/group_reinvite.php';
    // post join info (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'gif_groupid='+ gsGroupId +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    // debug_message("in request_reinvite_group sURL: " + sURL);
    // debug_message("in request_reinvite_group sRequestBody: " + sRequestBody);
    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    marquee_show_timed('Sending re-invites...', 10000);
    xhrJoin.onreadystatechange = function() {
	if (xhrJoin.readyState == 4) {
	    if(xhrJoin.status==200){
			var sResponseText=xhrJoin.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_reinvite_group');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_reinvite_group();}); // one retry	
			}else{ 
				// debug_message("in request_reinvite_group xhrJoin.responseText: " + xhrJoin.responseText);
			    reinvite_response(xhrJoin.responseText);
		    }
	    }else if(xhrJoin.status==0){ //user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect( function(){request_reinvite_group();});},1000); //one retry after 1 second
		}else if(xhrJoin.status==500){ //server error
			server_error_alert();
		}
    }
    };
    xhrJoin.send(sRequestBody);
} // end function request_reinvite_group


function request_invite_group(sRecipients, sInviteText, sReception) {
    // for group invite requests
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/group_invite.php';
    // post join info (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'gif_groupid='+ gsGroupId +'&gif_recipients='+ escape_plus(sRecipients) + '&gif_invitetext='+ escape_plus(sInviteText) + '&gif_reception='+ escape_plus(sReception) +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    // debug_message("in request_invite_group sURL: " + sURL);
    // debug_message("in request_invite_group sRequestBody: " + sRequestBody);
    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    xhrJoin.onreadystatechange = function() {
        if (xhrJoin.readyState == 4) {
            // debug_message("in request_invite_group xhrJoin.responseText: " + xhrJoin.responseText);
	    unpack_session_cache_data(xhrJoin.responseText);
            invite_group_response(xhrJoin.responseText, sRecipients); 
	    request_queue_pickup('wiggiomail.com', 'both');
	}
    };
    xhrJoin.send(sRequestBody);
} // end function request_invite_group


function request_group_data(sGroupId) {
    // for group invite requests
    
    var xhrJoin;
    var sURL, sRequestBody;
    
    xhrJoin = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/group_data.php';

    // post join info (rather than get) so the transistion to https for auth will be easy

    sRequestBody = 'groupid='+ sGroupId +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';

    // debug_message("in request_invite_group sURL: " + sURL);
    // debug_message("in request_invite_group sRequestBody: " + sRequestBody);
    xhrJoin.open('POST', sURL, true);
    xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
    xhrJoin.onreadystatechange = function() {
        if (xhrJoin.readyState == 4) {
            // debug_message("in request_invite_group xhrJoin.responseText: " + xhrJoin.responseText);
	    unpack_session_cache_data(xhrJoin.responseText);
	    gsGroupsLoaded += '['+ sGroupId +']'; // remember that we have loaded this group's data
            enter_group(sGroupId); 
	}
    };
    xhrJoin.send(sRequestBody);
} // end function request_group_data


function request_chatroom(sAction, sChatId) {
    var xhr;
    var sURL, sRequestBody;
    
    xhr = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/chat_room.php';
    // post chatroom info (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'action='+ sAction +'&id='+ sChatId +'&packnumber='+ gsPackNumber +'&ago='+ ago;
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';
    
    // debug_message("in request_chatroom sURL: " + sURL);
    // debug_message("in request_chatroom sRequestBody: " + sRequestBody);
    xhr.open('POST', sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader('Content-Length', sRequestBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    if (xhr.status == 200) {
			var sResponseText=xhr.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_chatroom');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_chatroom(sAction, sChatId);}); // one retry	
			}else{ 
			    // debug_message("in request_chatroom xhr.responseText: " + xhr.responseText);
				chatroom_response(sAction, sChatId, xhr.responseText);
			}
	    } else if(xhr.status==0) {
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
	    	setTimeout(function(){request_reconnect( function(){request_chatroom(sAction, sChatId);});},1000); //one retry after 1 second	
	    }else {	
			chatroom_response(sAction, sChatId, xhr.status);
	    }
	}
    };
    xhr.send(sRequestBody);
} // end function request_chatroom

// function request_chat(sChatId, sChatEntry, sSize, sChatReqIndex) {
function request_chat(sChatId, sChatEntry, sSize) {
    var xhr;
    var sURL, sRequestBody;
    
    xhr = get_new_xmlhttp_object();
    
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click
    
    sURL = '/chat.php';
    // post chat entry (rather than get) so the transistion to https for auth will be easy
    sRequestBody = 'id='+ sChatId +'&post='+ escape_plus(sChatEntry) +'&size='+ sSize;
    
    // debug_message("in request_chat sURL: " + sURL);
    // debug_message("in request_chat sRequestBody: " + sRequestBody);
    xhr.open('POST', sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader('Content-Length', sRequestBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    // debug_message("in request_chat xhr.responseText: " + xhr.responseText);
	    // send along size to avoid doppler effect
	    // chat_response(sChatId, sSize, sChatReqIndex, xhr.responseText);
	    chat_response(sChatId, sSize, xhr.responseText);
	}
    };
    xhr.send(sRequestBody);
} // end function request_chat


function request_events_repeat(sBody) {
    var xhr;
    var sURL;
    var sBody;

    sBody += '&packnumber=' + gsPackNumber + '&ago=' + get_seconds_ago(); // add the pack number

    sBody += '&maxblocks=' + gsMaxBlocks; // add the max record id blocks
    gsMaxBlocks = ''; // forget blocks

    xhr = get_new_xmlhttp_object();

    sURL = '/events_repeat_save.php';
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
		
	    unpack_session_cache_data(xhr.responseText, 'events', 'add', 0);
	    request_queue_pickup('wiggiomail.com', 'mail');
	}
    };
    xhr.send(sBody);
}


function request_action(sTable, sAction, sRecordId) {

    // for requests that require INSERT/UPDATE database access
    var xhrAction;
    var sURL;
    var oForm, sChildCount, sRequestBody;
    var sResult;
    var sValue;
    
    sRequestBody = "";
    if ((sAction == "delete") || (sAction == "dismiss")) {
	sRequestBody = sTable + "id=" + sRecordId + "&action=" + sAction;
	if (sTable == 'events') { //special case for deleting events
	    var aEventInfo = gaTable['events'][gsDeleteEventId];
	    var sEventGroupId = gaTable['events'][gsDeleteEventId]['groupid'];
	    var sEventGroupName = gaTable['groups'][sEventGroupId]['groupname'];
	    sRequestBody += "&eef_event_type="+gsEventDeleteType+"&sendtoall="+gsDeleteEventSendToAll+"&groupid="+sEventGroupId+"&eventid="+gsDeleteEventId+"&eventname="+aEventInfo['eventname']+"&first="+gsFirst+"&last="+gsLast+"&groupname="+sEventGroupName+"&seriesid="+gsChangeSeries+"&rrule="+gsRRule+"&byday="+gsRRByDay+"&interval="+gsRRInterval+"&count="+gsRRCount+"&notifyrepeat="+gsRRNotifyRepeat;
	    gsChangeSeries = 0;
	}
	// to delete, pass the record id and "action=delete" to "<table>_save.xml"
	// to dismiss, pass the record id and "action=dismiss" to "<table>_save.xml"
	
	//alert("in request_action: sTable=" + sTable +" sAction="+ sAction +" sRecordId="+ sRecordId +" sRequestBody=" + sRequestBody);
	// was: sURL = "/" + sTable + "_" + sAction + "_save.xml";
	sURL = "/" + sTable + "_save.php";
	if ((sTable == "groups") || (sTable == "documents")) { //note that groups delete is currently DEPRECATED (and even when it was in use, it provided ability for user to unjoin group, not group deletion)
	    // special case: when deleting a user_group or document, call ".html" not ".php"; 
	    sURL = "/" + sTable + "_save.html";
	    sRequestBody += '&groupid=' + gsGroupId;
	}
    } else {
	// action is not delete or dismiss
	
	// retrieve the values from the form
	sFormId = sTable + "_" + sAction + "_form_" + sRecordId;
	// alert("in request_action: save case; sFormId: " + sFormId);
	// DEBUG TIP: "oForm has no properties" here means that the formId was bad (there is no form with that formId)
	oForm = document.getElementById(sFormId);
	// alert("in request_action: oForm: " + oForm);
	if (! oForm) {
	    alert("in request_action, save case: the form was not found with sFormId: " + sFormId);
	    return 0;  // then abort the script
	}
	sChildCount = oForm.elements.length;
	for (var i = 0; i < sChildCount; i++) {
	    if (sRequestBody != "") {
		sRequestBody += "&";
	    }
	    // currently assumes text or textarea
	    oE = oForm.elements[i];
	    sValue = escape_plus(oE.value);
	    sRequestBody += oE.name + "=" + sValue;
	}
	
	//special case for edit events
	if ((sAction == "edit") && (sTable == "events")) {
	    sRequestBody+="&seriesid="+gsChangeSeries+"&rrule="+gsRRule+"&byday="+gsRRByDay+"&interval="+gsRRInterval+"&count="+gsRRCount+"&notifyrepeat="+gsRRNotifyRepeat+"&change_series_time="+gsChangeSeriesTime;
	    gsChangeSeries = 0;
	}
	
	// debug_message('in request_action sRequestBody: ' + sRequestBody);
	sRequestBody += "&action=" + sAction;
	sURL = "/" + sTable + "_save.php";
    }
    // debug_message("in request_action: save case; sRequestBody: " + sRequestBody);

    // add the pack number to any request
    sRequestBody += '&packnumber=' + gsPackNumber + '&ago=' + get_seconds_ago();
    
    // add the max record id blocks to any request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';
    
    // send the values to the appropriate script on the application server
    
    xhrAction = get_new_xmlhttp_object();
    
    // sURL = "/" + sTable + "_" + sAction + "_save.php";
    // alert("sURL: " + sURL);
    xhrAction.open("POST", sURL, true);
    xhrAction.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrAction.setRequestHeader("Content-Length", sRequestBody.length);
    xhrAction.onreadystatechange = function() {
	if (xhrAction.readyState == 4) {
	    if(xhrAction.status==200){
		var sResponseText=xhrAction.responseText;
		// if there is a view template in the cache for this type
		if ((sTable == "users") && (sAction == "add")) { 
		    register_response(sResponseText); // SPECIAL CASE FOR REGISTER
		    
		    request_queue_pickup('wiggio.com', '');
		} else if (sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
		    marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
		    report_phpsessid('request_action');
		    request_reauthenticate(gsAuthKey, gsUserId, function(){request_action(sTable, sAction, sRecordId);});
		} else { 

		    //alert('readystatechange == 4: back from server...');

		    // was: action_response(sTable, sAction, sStep, sRecordId, xhrAction.responseText);
		    sResult = unpack_session_cache_data(sResponseText, sTable, sAction, sRecordId);

		    //alert('after unpack_session_cache...');
		    
		    if ((sTable == 'users') && (sAction == 'edit')) {
			// marquee_show_timed('Successfully edited settings!', 10000);
			debug_message('about to call uaf_save_response');
			uaf_save_response(sResult);
			request_queue_pickup('wiggio.com', '');
		    }
		    
		    /*** Removed by ML: I believe it is deprecated
			 if ((sTable == 'groups') && (sAction == 'add')) {
			 // debug_message('in request_action sResult: ' + sResult);
			 group_add_response(sResult);
			 request_queue_pickup('wiggiomail.com', 'both');
			 }
			 
			 if ((sTable == 'groups') && (sAction == 'edit')) {
			 // debug_message('in request_action sResult: ' + sResult);
			 group_edit_response(sResult);
			 }***/
		    
		    if ((sTable == 'posts') && (sAction == 'add')) {
			paf_response(sResult);
			request_queue_pickup('wiggiomail.com', 'post');
		    }
		    if ((sTable == 'messages') && (sAction == 'add')) {
			maf_response(sResult);
			request_queue_pickup('wiggio.com', '');
		    }
		    if ((sTable == 'notes') && (sAction == 'add')) {
			naf_response(sResult);
			request_queue_pickup('wiggio.com', '');
		    }
		    if ((sTable == 'notes') && (sAction == 'dismiss')) {
			var e = getE('right_sticky_note_' + sRecordId,0);
			if (e) {
			    e.parentNode.removeChild(e);
			}
			request_queue_pickup('wiggio.com', '');
		    }
		    if ((sTable == 'poll_build') && (sAction == 'add')) {
			marquee_show_timed('Poll sent!', 10000);
			poll_build_response(sResult);
			request_queue_pickup('wiggiomail.com', 'mail'); // pickup outgoing invite(s)
		    }
		    if ((sTable == 'poll') && (sAction == 'take')) {
			poll_take_response(sResult);
		    }
		    if ((sTable == 'calls') && (sAction == 'add')) {
			call_response(sResult);
			request_queue_pickup('wiggio.com', '');
		    }
		    if ((sTable == 'chats') && (sAction == 'add')) {
			marquee_show_timed('Chat created!', 10000);
			chat_add_response(sResult);
			request_queue_pickup('wiggio.com', '');
		    }
		    if (sTable == 'documents' || (sTable == 'links' && gsSection == 'folderlist')) {
			document_response(sResult);
			request_queue_pickup('wiggiomail.com', 'post');
		    }
		    if (sTable == 'events') {
			if (gsSection == 'inperson') {
			    inperson_response(sResult);
			}
			request_queue_pickup('wiggiomail.com', 'post');
		    }
		    if (sTable == 'subgroups') {
			subgroup_save_response(sAction, sResult);
		    }
		    if ((sTable == 'todolists') && ((sAction == 'add') || (sAction == 'edit'))) {
			// debug_message('in request_action response function calling todolist_save_response');
			todolists_save_response(sResult);
		    }
		    if ((sTable == 'todolists') && (sAction == 'delete')) {
			todolist_delete_response(sResult);
		    }
		    if ((sTable == 'tasks') && (sAction == 'edit')) {
			debug_message('in request_action response function calling tasks_save_response');
			task_save_response(sResult);
		    }
		}
		
	    } else if (xhrAction.status == 0) { // user has no connection
		marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
		// retry after one second
		setTimeout(function(){ request_reconnect(function(){ request_action(sTable, sAction, sRecordId); }); }, 1000); 
	    } else if (xhrAction.status == 500) { // server error
		server_error_alert();
	    }
	}
    };
    xhrAction.send(sRequestBody);
}
 
function new_action_response(sBolus, sTable, sAction, sRecordId) {
      var sResult = unpack_session_cache_data(sBolus, sTable, sAction, sRecordId);

      // sResult now contains the '{o:' block from the session cache (if there was one)

      // parse the '{o:' block for status and recordId

      // for example sResult could contain "{o:(success,135)}"

}

function request_templates(sTemplateSet) {
  var xhrTemplates, sURL;
  
  xhrTemplates = get_new_xmlhttp_object();
  
  // sURL = "templates_tar.php?set=" + sTemplateSet;
  sURL = 'templates.html';
  // debug_message('in request_templates, prior to request');
  xhrTemplates.open('GET', sURL, true);
  xhrTemplates.onreadystatechange = function() {
    if (xhrTemplates.readyState == 3) {
	// debug_message('in request_templates, response incoming ... sURL: ' + sURL);
    }
    if (xhrTemplates.readyState == 4) {
      // cache both recordset and record templates
      sTemplates = xhrTemplates.responseText;
      // debug_message('in request_templates, response received');
      // debug_message('in request_templates\nsTemplates: ' + sTemplates);
      
      // cache_templates is defined in common.js
      cache_templates(sTemplates);
      
      if (sTemplateSet == 'initial') {
	// call those operations from on_load that require templates
	// init_templates_loaded() defined in common.js
	init_templates_loaded();
      } else {
	// possibly never needed (if init bolus never grows too large)
	
	// sTemplateSet == 'auth'
	// call those operations from authorization_response that require templates
	// auth_templates_loaded() defined in login.js
	// auth_templates_loaded();
      }
    }
  };
  xhrTemplates.send('');
}



function request_footer(sFooterName) {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    sURL = '/footers/' + sFooterName + '.html';
    // debug_message("in request_footer sURL: " + sURL);
    xhr.open("GET", sURL, true);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    // debug_message("in request_footer xhr.responseText: " + xhr.responseText);
	    footer_response(sFooterName, xhr.responseText);
	}
    };
    xhr.send('');
}

function request_tell(sRecips) {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    if (sRecips != '') {
	sRequestBody = "recips=" + sRecips;

	sURL = '/tell_a_friend.php';
	xhr.open("POST", sURL, true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader("Content-Length", sRequestBody.length);
	xhr.onreadystatechange = function() {
	    if (xhr.readyState == 4) {
		tell_a_friend_response(xhr.responseText);
		request_queue_pickup('wiggio.com', '');
	    }
	};
	xhr.send(sRequestBody);
    }
}

function request_announce() {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    sURL = '/announce.txt';
    // debug_message("in request_announce sURL: " + sURL);
    xhr.open("GET", sURL, true);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    // debug_message("in request_announce xhr.responseText: " + xhr.responseText);
	    unpack_session_cache_data(xhr.responseText, gsGroupId);  // process the announce data
	    announce_sort();
	}
    };
    xhr.send('');
}

function request_testimonial() {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    sURL = '/testimonials.txt';
    // debug_message("in request_announce sURL: " + sURL);
    xhr.open("GET", sURL, true);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    // debug_message("in request_announce xhr.responseText: " + xhr.responseText);
	    unpack_session_cache_data(xhr.responseText, gsGroupId);  // process the testimonial data
	}
    };
    xhr.send('');
}


function request_block(sBlockName) {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    sURL = '/'+ sBlockName;
    // debug_message("in request_announce sURL: " + sURL);
    xhr.open("GET", sURL, true);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    // debug_message("in request_announce xhr.responseText: " + xhr.responseText);
	    unpack_session_cache_data(xhr.responseText, gsGroupId);  // process the response cache data
	    
	    if (sBlockName == 'announce.txt') {
		announce_sort();
	    }
	    if (sBlockName == 'purpose.txt') {
		// populate_group_purpose(0);
	    }
  	}
    };
    xhr.send('');
}

function request_prefs_save(sPrefName, sPrefValue) {
    var xhr, sURL, sRequestBody, sResult;
    var sKey, sGroupId, sPrefsBlocks;
    var sSMSTarget = '';

    xhr = get_new_xmlhttp_object();
    
    sPrefsBlocks = '';
    for (sKey in gaDirtyPrefs) { // assemble prefs blocks from groups listed in gaDirtyPrefs
	if (sKey.indexOf('group_') > -1) { // in case any other properties might interfere
	    sGroupId = sKey.substr(6); // get the group id from the array key by stripping 'group_'
	    delete gaDirtyPrefs[sKey]; // clean up the array element
	    sPrefsBlocks += '{prefs:'+ sGroupId +','+ gaSort['user_group'][sGroupId]['prefs'] +'},'; // write group prefs block to prefs blocks
	}
    }

    if (sPrefsBlocks != '') { // there are blocks for processing
	sRequestBody = "prefsblocks=" + sPrefsBlocks; // add the prefs blocks to the request body to be sent up to the server
	if ((typeof sPrefName != 'undefined') && (sPrefName != '')) { // there is a pref name
	    sRequestBody += "&prefname=" + sPrefName + "&prefvalue=" + sPrefValue + "&groupid=" + gsGroupId; // append name, value, ad groupid to post body

	    if ((sPrefName == 'reception') && (sPrefValue == 's')) {
		if (typeof gaTable['users'][gsUserId]['smstarget'] != 'undefined') {
		    sSMSTarget = gaTable['users'][gsUserId]['smstarget'];
		}
		sRequestBody += "&groupname=" + gsGroupName + "&maillistname=" + gaTable['groups'][gsGroupId]['maillistname'] + "&first=" + gsFirst + "&smstarget=" + sSMSTarget; // append reception-appropriate parameters to the post body
	    }
	}

	sURL = '/prefs_save.php';
	xhr.open("POST", sURL, true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader("Content-Length", sRequestBody.length);
	xhr.onreadystatechange = function() {
	    if (xhr.readyState == 4) {
			if(xhr.status==200){
				var sResponseText=xhr.responseText;
				if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
					marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
					report_phpsessid('request_prefs_save');
					request_reauthenticate(gsAuthKey, gsUserId, function(){request_prefs_save(sPrefName, sPrefValue);});	
				}else{ 
			    	prefs_save_response(sPrefName, sPrefValue, xhr.responseText);
					if ((sPrefName == 'reception') && (sPrefValue == 's')) { // an add-to-contacts suggestion SMS has been queued
				    request_queue_pickup('wiggiomail.com', 'mail');
			    	}
			    }
		    }else if(xhr.status==0){ //user has no connection
		    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
				setTimeout(function(){request_reconnect(function(){request_prefs_save(sPrefName, sPrefValue);});},1000); //retry after one second
			}else if(xhr.status==500){ //server error
				server_error_alert();
			}
		    
	    }
	};
	xhr.send(sRequestBody);
    }
}


function request_feedback(sRequestBody) {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    if (sRequestBody != '') {
	sURL = '/feedback.php';
	xhr.open("POST", sURL, true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader("Content-Length", sRequestBody.length);
	xhr.onreadystatechange = function() {
	    if (xhr.readyState == 4) {
		feedback_response(xhr.responseText);
		request_queue_pickup('wiggio.com', '');
	    }
	};
	xhr.send(sRequestBody);
    }
}
function request_premium_feedback(sRequestBody) {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    if (sRequestBody != '') {
	sURL = '/feedback.php';
	xhr.open("POST", sURL, true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader("Content-Length", sRequestBody.length);
	xhr.onreadystatechange = function() {
	    if (xhr.readyState == 4) {
		premium_feedback_response(xhr.responseText);
		request_queue_pickup('wiggio.com', '');
	    }
	};
	xhr.send(sRequestBody);
    }
}
//This function is used to report potential abuse, so differs only slightly from the one above it
function request_send_feedback(sRequestBody) {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    if (sRequestBody != '') {
	sURL = '/feedback.php';
	xhr.open("POST", sURL, true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader("Content-Length", sRequestBody.length);
	xhr.onreadystatechange = function() {
	    if (xhr.readyState == 4) {
	    }
	};
	xhr.send(sRequestBody);
    }
}

function request_test_sms(sRequestBody) {
    var xhr, sURL;
    
    xhr = get_new_xmlhttp_object();
    
    if (sRequestBody != '') {
	sURL = '/send_test_sms.php';
	xhr.open("POST", sURL, true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader("Content-Length", sRequestBody.length);
	xhr.onreadystatechange = function() {
	    if (xhr.readyState == 4) {
			if(xhr.status==200){
				var sResponseText=xhr.responseText;
				if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
					marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
					report_phpsessid('request_test_sms');
					request_reauthenticate(gsAuthKey, gsUserId, function(){request_test_sms(sRequestBody);});	
				}else{ 		
	    			test_sms_response(xhr.responseText);
    			}
		    }else if(xhr.status==0){ //user has no connection
		    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
		setTimeout(function(){request_reconnect(function(){request_test_sms(sRequestBody);});},1000); //retry after one second
			}else if(xhr.status==500){ //server error
				server_error_alert();
			}
	    }
	};
	xhr.send(sRequestBody);
    }
}

function request_generic(sURL, sRequestBody, sFunction) {
    var xhr = get_new_xmlhttp_object();
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sRequestBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    if (xhr.status == 200) {
		var sResponseText = xhr.responseText;
		if (sResponseText == 'failure:no session' || sResponseText == '\nfailure:no session') {
		    marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
		    report_phpsessid('request_generic');
		    request_reauthenticate(gsAuthKey, gsUserId, function(){request_generic(sURL, sRequestBody, sFunction);});	
		} else { 	    
		    generic_response(sFunction, xhr.responseText);
		}
	    } else if (xhr.status == 0){ // user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
		setTimeout(function(){request_reconnect(function(){request_generic(sURL, sRequestBody, sFunction);});},1000); // retry after one second
	    } else if (xhr.status == 500){ // server error
		server_error_alert();
	    }
	}
    };
    xhr.send(sRequestBody);
}

function generic_response(sFunction, sResponse) {
    switch(sFunction) {
    case 'cal_code':
	cal_code_response(sResponse);
	break;
    case 'cell_save':
	sResult = unpack_session_cache_data(sResponse, 'users', 'save', gsUserId);
	cell_save_response(sResult);
	request_queue_pickup('wiggiomail.com', 'mail');
	break;
    case 'send_list_address':
	send_list_address_response(sResponse);
	break;
    case 'verify_session_cookie':
	verify_sesion_cookie_response(sResponse);
	break;
    }
}

function request_queue_pickup(sPickupDomain, sType) {
    var sSite, eIFrame;

    //alert('entering request_queue_pickup...'); 

    if (0) { // WHY was this function deprecated ???

	if (0) { // DEPRECATED in favor of the following switch
	    if ((document.domain.indexOf('dev.wiggio') > -1) || (document.domain.indexOf('rob.wiggio') > -1) || (document.domain.indexOf('dtd.wiggio') > -1) || (document.domain.indexOf('cmc.wiggio') > -1) || (document.domain.indexOf('jr.wiggio') > -1) || (document.domain.indexOf('zb.wiggio') > -1) || (document.domain.indexOf('ml.wiggio') > -1)) {
	    }
	    if (document.domain.indexOf('alpha.wiggio') > -1) {
	    }
	    if ((document.domain.indexOf('www.wiggio') > -1) || (sSite == '')) {

	    }
	}

	switch (document.domain) {
	case 'alpha.wiggio.com':
	    sSite = 'alpha';
	    break;
	case 'wiggio.com': // fall-through
	case 'www.wiggio.com':
	    sSite = 'www';
	    break;
	default:
	    sSite = 'dev';
	    break;
	}

	// make the request; no response expected or required; cannot make the usual xhr request due to cross-site scripting restrictions
	switch (sPickupDomain) {
	case 'wiggio.com': // this request is for a mailqueue pickup for wiggio.com, sType doesn't matter for this case
	    eIFrame = getE('mailqueue_iframe', 0);
	    if (eIFrame) {
		eIFrame.src = 'http://echo2.wiggio.com/' + sSite + '.php'; 
	    }
	    break;
	case 'wiggiomail.com': // this request is for wiggiomail.com
	    switch (sType) {
	    case 'mail': // a mail queue pickup is requested
		eIFrame = getE('mailqueue_iframe', 0);
		if (eIFrame) {
		    eIFrame.src = 'http://wiggiomail.com/mq/' + sSite + '.php'; 
		}
		break;
	    case 'post':
		eIFrame = getE('postsqueue_iframe', 0);
		if (eIFrame) {
		    eIFrame.src = 'http://wiggiomail.com/pq/' + sSite + '.php'; 
		}
		break;
	    case 'both': // a mail queue pickup and a post queue pickup are requested
		eIFrame = getE('mailqueue_iframe', 0);
		if (eIFrame) {
		    eIFrame.src = 'http://wiggiomail.com/mq/' + sSite + '.php'; 
		}
		eIFrame = getE('postsqueue_iframe', 0);
		if (eIFrame) {
		    eIFrame.src = 'http://wiggiomail.com/pq/' + sSite + '.php'; 
		}
		break;
	    }
	    break;
	}

    }
    //alert('leaving request_queue_pickup...'); 

}


function request_delete_account(sBody) {
    var xhr;
    var sURL;
    var sBody;

    xhr = get_new_xmlhttp_object();

    sURL = '/delete_account.php';
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    if(xhr.status==200){
			var sResponseText=xhr.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_delete_account');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_delete_account(sBody);});
			}else{ 
				delete_account_response(xhr.responseText);
			}
		}else if(xhr.status==0){ //user has no connection
			marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect(function(){request_delete_account(sBody);});},1000); //retry after one second
		}else if(xhr.status==500){ //server error
			server_error_alert();
		}
	}
    };
    xhr.send(sBody);
}
//Added by ML
function request_invite_set_to_reject(sId){
	var xhr;
    var sURL;
    var sBody;
  	var ago = get_seconds_ago();  // get the time since the users last mouse or key click
  	
    xhr = get_new_xmlhttp_object();

    sURL = '/invite_reject.php';
    sBody='inviteId='+sId+'&packnumber='+ gsPackNumber +'&ago='+ ago;;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
		//do nothing
	}
    };
    xhr.send(sBody);
}

function request_poll_resend(sBody) {
    var xhr;
    var sURL;
    var sBody;

    xhr = get_new_xmlhttp_object();

    sURL = '/poll_resend.php';
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
		if(xhr.status==200){
			var sResponseText=xhr.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_poll_resend');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_poll_resend(sBody);});
			}else{ 
			    var sResult = unpack_session_cache_data(xhr.responseText, '', '', '');
			    poll_resend_response(sResult);
		    }	
		}else if(xhr.status==0){ //user has no connection
			marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect(function(){request_poll_resend(sBody);});},1000); //retry after one second
		}else if(xhr.status==500){ //server error
			server_error_alert();
		}
			    
    }
    };
    xhr.send(sBody);
}

//
function request_close_group(sGroupId) {
  // for group closing requests
  
  var xhrJoin;
  var sURL, sRequestBody;
  
  xhrJoin = get_new_xmlhttp_object();

  var ago = get_seconds_ago();  // get the time since the users last mouse or key click

  //alert('about to do server request for group_unjoin.php ...');

  sURL = '/group_close.php';
  // post join info (rather than get) so the transistion to https for auth will be easy
  sRequestBody = 'groupid='+ escape_plus(sGroupId)+'&packnumber='+ gsPackNumber +'&ago='+ ago;
  // add the max record id blocks to the request and forget them
  sRequestBody += '&maxblocks=' + gsMaxBlocks;
  gsMaxBlocks = '';
  // alert("in request_authentication\nsURL: " + sURL);
  // alert("in request_authentication\nsRequestBody: " + sRequestBody);
  xhrJoin.open('POST', sURL, true);
  xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
  xhrJoin.onreadystatechange = function() {
    if (xhrJoin.readyState == 4) {
    	if(xhrJoin.status==200){
			var sResponseText=xhrJoin.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_close_group');
				request_reauthenticate(gsAuthKey, gsUserId, function(){request_close_group(sGroupId);});
			}else{ 
    			close_group_response(xhrJoin.responseText, sGroupId);
			}
	    }else if(xhrJoin.status==0){ //user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect(function(){request_close_group(sGroupId);});},1000); //retry after one second
		}else if(xhrJoin.status==500){ //server error
			server_error_alert();
		}
    }
  };
  xhrJoin.send(sRequestBody);
} // end function request_close_group

function request_dismiss_group_close(sUserGroupId){
  // for permanently dismissing the group close notification on allgroups age
  
  var xhrJoin;
  var sURL, sRequestBody;
  
  xhrJoin = get_new_xmlhttp_object();

  var ago = get_seconds_ago();  // get the time since the users last mouse or key click

  //alert('about to do server request for group_unjoin.php ...');

  sURL = '/groupclose_notice_dismiss.php';
  // post join info (rather than get) so the transistion to https for auth will be easy
  sRequestBody = 'usergroupid='+ escape_plus(sUserGroupId)+'&packnumber='+ gsPackNumber +'&ago='+ ago;
  // add the max record id blocks to the request and forget them
  sRequestBody += '&maxblocks=' + gsMaxBlocks;
  gsMaxBlocks = '';
  // alert("in request_authentication\nsURL: " + sURL);
  // alert("in request_authentication\nsRequestBody: " + sRequestBody);
  xhrJoin.open('POST', sURL, true);
  xhrJoin.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhrJoin.setRequestHeader('Content-Length', sRequestBody.length);
  xhrJoin.onreadystatechange = function() {
    if (xhrJoin.readyState == 4) {
	unpack_session_cache_data(xhrJoin.responseText, '', '', '');
    }
  };
  xhrJoin.send(sRequestBody);	
}

//checks to see whether user has connection and whether user still has server session
function request_check_server_and_conn(fActionToTake){
	var xhrConn;
    var sURL;
    
    xhrConn = get_new_xmlhttp_object();
    
    sURL = '/check_server_and_conn.php';
    sRequestBody = 'packnumber=' + gsPackNumber + '&ago=' + get_seconds_ago();
    
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';
    
    xhrConn.open("POST", sURL, true);
    xhrConn.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrConn.setRequestHeader("Content-Length", sRequestBody.length);	    
	xhrConn.onreadystatechange = function() {
	if (xhrConn.readyState == 4) {
		if(xhrConn.status==200){
			var sResponseText=xhrConn.responseText;
			if(sResponseText=='failure:no session' || sResponseText=='\nfailure:no session'){
				marquee_show_timed('Lost contact with server. Reconnecting...', 10000);
				report_phpsessid('request_check_server_and_conn');
				request_reauthenticate(gsAuthKey, gsUserId, fActionToTake); // one retry
			}else{ 
				fActionToTake();
			}
	    }else if(xhrConn.status==0){ //user has no connection
	    	marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect(fActionToTake)},1000); //one retry after 1 second
		}else if(xhrConn.status==500){ //server error
			server_error_alert();
		}
	}
	};
	xhrConn.send(sRequestBody);
    
}

//checks to see whether user has connection 
function request_check_conn(fActionToTake){
    var xhrConn;
    var sURL;
    
    //fActionToTake();

    xhrConn = get_new_xmlhttp_object();
    
    sURL = '/check_conn.php';
    sRequestBody = 'packnumber=' + gsPackNumber + '&ago=' + get_seconds_ago();
    
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';
    
    // alert('in request_session_cache \n sURL: ' + sURL +' sRequestBody='+ sRequestBody);
    xhrConn.open("POST", sURL, true);
    xhrConn.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrConn.setRequestHeader("Content-Length", sRequestBody.length);	    
    xhrConn.onreadystatechange = function() {
	if (xhrConn.readyState == 4) {
		if(xhrConn.status==0){ //user has no connection
			marquee_show_timed('Connection failed. Attempting to reconnect...', 10000);
			setTimeout(function(){request_reconnect(fActionToTake)},1000); //one retry after 1 second
		} else {
			fActionToTake();
		}
	}
	};
	xhrConn.send(sRequestBody);
}

function request_reconnect(fActionToTake){
    var xhrConn;
    var sURL;
    
    //fActionToTake();

    xhrConn = get_new_xmlhttp_object();
    
    sURL = '/check_conn.php';
    sRequestBody = 'packnumber=' + gsPackNumber + '&ago=' + get_seconds_ago();
    
    // add the max record id blocks to the request and forget them
    sRequestBody += '&maxblocks=' + gsMaxBlocks;
    gsMaxBlocks = '';
    
    // alert('in request_session_cache \n sURL: ' + sURL +' sRequestBody='+ sRequestBody);
    xhrConn.open("POST", sURL, true);
    xhrConn.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhrConn.setRequestHeader("Content-Length", sRequestBody.length);	    
    xhrConn.onreadystatechange = function() {
	if (xhrConn.readyState == 4) {
		if(xhrConn.status==0){ //user has no connection
			gfSavedAction=fActionToTake; //save function that was supposed to be called as global
			connection_loss_alert(); //The only place this should be called (for now). If it is ever added anywhere else, gfSavedAction must be set to the function that should be called on OK click to the alert.
		}else{
			marquee_show_timed('Regained connection!', 7000);
			fActionToTake();
		}
	}
	};
	xhrConn.send(sRequestBody);
}

// THIS FUNCTION APPEARS TO BE UNUSED
function request_change_series(sEventId) {
    var xhr;
    var sURL;
    var sRequestBody = '';

    alert('entering request_change_series...');

    // retrieve the values from the form
    var sFormId = 'events_edit_form_'+ sEventId;
    // alert("in request_action: save case; sFormId: " + sFormId);
    // DEBUG TIP: "oForm has no properties" here means that the formId was bad (there is no form with that formId)
    oForm = document.getElementById(sFormId);
    // alert("in request_action: oForm: " + oForm);
    if (! oForm) {
	alert('in request_change_series, save case: the form was not found ');
	return 0;  // then abort the script
    }
    sChildCount = oForm.elements.length;
    alert('in request_change_series: collecting form vars: '+ sChildCount);
    for (var i = 0; i < sChildCount; i++) {
	if (sRequestBody != '') {
	    sRequestBody += '&';
	}
	// currently assumes text or textarea
	oE = oForm.elements[i];
	sValue = escape_plus(oE.value);
	sRequestBody += oE.name + '=' + sValue;
    }
    debug_message(sRequestBody);
    sRequestBody += '&action=' + sAction;
	
    xhr = get_new_xmlhttp_object();

    alert('in request_change_series: about to call event_change_series.php...');

    sURL = '/event_change_series.php';
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sRequestBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    var sResult = unpack_session_cache_data(xhr.responseText, '', '', '');
	    event_change_series_response(sResult);
	}
    };
    xhr.send(sRequestBody);
}

function request_fb_connect() {
    var xhr;
    var sURL; 
    var sBody;
    
    xhr = get_new_xmlhttp_object();
    sURL = "fbconn/fbconn.php";
    sBody = "fbid=" + gsFbId;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_fb_connect(xhr.responseText);
	}
    };
    xhr.send(sBody);
}

function request_fb_link(sEmail) {
    var xhr;
    var sURL; 
    var sBody;
    
    xhr = get_new_xmlhttp_object();
    sURL = "fbconn/fblink.php";
    sBody = "fbid=" + gsFbId + '&email=' + sEmail + '&timezone=' + gsViewZone;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_fb_link(xhr.responseText);
	}
    };
    xhr.send(sBody);
}

function request_fb_invited() {
    var xhr;
    var sURL; 
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "fbconn/fbinvited.php";
    sBody = '&groupid=' + gsGroupId ;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_fb_invited(xhr.responseText);
	}
    };
    xhr.send(sBody);
}

function request_group_link_join(sEmail) {
    var xhr;
    var sURL; 
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "group_link_join.php";
    sBody = 'groupid=' + gsGroupJoinId + '&email=' + sEmail + '&fbid=' + gsFbId + '&timezone=' + gsViewZone;;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_group_link_join(xhr.responseText);
	}
    };
    xhr.send(sBody);
}
function request_get_started(sEmail) {
    var xhr;
    var sURL; 
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "get_started.php";
    sBody = '&email=' + sEmail + '&timezone=' + gsViewZone;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_get_started(xhr.responseText);
	}
    };
    xhr.send(sBody);
}

function request_group_link_join_pw(sEmail,sPassword) {
    var xhr;
    var sURL; 
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "group_link_join_pw.php";
    sBody = 'groupid=' + gsGroupJoinId + '&email=' + sEmail + '&password=' + sPassword + '&fbid=' + gsFbId;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_group_link_join_pw(xhr.responseText);
	}
    };
    xhr.send(sBody);
}

function request_fb_update() {
    var xhr;
    var sURL; 
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "fbconn/fbupdate.php";
    sBody = 'fbid=' + gsFbId + '&userid=' + gsUserId;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_fb_update(xhr.responseText);
	}
    };
    xhr.send(sBody);
}
function request_fb_friends() {

    var xhr;
    var sURL;
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "fbconn/fbfriends.php";
    sBody = "fbid=" + gsFbId + '&groupid=' + gsGroupId + '&groupname=' + gsGroupName + '&email=' + gsEmail + '&url=' + gsUrl;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            load_fb_friends(xhr.responseText);
        }
    };
    xhr.send(sBody);
}
function request_group_open_join(sGroup,sPassword,sType) {
    var xhr;
    var sURL;
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "group_open_join.php";
    sBody = "groupname=" + sGroup + '&password=' + sPassword + '&type=' + sType;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            get_group_cancel();
	    on_load();
        }
    };
    xhr.send(sBody);
}
function request_demo_group_update_name(sUserId,sFirst) {
    var xhr;
    var sURL;
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "demo_group_update_name.php";
    sBody = "userid=" + sUserId + '&first=' + sFirst;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            request_session_cache();
	}
    };
    xhr.send(sBody);
}

function request_set_machine_tz(sMachineTz) {
    var xhr;
    var sURL;
    var sBody;
    xhr = get_new_xmlhttp_object();
    sURL = "set_machine_tz.php";
    sBody = "timezone=" + sMachineTz;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            request_session_cache();
	}
    };
    xhr.send(sBody);
}

function request_event_reminder(sMinutes, sEventId, sType, sSeries, sGroupName, sRecipType) {
    var xhr;
    var sURL;
    var sBody;
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click

    xhr = get_new_xmlhttp_object();
    sURL = "set_event_reminder.php";
    sBody = "minutes=" + sMinutes + "&eventid=" + sEventId + "&type=" + sType + "&seriesid=" + sSeries + "&groupname=" + sGroupName + "&reciptype=" + sRecipType + '&packnumber=' + gsPackNumber +'&ago='+ ago;;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            unpack_session_cache_data(xhr.responseText);
	}
    };
    xhr.send(sBody);
}

function request_user_phone_update(sPhone, sCarrier, sCarrierId, sCarrierDomain, sPhonePrivate) {
    
    var xhr;
    var sURL;
    var sBody;
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click

    xhr = get_new_xmlhttp_object();
    sURL = "user_phone_update.php";
    sBody = "&phone="+sPhone+"&carrier="+sCarrier+"&carrierid="+sCarrierId+"&carrierdomain="+sCarrierDomain+"&phoneprivate="+sPhonePrivate+'&packnumber='+gsPackNumber+'&ago='+ago;;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
        
	    unpack_session_cache_data(xhr.responseText);
	    marquee_hide();
	    
	    // test if being updated from event details
	    var e = getE('event_reminder_edit', 0);
	    if (e) { // if so update event reminder
		setTimeout('change_event_reminder();',2000);    
	    }
	}
    };
    xhr.send(sBody);
}
function request_user_names_update(sJson) {
    
    var xhr;
    var sURL;
    var sBody;
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click

    xhr = get_new_xmlhttp_object();
    sURL = "user_names_update.php";
    sBody = "&json_edit_names="+sJson+'&packnumber='+gsPackNumber+'&ago='+ago;;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
	    unpack_session_cache_data(xhr.responseText);
	    group_members_edit_names_response();
	}
    };
    xhr.send(sBody);
}
function request_user_prefs_update(sJson) {
    
    var xhr;
    var sURL;
    var sBody;
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click

    xhr = get_new_xmlhttp_object();
    sURL = "user_prefs_update.php";
    sBody = "&json_edit_prefs="+sJson+'&packnumber='+gsPackNumber+'&ago='+ago;;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
	    unpack_session_cache_data(xhr.responseText);
	    user_prefs_update_response();
	}
    };
    xhr.send(sBody);
}
var gsSignUp = 0;
function request_create_test_user(sSignUp) {
    
    gsSignUp = sSignUp; //set a flag so we know to call sign up at the end of authentication response
    
    var xhr;
    var sURL; 
    var sBody;
    gsTestUser = 1;
    gsFbId = 0; // reset flag incase they have iniated fb conn and canceled
    loading_start();
    // store globals to auto-populate login on convert to user
    gsStoreEmail = (getE('email',0).value != 'Email' ? getE('email',0).value : gsStoreEmail);
    gsStorePassword = (getE('password',0).value != 'Password' ? getE('password',0).value : gsStorePassword);
    xhr = get_new_xmlhttp_object();
    sURL = "create_test_user.php";
    sBody = 'timezone=' + gsViewZone;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_create_test_user(xhr.responseText);
	}
    };
    xhr.send(sBody);
}

function request_convert_login(sJson) {
    
    var xhr;
    var sURL;
    var sBody;
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click

    xhr = get_new_xmlhttp_object();
    sURL = "convert_login.php";
    sBody = "&json_convert_login="+sJson+'&packnumber='+gsPackNumber+'&ago='+ago;;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
	    unpack_convert_login(xhr.responseText);	    
	}
    };
    xhr.send(sBody);
}
function request_convert_test_user(sRequest) {
    var xhr;
    var sURL;
    var sBody;
    var ago = get_seconds_ago();  // get the time since the users last mouse or key click

    xhr = get_new_xmlhttp_object();
    sURL = "convert_test_user.php";
    sBody = sRequest + '&packnumber='+escape_plus(gsPackNumber)+'&ago='+escape_plus(ago);;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
	    unpack_convert_test_user(xhr.responseText);	    
	}
    };
    xhr.send(sBody);
}
function request_terms() {
    var xhr, sURL;
    xhr = get_new_xmlhttp_object();
    sURL = '/footers/terms_and_conditions.html';
    xhr.open("GET", sURL, true);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_terms(xhr.responseText);
	}
    };
    xhr.send('');
}
function request_privacy() {
    var xhr, sURL;
    xhr = get_new_xmlhttp_object();
    sURL = '/footers/privacy_policy.html';
    xhr.open("GET", sURL, true);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_privacy(xhr.responseText);
	}
    };
    xhr.send('');
}
function request_convert_fbconn() {
    var xhr;
    var sURL; 
    var sBody;
    
    xhr = get_new_xmlhttp_object();
    sURL = "fbconn/fbconn.php";
    sBody = "fbid=" + gsFbId;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_convert_fbconn(xhr.responseText);
	}
    };
    xhr.send(sBody);
}
function request_convert_fb_link(sEmail) {
    var xhr;
    var sURL; 
    var sBody;
    
    xhr = get_new_xmlhttp_object();
    sURL = "fbconn/convert_fb_link.php";
    sBody = "fbid=" + gsFbId + '&email=' + sEmail + '&userid=' + gsUserId;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    unpack_convert_fb_link(xhr.responseText);
	}
    };
    xhr.send(sBody);
}
function request_convert_confirm_resend() {
    var xhr;
    var sURL; 
    var sBody;
    
    xhr = get_new_xmlhttp_object();
    sURL = "convert_confirm_resend.php";
    sBody = "email=" + oUserConfirm.email + '&section=' + oUserConfirm.section + '&confcode=' + oUserConfirm.confcode + '&userid=' + gsUserId + '&first=' + oUserConfirm.first;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    eval(xhr.responseText);
	    if (oResponse.status == 'success') {
		w_alert('Please check your email','We have sent you a new confirmation link.');
	    }
	}
    };
    xhr.send(sBody);
}
function get_user_messages(sGroupId) {
    var xhr;
    var sURL; 
    var sBody;
    
    xhr = get_new_xmlhttp_object();
    sURL = "get_user_messages.php";
    sBody = "groupid=" + sGroupId;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	    draw_messages(xhr.responseText);
	}
    };
    xhr.send(sBody);
}
function request_error_report(sErrorReport) {
    var xhr;
    var sURL; 
    var sBody;
    
    xhr = get_new_xmlhttp_object();
    sURL = "error_report.php";
    sBody = "error_report=" + sErrorReport;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
	if (xhr.readyState == 4) {
	}
    };
    xhr.send(sBody);
}

function request_warning_report(sWarningReport) {
    var xhr;
    var sURL;
    var sBody;

    xhr = get_new_xmlhttp_object();
    sURL = "warning_report.php";
    sBody = "warning_report=" + sWarningReport;
    xhr.open("POST", sURL, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.setRequestHeader("Content-Length", sBody.length);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
        }
    };
    xhr.send(sBody);
}
