	if(!com) var com = {};
	if(!com.qwidget) com.qwidget = {};

  	com.qwidget.AccountManager = { // TODO - this looks more and more like a Member object...
		memberId: com.qwidget.guestUserId, // start with a guest user
		memberEmail: undefined,
		memberPassword: undefined,
		memberLoggedIn: false,
		memberUnreadMessageCount: 0,
		postInitFunction: undefined,
		afterLoginFunction: undefined,
		logInAccount: undefined,
		createAccount: undefined,
		createPhotoAccount: undefined,
		updateAccount: undefined,
		cqq: com.qwidget.qwids,
		init: function (postInitFunction)
		{
			this.postInitFunction = postInitFunction;
			this.restore();
			this.dump();
		},
		showLogIn: function (afterLogin)
		{
			if (!this.logInAccount) this.logInAccount = new com.qwidget.LogInAccount();
			
			this.afterLoginFunction = afterLogin;
			this.logInAccount.show();
		},
		showRegister: function ()
		{
			if (!this.createAccount) this.createAccount = new com.qwidget.CreateAccount();
			
			this.createAccount.show();
		},
		showRegisterPhoto: function ()
		{
			if (!this.createPhotoAccount) this.createPhotoAccount = new com.qwidget.CreatePhotoAccount();
			
			this.createPhotoAccount.show();
		},
		showMaintain: function ()
		{
			if (!this.updateAccount) this.updateAccount = new com.qwidget.UpdateAccount();
			
			this.updateAccount.show();
		},
		qwidMap: function (qwidMap)
		{
			qwidMap[this.cqq.member_id]			= this.memberId;
			qwidMap[this.cqq.member_email]		= this.memberEmail;
			qwidMap[this.cqq.member_password]	= this.memberPassword;
		},
		resetPassword: function (email, closeDialog)
		{
			var url = com.qwidget.servicesUrl + '/member/password/reset.jsp';
			var dataOut = {
				email: email
			};
			var dataPass = {};
			var callback = function (dataIn, dataPass)
			{
				switch (dataIn.status)
				{
				 case 200:
					if (closeDialog) closeDialog();
					alert('Your password has been reset. An email with your new password has been sent.');
					break;
				 case 401:
					alert('Unable to locate a member with the email provided. Please try again or register.');
					break;
				 default:
					if (closeDialog) closeDialog();
					com.qwidget.error('AccountManager.resetPassword - unknown status: ' + dataIn.status);
					break;
				}
				com.qwidget.debug('AccountManager.resetPassword callback for ' + email);
			}
			com.qwidget.ajax(url, dataOut, dataPass, callback);
		},
		submitLogIn: function (email, password, autoLogIn, hideFunction)
		{
			var dataOut =
			{
			 	email:		email,
			 	password:	password
			};
			var dataPass = {};
			var that = this;
			var callback = function (dataIn, dataPass)
			{
				if (dataIn.status == 200) // success
				{ 
					that.unreadMessageCount(dataIn.unreadMessageCount);
					that.logIn({memberId: dataIn.memberId, memberEmail: dataIn.email, memberPassword: password}, autoLogIn);
					if (hideFunction) hideFunction();
					if (that.postInitFunction)
					{
						that.postInitFunction();
						that.postInitFunction = undefined;
					}
					if (that.afterLoginFunction)
					{
						that.afterLoginFunction();
						that.afterLoginFunction = undefined;
					}
				}
				else
				{
					that.logOut();
					if (hideFunction) alert("Unknown Email and/or Password.\n\nPlease try again."); // TODO - display the error message in the dialog
				}
				
			}
			com.qwidget.ajax(com.qwidget.servicesUrl + '/member/credentials/verify.jsp', dataOut, dataPass, callback);
		},
		logIn: function (credentials, autoLogIn)
		{
			this.memberId 				= credentials.memberId;
			this.memberEmail 			= credentials.memberEmail;
			this.memberPassword 		= credentials.memberPassword;
			this.memberLoggedIn = true;
			if (autoLogIn)
				this.save();
			else
				this.unsave();
			com.qwidget.QwidgetManager.memberLoggedIn(true);
		},
		logOut: function ()
		{
			this.clear();
			this.unsave();
			com.qwidget.QwidgetManager.memberLoggedIn(false);
		},
		isLoggedIn: function ()
		{
			return this.memberLoggedIn;
		},
		clear: function ()
		{
			this.memberId 				= com.qwidget.guestUserId;
			this.memberEmail 			= undefined;
			this.memberPassword 		= undefined;
			this.memberLoggedIn 		= false;
			this.unsave();
		},
		save: function ()
		{
		    com.qwidget.Cookie.set('credentials', JSON.stringify({memberId: this.memberId, email: this.memberEmail, password: this.memberPassword}));
		},
		unsave: function ()
		{
		    com.qwidget.Cookie.del('credentials');
		},
		restore: function ()
		{
		    var cookieString = com.qwidget.Cookie.get('credentials');
		    if (cookieString != undefined && cookieString.length)
		    {
		        eval('var cookie = '+cookieString+';');
				this.submitLogIn(cookie.email, cookie.password, true, undefined);
		    }
			else
			{
				if (this.postInitFunction)
				{
					this.postInitFunction();
					this.postInitFunction = undefined;
				}
			}
		},
		validCredentials: function ()
		{
			// TODO? - should we log in with the credentials to validate them?
			return (this.memberId && this.memberEmail && this.memberPassword && this.memberId != com.qwidget.guestUserId)
		},
		credentials: function ()
		{
			var c =
			{
				memberId: this.memberId,
				memberEmail: this.memberEmail,
				memberPassword: this.memberPassword
			};
			return c;
		},
		unreadMessageCount: function (count)
		{
			if (count != undefined)
			{
				com.qwidget.debug("com.qwidget.AccountManager.unreadMessageCount(): " + count);
				this.memberUnreadMessageCount = count < 0 ? 0 : count;
			}
			return this.memberUnreadMessageCount;
		},
		dump: function ()
		{
			var msg = "AccountManager.dump - ";
			if (this.memberLoggedIn)
			{
				msg += "id: " + this.memberId + ", email: " + this.memberEmail + ", password: " + this.memberPassword;
			}
			else
			{
				msg += " not logged in";
			}
			com.qwidget.log(msg);
		},
		deleteImage: function (callback)
		{
			var dataOut =
			{
				memberId: 	this.memberId,
			 	email:		this.memberEmail,
			 	password:	this.memberPassword
			};
			var dataPass =
			{
			};
  			com.qwidget.ajax(com.qwidget.servicesUrl + '/member/image/delete.jsp', dataOut, dataPass, callback);
		}
	};
	// com.qwidget.AccountManager.init();

	com.qwidget.AccountBase = Class.extend({
		view: undefined,
		model: undefined,
		cqq: com.qwidget.qwids,
		init: function ()
		{
		},
		createUpdatePreflight: function (qwidMap, tosRequired)
		{
			var requiredItems = [
				{qwid: this.cqq.account_displayName, description: 'Username', minLength: 4, alphaNumeric: true},
				{qwid: this.cqq.account_email, description: 'Email'},
				{qwid: this.cqq.account_password, description: 'Password'},
				{qwid: this.cqq.account_passwordConfirm, description: 'Confirm Password'}
			];
			var problemItems = '';
			// var formatItem = function (s)
			// {
			// 	(problemItems.length == 0 ? '' : '\n') + s;
			// 	return s;
			// }
			for (var i = 0; i < requiredItems.length; i++)
			{
				var item = requiredItems[i];
				if (qwidMap[item.qwid] == '')
				{
					problemItems += item.description + ' (required item)\n';
				}
				else if (item.minLength && qwidMap[item.qwid].length < item.minLength)
				{
					problemItems += item.description + ' (minimum length is ' + item.minLength + ')\n';
				}
				else if (item.alphaNumeric && !qwidMap[item.qwid].match(/^([a-zA-Z0-9]+)$/))
				{
					problemItems += item.description + ' (only letters and numbers permitted)\n';
				}
			}
			if (problemItems.length > 0)
			{
				alert('\nThere were problems with the following items:\n\n' + problemItems);
				return false;
			}
			if (tosRequired && !qwidMap[this.cqq.account_tosAgree])
			{
				alert('\nYou are required to agree to the terms of service to create an account.');
				return false;
			}
			return true;
		}
	});
	
	com.qwidget.LogInAccount = com.qwidget.AccountBase.extend({
		// view: undefined,
		// model: undefined,
		init: function ()
		{
			this.view = new com.qwidget.LogInAccountDialog(this);
		},
		show: function ()
		{
			this.view.show();
		},
		hide: function ()
		{
			this.view.hide();
		},
		submitLogIn: function ()
		{
			var qwidMap = {};
			this.view.qwidMap(qwidMap);
			com.qwidget.AccountManager.submitLogIn(qwidMap[this.cqq.account_email], qwidMap[this.cqq.account_password], qwidMap[this.cqq.account_autoLogIn], this.view.hide);
		}
	});
	com.qwidget.CreateAccount = com.qwidget.AccountBase.extend({
		// view: undefined,
		// model: undefined,
		init: function ()
		{
			this.view = new com.qwidget.CreateAccountDialog(this);
			this.model = new com.qwidget.AccountModel(com.qwidget.AccountManager.credentials(), this.view);
		},
		show: function ()
		{
			this.view.show();
			this.model.updateCredentials(com.qwidget.AccountManager.credentials());
			this.model.refresh();
		},
		createAccount: function ()
		{
			var qwidMap = {};
			this.view.qwidMap(qwidMap);
			if (this.createUpdatePreflight(qwidMap, true))
				this.model.createAccount(qwidMap);
		},
		accountCreated: function ()
		{
			this.view.hide();
			com.qwidget.AccountManager.showRegisterPhoto();
		},
		accountUpdated: function ()
		{
			this.view.hide();
		}
	});
	com.qwidget.CreatePhotoAccount = com.qwidget.AccountBase.extend({
		// view: undefined,
		// model: undefined,
		init: function ()
		{
			this.view = new com.qwidget.PhotoCreateAccountDialog(this);
			
		},
		show: function ()
		{
			this.view.show();
		}
	});
	com.qwidget.UpdateAccount = com.qwidget.AccountBase.extend({
		// view: undefined,
		// model: undefined,
		init: function ()
		{
			this.view = new com.qwidget.UpdateAccountDialog(this);
			this.model = new com.qwidget.AccountModel(com.qwidget.AccountManager.credentials(), this.view);
		},
		show: function ()
		{
			this.view.show();
			this.model.updateCredentials(com.qwidget.AccountManager.credentials());
			this.model.refresh();
		},
		updateAccount: function ()
		{
			var qwidMap = {};
			this.view.qwidMap(qwidMap);
			if (this.createUpdatePreflight(qwidMap, false))
				this.model.updateAccount(qwidMap);
		},
		accountUpdated: function ()
		{
			this.view.hide();
		},
		deleteImage: function ()
		{
			var that = this;
			com.qwidget.AccountManager.deleteImage(function () {that.model.refresh();});
		}
	});

