function watchitoo_OnLoginFailed( type, msg, options ) {
	alert(msg);
}

function loginAPI() {
	this.username = "";
	this.nickname = "";
	this.certificate = "";
	this.accountType = 'Temporary';
	this.avatarURL = "";

	this.objState = "loggedOut"; //loggedOut or loggedIn or sending
	
	this.messagingServer = false;
	
	this.cookieName = "WatchitooLogin";
	this.guid = 0;
	this.cookieData = null;
	
	this.bIsLoggedIn = false;
	this.bWriteToCookie = true;
	this.baseURL = "";
	
	if (baseURL != "undefined" && (typeof baseURL) != "undefined") {
		this.baseURL = baseURL;
		////console.log('BaseURL undefined.');
	}
	this.init();
}

/**
 * init function - should initalize the login object, check for existing for cookies.
 * if cookies exists then process a login request.
 */
loginAPI.prototype.init = function() {
	//console.log('loginAPI init()');
	//console.lotg(location.href);
	this.guid = this.GenerateUniqueGUID();
	
	//check for cookies
	this.ReadCookieData();
	if (this.cookieData != null && this.cookieData.length > 0 && this.cookieData[1].length==10 && this.cookieData[0] != null) {
		if (this.objState != "sending") {			
			this.getMessagingServer(this.cookieData[0]);
			this.loginUsingCertificate(this.cookieData[0],this.cookieData[1], this.cookieData[4]);
		}
		
	} else { // can remove the else statment from production
		this.eraseCookie(this.cookieName);
		this.onStateChange("loggedOut");
	}
	
	this.waitForLogin();
}

loginAPI.prototype.login = function(settings) {
	//username being an email address
	//if (console) console.log('login function running - u: '+settings.username+",p: "+settings.password);
	
	// encrypt password
	var ciphertext = des(userKey, settings.password, 1, 0);
	pass = userKey + stringToHex(ciphertext);
	this.getMessagingServer(settings.username);
	return this.processLogin(settings.username, pass, settings.remember);
	
}

/**
	processLogin(username,password) - return true upon a successul login or false otherwise;
*/
loginAPI.prototype.processLogin = function (username,password, remember) {
	//console.log("processLogin: "+username+","+password);
	if (this.messagingServer == undefined || this.version == undefined) { return false; }//if missing any one of these
	this.onStateChange("sending");
	$('#signin').append('<img src="images/ajax-loader.gif" id="loader" style="margin-bottom: 8px; margin-left: 4px;" align="center" />');
	var requestFile = this.baseURL + "proxy/" +this.messagingServer+'/messages_'+this.version+'/loginUser.php';
	var obj = this; //scope
	var certificate = "";
	var jsonResult = null;
	var failedLoginTriggered = false;
	$.ajax({
		url: requestFile,
		type: "GET",
		async: false,
		dataType: "json",
		data: { userID: username, password: password },
		error : function (xhr, textStatus, errorThrown) {
			$('#loader').remove();
			obj.onStateChange('loggedOut');
			if (xhr.responseText.indexOf("</WResult>") > 0) { //catch xml errors again - stupid IE.
					xmlDoc = obj.loadXML(xhr.responseText);
					x = xmlDoc.childNodes[0].childNodes;
					errorCode = x[1].childNodes[0].firstChild.nodeValue;
					errorDesc = x[1].childNodes[1].firstChild.nodeValue;
					obj.onLoginFailed(errorCode, errorDesc);
					failedLoginTriggered = true;
			} else {
				obj.onError(xhr, textStatus);
			}
			
			
		},
		success: function(responseText) {
					$('#loader').remove();
					if (((typeof responseText) == 'xml') || (((typeof responseText) == 'string') && (responseText.indexOf("</WResult>") > 0))) {
						xmlDoc = obj.loadXML(responseText.toString()); 
						x = xmlDoc.childNodes[0].childNodes;
						//type node x[1].nodeName;
						responseType = x[1].firstChild.nodeValue; //should be error
						//code node x[3].childNodes[1].nodeName
						//descriptio node x[3].childNodes[3].nodeName
						if (responseType == 'Error') {
							errorCode = x[3].childNodes[1].firstChild.nodeValue;	
							errorDescription = x[3].childNodes[3].firstChild.nodeValue;
							obj.onLoginFailed(errorCode, errorDescription);
							failedLoginTriggered = true;
						} else {
							obj.onLoginFailed(0, 'Unknown Response');
							failedLoginTriggered = true;
						}
					} else {
						//console.log("JSON Found");
						jsonResult = responseText;
						certificate = responseText[1];
					}
			   }
	});
	
	if (certificate.length == 10 && jsonResult[0] != null) {
		//console.log('Certificate is the correct length. '+certificate);
		//set object variables
		this.bIsLoggedIn = true;
		this.certificate= certificate;
		this.username=jsonResult[0];
		
		this.accountType = jsonResult[5];
		this.nickname = jsonResult[2];
		this.avatarURL = jsonResult[4];

		// write the cookie data
		this.WriteCookieData(remember);
		
		//startGettingMessages
		//this.getMessages(); setinterval
		//trigger login event
		this.onStateChange("loggedIn");
		this.onLogin();
		return true;
	} else {
		//console.log('Certificate has wrong length. '+certificate);
		this.bIsLoggedIn = false;
		//if onLoginFailed was already triggered by the response
		if (!failedLoginTriggered) this.onLoginFailed(0, 'Certificate wrong length');
		this.onStateChange("loggedOut");
		return false;
	}
}

