/*
Some of the functions come in pairs. The first function is called to submit data to the API, the second function is
what's called when XML data is returned from the API. Inside the second function is always a switch() statement. The
cases in the switch() are the potential response codes for the API request that was sent in, as some responses may
require unique action to be taken. A lot of cases are completely blank, but I leave them as a semi-reminder as to which
cases could possibly come if I want to make any quick changes. Plus it helps in debugging. It looks stupid, but they're
commented out.

A list of response codes and their meaning is in the api.php file (not publicly accessible).
*/

var global_username = '';
var global_password = '';
displayed_username = '';
var login_form_content = 
	"<form action='#' onsubmit='login();return(false);'> \
	<table> \
		<tr><td><span class='login-prompt-text'>Username:</span></td> <td><input type='text' class='login-field' id='username' tabindex='1' /></td></tr> \
		<tr><td><span class='login-prompt-text'>Password:</span></td> <td><input type='password' class='login-field' id='password' tabindex='2' /></td></tr> \
	</table> \
	<input class='clicky' type='submit' value='Log In' tabindex='3' /><br /> \
	</form>";
var default_notepad_rows = 13;
var default_notepad_cols = 80;
var timer;


/////
// For when the page loads or unloads.
/////
function page_load(page_name)
{
	// Only specific pages get anything special
	switch (page_name) {
	
		case 'index':
			adjust_notepad_size('increment',0,0); //Force the 'notepad size' text to display
			document.getElementById('status-text').innerHTML = "Log in on the left, or <a href='register.php'>register</a>, to access your personal notepad.";
			document.getElementById('username').focus(); //Set the focus so they can immediately start typing
			//document.getElementById('leave_save').checked = false; //Force some of the options to be blank (in case of a page refresh)
			document.getElementById('autosave').checked = false;
		break;
		
		case 'register':
			document.getElementById('username').focus(); //Set the focus so they can immediately start typing, all the register pages have a username field
		break;
	
	}
	
	// Pre-load the "loading" image. Or should we have a "loading" image to indicate that the "loading" image is loading? :-P
	progress_bar = new Image(16,16); 
	progress_bar.src = "waiting.gif"; 
}

function page_unload(page_name)
{/*
	* This function isn't being used yet, only exists for future development. *
	switch (page_name) {
	
		case 'index':
			leave_save();
		break;
		
	}*/
}


/////
// To log a user in and set up their notepad
/////
function login()
{
	var send_data;
	var func_to_call = login_recieve;
	
	// Send the data
	send_data = "action=login&username=" + Base64.encode(document.getElementById('username').value) + "&password=" + Base64.encode(document.getElementById('password').value);
	send_cmd(send_data,"Logging in.",func_to_call);
}

function login_recieve(xmlData)
{
	// The data request was successful. Now check the first few characters for the responce code and output data accordingly.
	// See the login.php file for a list of what each response code means.
	
	switch (xmlData.getElementsByTagName("response_code")[0].childNodes[0].nodeValue) {
		// If they log in correctly, set up their personal notepad, set the focus, store the global variable data, and give them a welcome message.
		case "10":
			// Set the notepad options/preferences
			adjust_notepad_size('set',xmlData.getElementsByTagName("rows")[0].childNodes[0].nodeValue,xmlData.getElementsByTagName("cols")[0].childNodes[0].nodeValue);
			set_font_color(xmlData.getElementsByTagName("font_color")[0].childNodes[0].nodeValue);
			set_background_color(xmlData.getElementsByTagName("background_color")[0].childNodes[0].nodeValue);
			/*set_font_style(xmlData.getElementsByTagName("font_style")[0].childNodes[0].nodeValue);
			if (xmlData.getElementsByTagName("leave_save")[0].childNodes[0].nodeValue == 'true')
				document.getElementById('leave_save').checked = true;
			else
				document.getElementById('leave_save').checked = false;*/
			if (xmlData.getElementsByTagName("autosave")[0].childNodes[0].nodeValue == 'true')
				document.getElementById('autosave').checked = true;
			else
				document.getElementById('autosave').checked = false
			
			// Set the notepad data
			document.getElementById('notepad').value = Base64.decode(xmlData.getElementsByTagName("notepad_data")[0].childNodes[0].nodeValue);
			document.getElementById('notepad').focus();
			
			// Set the global vars
			displayed_username = Base64.decode(xmlData.getElementsByTagName("username")[0].childNodes[0].nodeValue);
			global_username = document.getElementById('username').value;
			global_password = document.getElementById('password').value;
			document.getElementById('login-header').innerHTML = "Welcome!"
			document.getElementById('login-form').innerHTML = 
				"Welcome to your notepad, <b>" + displayed_username + "</b>.<br />" +
			 	"&bull; Check out the <a href='details.php'>usage</a> page for quick tips on using your notepad.<br />" + 
			 	"&bull; <a href='javascript:logout();' tabindex='6' title='Log out'>Click here to log out</a>.";
			
			// Start the autosave counter
			autosave(0); 
		break;
		
		case "11":
			document.getElementById('username').value = '';
			document.getElementById('password').value = '';
			document.getElementById('username').focus(); 
		break;
		/*
		case "16":
		break;*/
	}
	document.getElementById('status-text').innerHTML = xmlData.getElementsByTagName("status")[0].childNodes[0].nodeValue;
}

function logout()
{
	autosave(-1); //Clear the autosave counter, do this first so that it doesn't try to save a millisecond too late after other variables have been unset.
	//leave_save(); //See if the user wants his notepad automatically saved.
	
	// Clear the "undo" history of the notepad textarea by creating a new notepad element and replacing 
	// the existing one with it. Cheers to ShamrockMan (http://shamrockman.net) for helping.
	document.getElementById('notepad').value = ''; 
	var old_area = document.getElementById("notepad");
   var new_area = document.createElement("textarea");
	new_area.value = "";
   var divRef = document.getElementById("notepad-container");
   divRef.replaceChild(new_area,old_area);   
   new_area.id="notepad";
   
   // Adjust visible notepad options/preferences
   adjust_notepad_size('set',default_notepad_rows,default_notepad_cols);
   /*document.getElementById('leave_save').checked = false;*/
   document.getElementById('autosave').checked = false;
	
	// Reset the login form and login session data
	document.getElementById('status-text').innerHTML = "Log in on the left, or <a href='register.php'>register</a>, to access your personal notepad."; //Reset the status
	reset_login(); //Reset the login form data
	document.getElementById('username').focus(); //In case they want to login again
}

function reset_login()
{
	global_username = '';
	global_username = '';
	document.getElementById('login-header').innerHTML = "Login";
	document.getElementById('login-form').innerHTML = login_form_content;
}


/////
// Save the user's notepad
/////
function save(mode)
{
	var send_data;
	var func_to_call = save_recieve;
	
	// Send the data (trim hash marks off the front of color codes and add them later)
	send_data = "action=save" + 
					"&mode=" + mode + 
	            "&username=" + Base64.encode(global_username) + 
					"&password=" + Base64.encode(global_password) + 
					"&notepad_data=" + Base64.encode(document.getElementById('notepad').value) + 
					"&rows=" + document.getElementById('notepad').rows + 
					"&cols=" + document.getElementById('notepad').cols + 
					"&autosave=" + document.getElementById('autosave').checked + 
					"&font_color=" + document.getElementById('font-colors').value.substr(1,6) + 
					"&background_color=" + document.getElementById('background-colors').value.substr(1,6) /*+ 
					"&leave_save=" + document.getElementById('leave_save').checked +
					"&font_style=" + document.getElementById('font-styles').value*/;
	send_cmd(send_data,"Saving data.",func_to_call);
}

function save_recieve(xmlData)
{
	var str_date, hour, str_output;
	var the_date = new Date();
	var response_code = xmlData.getElementsByTagName("response_code")[0].childNodes[0].nodeValue;
	// The data request was successful. Now check the first few characters for the responce code and output data accordingly.
	// See the api.php file for a list of what each response code means.
	
	switch (response_code) {
		case "11":
			reset_login();
		break;
		/*
		case "12":
		break;
		
		case "16":
		break;*/
	}
	
	str_output = xmlData.getElementsByTagName("status")[0].childNodes[0].nodeValue;
	
	// For certain return values, calculate the time and parse the hours to be 1-12.
	if (response_code != 11) {
		hour = the_date.getHours();
		minute = the_date.getMinutes();
		if (minute < 10)
			minute = "0" + minute;
		if (hour > 12)
		   str_date = (hour - 12) + ":" + minute + " PM.";
		else if (hour == 12)
		   str_date = "12:" + minute + " PM.";
		else if (hour > 0 && hour < 12)
			str_date = hour + ":" + minute + " AM.";
		else if (hour == 0)
			str_date = "12:" + minute + " AM.";
		
		str_output += str_date;
	}
	
	document.getElementById('status-text').innerHTML =  str_output;
	
	// Restart the autosave counter when the data is manually saved
	autosave(0);
}

function autosave(start)
{
	// Start/restart the one minute wait.
	if (start == 0) {
		clearTimeout(timer);
		timer = setTimeout("autosave(1)",60 * 1000); // Milliseconds
	}
	// Save the notepad data if the option is set. Then start over.
	else if (start == 1) {
		if (document.getElementById('autosave').checked == true)
			save("auto");
		autosave(0);
	}
	// Destroy the counter.
	else if (start == -1) {
		clearTimeout(timer);
	}
}