loginAPI.prototype.getMessagingServer = function(username) {
	var obj = this; //scope
	$.ajax({
		async: false,
		cache: false,
		dataType: "json",
		type: "POST",
		data: { user: username },
		success: function(data, textStatus) {
			if (data['error'] == undefined) {
				obj.messagingServer = data['server'];
				obj.version = data['version'];
			} else {
				obj.onLoginFailed(0, 'Couldn\'t find user');
			}
		},
		error: function(XHR, textStatus, errorThrown) {
			obj.onError(XHR, textStatus);
		},
		url: this.baseURL + "ajax/getUserLoginServer.php"
	});
}

/**
 * loginUsingCertificate also log's in the the user base on the certificate in the cookie
 * it starts by sending a async ajax call to verify the certificate and if passed
 * moves on to set the object variables.
 */
loginAPI.prototype.loginUsingCertificate = function(username, certificate, remmber) {
	//console.log("loginUsingCertificate: "+username+","+certificate);
	this.onStateChange("sending");
	$('#signin').append('<img src="images/ajax-loader.gif" id="loader" style="margin-bottom: 8px; margin-left: 4px;" align="center" />'); //why is this not working?!
	var requestFile = this.baseURL + "moc/dbaseRoutines/validateCertificate.php";
	var obj = this; //for scope
	var responseText = "";
	$.ajax({
		url: requestFile,
		type: "GET",
		async: true, //change to false if cause problems 
		dataType: "json",
		data: { userID: username, certificate: certificate },
		error : function (xhr, textStatus, errorThrown) {
			$('#loader').remove();
			obj.onStateChange('loggedOut');
			obj.onError(xhr, textStatus);
		},
		success: function(json) {
					$('#loader').remove();
					if (json != "0") {
						//console.log('responseText: '+json);
						obj.bIsLoggedIn = true;
						obj.username = json[0];	
						obj.nickname = json[1];
						obj.certificate = json[2];
						obj.accountType = json[5];
						obj.avatarURL = json[4];
						if (obj.bWriteToCookie) {
							obj.WriteCookieData(remmber);
						}
						obj.onStateChange("loggedIn");
						obj.onLogin(); //trigger onlogin event
					} else {
						obj.eraseCookie(obj.cookieName); // temporary fix to research bug - will remove later
						obj.cookieData = null;
						//obj.onLoginFailed(106, 'Security certificate invalid(JS)');
					}
			   }
	});
}

/**
 * Return the user info from the login object as a object
 */
loginAPI.prototype.getUserInfo = function() {
	return {
		username: this.username,
		nickname: this.nickname,
		certificate: this.certificate,
		avatarURL: this.avatarURL,
		accountType: this.accountType
	};
}

/**
 * Change the email address in the login object and the cookie - should be called when a user changes his email address
 */

loginAPI.prototype.changeEmail = function(toEmail) {
	/**
	 * TODO: Implement this function 
	 */
}

loginAPI.prototype.logout = function() {
	//console.log('logout function running');
	if (this.messagingServer == undefined || this.version == undefined) { return false; }
	this.onStateChange("sending");
	var obj = this; //for scope
	var requestFile = this.baseURL + "proxy/" +this.messagingServer+'/messages_'+this.version+'/logoutUser.php';
	$('#signout').append('<img src="images/ajax-loader.gif" id="loader" style="margin-bottom: 8px; margin-left: 4px;" align="center" />'); //why is this not working?!
	$.ajax({
		url: requestFile,
		type: "GET",
		async: true,  
		data: { userID: this.username, certificate: this.certificate },
		error : function (xhr, textStatus, errorThrown) {
			$('#loader').remove();
			obj.onStateChange('loggedIn');
			obj.onError(xhr, textStatus);
		},
		success: function(responseText) {
					$('#loader').remove();
					if (responseText == "0") {
						obj.username = "";
						obj.nickname = "";
						obj.certificate = "";
						obj.accountType = 'Temporary';
						obj.avatarURL = "";
						obj.guid = 0;
						obj.bIsLoggedIn = false;
						obj.eraseCookie(obj.cookieName);
						obj.cookieData = null;
						obj.onStateChange("loggedOut");
						obj.onLogout(); //trigger logout even
					} else { //can remove later.
						//console.log('Did not log out out');
					}
			   }
	});
}