// When triggered, save the notepad on logout/window exit if the option is turned on to.
function leave_save()
{
	/* This function isn't being used yet, only exists for future development. 
	// See if the option is turned on
	if (document.getElementById('leave_save').checked == true)
		save('auto');*/
}


/////
// To register a new user
/////
function register_user()
{
	var send_data;
	var func_to_call = register_recieve;
	
	// If the email field is empty, double check that the user realizes the ramifications of this
	if (document.getElementById('email').value == '') {
		if (!confirm("Are you sure you don't want to provide an e-mail? You do NOT have to provide one, if you do not then there won't be any way to reset your password if you forget it.\n\nClick \"OK\" to continue registering, click \"Cancel\" to NOT register."))
			return;
	}
	
	// Double check that their passwords are the same. (Doesn't matter that it's being done client-side, since if they bypassed it they're only hurting themselves. It's for their sake, not mine.)
	if (document.getElementById('password').value != document.getElementById('password2').value) {
		document.getElementById('register-status').innerHTML = "<span style='font-color:red;'>Error: Your passwords do not match.</span>";
		document.getElementById('password').value = '';
		document.getElementById('password2').value = '';
		document.getElementById('password').focus();
		return;
	}
	
	// Send the data
	send_data = "action=register&username=" + Base64.encode(document.getElementById('username').value) + 
	            "&password=" + Base64.encode(document.getElementById('password').value) + 
	            "&email=" + Base64.encode(document.getElementById('email').value);
	send_cmd(send_data,"Processing registration.",func_to_call);
}

function register_recieve(xmlData)
{
	switch (xmlData.getElementsByTagName("response_code")[0].childNodes[0].nodeValue) {
		/*case "13":
		break;*/
		
		case "14":
		case "20":
			document.getElementById('username').value = '';
			document.getElementById('username').focus();
		break;
		
		case "21":
			document.getElementById('password').value = '';
			document.getElementById('password2').value = '';
			document.getElementById('password').focus();
		break;
	}
	document.getElementById('register-status').innerHTML = xmlData.getElementsByTagName("status")[0].childNodes[0].nodeValue;
	document.getElementById('password').value = ''; //Reset the password fields by default, but not the username/email ones.
	document.getElementById('password2').value = '';
}


/////
// To reset a password
/////
function reset_pwd()
{
	var send_data;
	var func_to_call = reset_recieve;
	
	// Make sure a username is specified
	if (document.getElementById("username").value == '') {
		alert("Please specify a username.");
		return;
	}
	
	// Send the data
	send_data = "action=reset_pwd&username=" + Base64.encode(document.getElementById('username').value);
	send_cmd(send_data,"Resetting password.",func_to_call);
}

function reset_recieve(xmlData)
{/*
	switch (xmlData.getElementsByTagName("response_code")[0].childNodes[0].nodeValue) {
		case "17":
		case "18":
		case "19":
		break;
	}*/
	document.getElementById('register-status').innerHTML = xmlData.getElementsByTagName("status")[0].childNodes[0].nodeValue;
}


/////
// To change a password
/////
function change_pwd()
{
	var send_data;
	var func_to_call = change_pwd_recieve;
	
	// Double check that their new passwords are the same. (Doesn't matter that it's being done client-side, since nothing could happen if they bypassed it.
	// It's for their sake, not mine.
	if (document.getElementById('new_password').value != document.getElementById('new_password2').value) {
		document.getElementById('register-status').innerHTML = "<span style='font-color:red;'>Error: Your passwords do not match.</span>";
		document.getElementById('new_password').value = '';
		document.getElementById('new_password2').value = '';
		document.getElementById('new_password').focus();
		return;
	}
	
	// Send the data
	send_data = "action=change_pwd&username=" + Base64.encode(document.getElementById('username').value) + 
	            "&old_password=" + Base64.encode(document.getElementById('old_password').value) + 
	            "&new_password=" + Base64.encode(document.getElementById('new_password').value);
	send_cmd(send_data,"Changing password.",func_to_call);
}

function change_pwd_recieve(xmlData)
{
	switch (xmlData.getElementsByTagName("response_code")[0].childNodes[0].nodeValue) {
		case "16":
			document.getElementById('old_password').value = '';
			document.getElementById('old_password').focus();
		break;
		/*
		case "17":
		break;*/
		
		case "18":
			document.getElementById('username').value = '';
			document.getElementById('username').focus();
		break;
	}
	document.getElementById('register-status').innerHTML = xmlData.getElementsByTagName("status")[0].childNodes[0].nodeValue;
}


/////
// To submit feedback
/////
function submit_feedback()
{
	var send_data;
	var func_to_call = submit_feedback_recieve;
	
	// Make sure there's at least a message
	if (document.getElementById('message').value == '') {
		alert("You have to at least enter a message. Just tell me what you think.");
		return;
	}
	
	// Send the data
	send_data = "action=submit_feedback&name=" + Base64.encode(document.getElementById('name').value) + 
	            "&email=" + Base64.encode(document.getElementById('email').value) + 
	            "&subject=" + Base64.encode(document.getElementById('subject').value) + 
	            "&message=" + Base64.encode(document.getElementById('message').value);
	send_cmd(send_data,"Submitting feedback.",func_to_call);
}

function submit_feedback_recieve(xmlData)
{
	// No switch() since there is no response code. 
	document.getElementById('register-status').innerHTML = xmlData.getElementsByTagName("status")[0].childNodes[0].nodeValue;
}


/////
// A function to send any arbitrary data to the server. First parameter is the data to send, second is the 'waiting' message to
// show while the status is not yet complete, the third is a pointer to a function to execute when the request is complete.
/////
function send_cmd(data,waiting_message,func_to_call)
{
   var XmlHttp;
   var msg_shown = 0;
   var p;
   var xmlData;
   
   // No response recieved yet
   response_recieved = 0;
   
   /* Open the connection. */
   // Firefox, Opera 8.0+, Safari
   try {
      XmlHttp = new XMLHttpRequest();
   }
   // Internet Explorer
   catch(e) {
      try {
         XmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e) {
         try {
            XmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
         }
         catch(e) {
            document.getElementById('status-text').innerHTML = "Sorry, your browser doesn't support AJAX so this site's notepad functionality will be unavailible to you. :-(<br />Try getting a <a href='http://getfirefox.com'>better browser</a>.";
            return false;
         }
      }
   }
   
   /*XmlHttp.open("GET","http://b-con.us/my_notepad/api.php?" + data,true);
   XmlHttp.send(null);*/   
   XmlHttp.open("POST","/api.php",true);
   XmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
   XmlHttp.setRequestHeader("Content-length",data.length);
   XmlHttp.setRequestHeader("Connection","close");
   XmlHttp.send(data);
   
   // Set the "waiting" status
   document.getElementById('progress-bar').innerHTML = "<img src='waiting.gif' height='16' width='16' alt='Waiting' />";
   if (document.getElementById('status-text'))
	   document.getElementById('status-text').innerHTML = waiting_message;
   else if (document.getElementById('register-status'))
   	document.getElementById('register-status').innerHTML = waiting_message;

   
   // Function to recieve the data
   XmlHttp.onreadystatechange = function()
   {
      // State 4 is when the response comes back. Determine if the response is good or an error
      if (XmlHttp.readyState == 4) {
         // Success
         document.getElementById('progress-bar').innerHTML = ''; //Clear the "progress bar" regardless of success
         if (XmlHttp.status == 200) {
            xmlData = XmlHttp.responseXML;
            func_to_call(xmlData);
         }
         // Show an error if the return code was not successful
         else {
            document.getElementById('status-text').innerHTML = "<b>Error: " + XmlHttp.status + "</b><br />" + XmlHttp.responseText + "<br />* Please <a href='/contact.php'>report</a> this error to the administrative staff.";
         }
      }
   }
}


/////
// Manipulate the notepad's properties
/////
function adjust_notepad_size(method,row_size,col_size)
{
	// Adjust the size of the notepad. Use the 'method' to explicitly set the absolute new size
	// or to merely increment the current size by the specified amount.
   switch (method) {
      case "set": 
      	document.getElementById('notepad').rows = row_size;
      	document.getElementById('notepad').cols = col_size;
      	if (row_size > 255)
      		document.getElementById('notepad').rows = 255;
      	if (col_size > 255)
      		document.getElementById('notepad').cols = 255;
      break;
      case "increment": 
      	document.getElementById('notepad').rows += row_size;
      	document.getElementById('notepad').cols += col_size;
      	if (document.getElementById('notepad').rows > 255)
      		document.getElementById('notepad').rows = 255;
      	if (document.getElementById('notepad').cols > 255)
      		document.getElementById('notepad').cols = 255;
      break;
   }
   document.getElementById('notepad_size_rows').innerHTML = document.getElementById('notepad').rows;
   document.getElementById('notepad_size_cols').innerHTML = document.getElementById('notepad').cols;
}

function set_font_color(color)
{
	document.getElementById('notepad').style.color = color;
	document.getElementById('font-colors').value = color;
}

function set_background_color(color)
{
	document.getElementById('notepad').style.backgroundColor = color;
	document.getElementById('background-colors').value = color;
}

function set_font_style(style)
{
	document.getElementById('notepad').style.font = style;
	/*document.getElementById('font-styles').value = style;*/
}