loginAPI.prototype.waitForLogin = function() {
	//var d = new Date();
	//console.log("waitingForCookie"+d.getTime());
	this.ReadCookieData();
	if (this.cookieData != null && ((this.accountType != this.cookieData[3]) || (this.username != this.cookieData[0]))) { //account usernames types don't match
		//console.log('something doesn\'t match');
		if (this.cookieData != null && this.cookieData.length > 0 && this.cookieData[1].length==10) {
			//console.log('trying to log in according to new cookies');
			if (this.objState != "sending") {
					this.loginUsingCertificate(this.cookieData[0],this.cookieData[1]);
			}
		} else {
			//console.log('something is wrong with the new cookies');
		}
	}
	
	//if object remains in state of loggedIn but the cookies were deleted
	//from another windows
	if (this.cookieData == null && this.bIsLoggedIn) { 
		this.logout();
	}
	// else {
		//console.log('everything matches');
	//}
	var obj = this; //for scope
	setTimeout(function() { obj.waitForLogin(); },1000);
}

loginAPI.prototype.isLoggedIn = function() {
	return this.bIsLoggedIn;
}

/** returns the state of the object */
loginAPI.prototype.getState = function() {
	return this.objState;
}

/** Event methods */

loginAPI.prototype.onLogin = function() {
	watchitoo_OnLogin(this.username, this.nickname, this.certificate, this.accountType); 
}

loginAPI.prototype.onLogout = function() {
	watchitoo_OnLogout();
}

loginAPI.prototype.onLoginFailed = function(errorCode, description) {
	watchitoo_OnLoginFailed(errorCode, description);
}

loginAPI.prototype.onStateChange = function(state) {
	//console.log("state change to: "+state);
	this.objState = state;
	watchitoo_OnStateChange(this.objState);
}

loginAPI.prototype.onError = function(xhr, text) {
	watchitoo_OnError(text);
}

loginAPI.prototype.onMessage = function() {
	
}

loginAPI.prototype.onEmailChanged = function() {
	
}

/** Cookie Helpers **/

loginAPI.prototype.createCookie = function(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

loginAPI.prototype.readCookie = function (name) {
	//console.log('readCookie Running');
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}


loginAPI.prototype.eraseCookie = function(name) {
	this.createCookie(name,"",-1);
}

	
loginAPI.prototype.ReadCookieData=function() {
		//console.log('ReadCookieData running');
		// if failed reading cookie just make sure cookieData is null and return;
		var cookieAsString = this.readCookie(this.cookieName);//'login');
		if(cookieAsString==null||cookieAsString.length==0)
		{
			this.cookieData=null;
			return;
		}
		if(this.cookieData==null)
			this.cookieData=new Array();
		// split the cookie data into an array
		this.cookieData = cookieAsString.split(",");
		
		//We get this as a string
		if(this.cookieData[4]=='true')
			this.cookieData[4] = true;
}
	
loginAPI.prototype.WriteCookieData=function( remember ) {
		if(this.bWriteToCookie==false)
			return;

		// make sure username & certificate are set
		var cookieString=this.username;
		cookieString+=',';
		cookieString+=this.certificate;
		cookieString+=',';
		cookieString+=this.guid;
		cookieString+=',';
		cookieString+=this.accountType;
		cookieString+=',';
		cookieString+=remember;

		var time = 0;
		if(remember==true || remember=='true')
			time = 7;

		var retVal=this.createCookie(this.cookieName,cookieString,time);//'login',cookieString);
		var cookieAsString=this.readCookie(this.cookieName);//'login');	
}
/** Other Helpers **/
loginAPI.prototype.loadXML = function(text) {
	try { //Internet Explorer  
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(text);
	} catch(e) {
		try { //Firefox, Mozilla, Opera, etc.
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(text,"text/xml");
		} catch(e) {alert(e.message)}
	}
	return xmlDoc;
}

loginAPI.prototype.GenerateUniqueGUID = function() {
	var g = "";
	var i = 0;
	for (i=0; i<10; i++) {
		var random_number = Math.floor(Math.random() * 10);
		g += random_number.toString();
	}
	return g;
}

loginAPI.prototype.validateForm = function(form) {	
	var username = form.username.value;
	var password = form.pwd.value;
	
	var bPassed = false;
	
	if (username.length == 0) {
		$('#errorMessage').text('Please enter a username');
	} else if (password.length == 0) {
		$('#errorMessage').text('Please enter a password');
	} else if (!this.validEmail(username)) {
		$('#errorMessage').text('Invalid email address');
	} else { 
		bPassed = true; 
		//console.log('passed!');
	}
	
	if (bPassed) {
		//console.log('validate form complete - moving to login');
		this.login({username: username, password: password});
	}
	
	//if validation passed - invoke the login function
	
	return false;
}

loginAPI.prototype.validEmail = function(email) {
	var invalidChars = " /:;,";
	if (email == "") { return false; } 
	for (var k=0; k < invalidChars.length; k++) {
		var badChar = invalidChars.charAt(k);
		if (email.indexOf(badChar) > -1) { return false; }
	}
	var atPos = email.indexOf("@", 1);
	if (atPos == -1) { return false; }
	if (email.indexOf("@", atPos+1) != -1) { return false; }
	var periodPos = email.indexOf(".",atPos);
	if (periodPos == -1) { return false; }
	if (periodPos+3 > email.length) { return false; }
	return true;
}