/**
 * Login Module
 *
 * @author Kevin McBriraty Login dialog box
 * @dependencies DialogControl CookieUtil getUrlParam
 */
function LoginModule() {
	/** name of this module */
	this._name = LoginModule.NAME;

	this._mode = LoginModule.MODE_REFRESH_MODULES;

	this._status = false;
	this._isExternal = false;

	this._logoutPath = window.location.pathname + window.location.search;
	this._loginPath = window.location.pathname + window.location.search;

	this._sctkn = null;
	this._scgid = null;
	this._redirect = null;
	this._gameInvitor = null;

	/**
	 * called by the page during initialization
	 */
	this.initialize = function() {
		this._status = LoginModule.isUserLoggedIn();

		this._cont = $("#login_module");
		this._form = $("#login_dialogForm");
		this._submitBool = true; // used as a switch for turning off form submission while waiting for callback

		this._loginDialogControl = new DialogControl("#login_module");
		this._form.submit(bindContext(this, this.submitForm));

		$("#login_forgotPassword").click(
				bindContext(this, this._forgotPassword));
		$("#login_cancelLogin").click(bindContext(this, this._handleCancel));
		$(".login_registerLink").click(bindContext(this, this._registerLink));
	};

	this.submitForm = function(e) {
		if(this._submitBool) {
			e.preventDefault();
			this._clearErrors();
			this._disableForm();
			this._processLogin();
		}
		return false;
	};

	this.login = function(args) {

		// TODO: Remove after showdown
		// Modify message for U13 showdown users
		if ( !LoginModule.getLoggedIn() && LoginModule.getShowdownOptedIn()  )  {
			this._cont.find("p.h1").html( "Bummer!");
			this._cont.find(".dialogue_body").css("text-align","center").html( "<h2 style='margin-bottom: 20px;' >Sorry, this feature is not available for your account type.</h2><a id='login_u13ContinueButton' class='button_primary' href='#'>Continue</a>");
			$("#login_u13ContinueButton").click(bindContext(this, this._loginHide));
			this._loginDialogControl.showDialog();
			return;
		}

		if (this._gameInvitor) {
			this._cont.find("p.h1").html(
					"Log in to play against " + this._gameInvitor);
		} else if (args) {
			this._args = args;
			if (args.headerMessage) {
				this._cont.find("p.h1").html(args.headerMessage);
			}
			if (args.scoreToken) {
				this._sctkn = args.scoreToken;
			}
			if (args.gameId) {
				this._scgid = args.gameId;
			}
			if (args.redirect) {
				this._redirect = args.redirect;
			}
		}
		if (typeof g_page.useFacebook != 'undefined' && g_page.useFacebook) {
			$("#facebookLogin").show();
			$("#login_module").addClass("withFacebookWide");
		}
		this._loginDialogControl.showDialog();
	};

	/** set path to redirect when logging in */
	this.setLoginPath = function(path) {
		this._loginPath = path;
	};

	this.logout = function() {
		FB.getLoginStatus(function (response) {
			if (response.authResponse) {
				FB.logout(function() {
					var module = g_page.getModule("LoginModule");
					module._logout();
				});
			} else {
				var module = g_page.getModule("LoginModule");
				module._logout();
			}
		});
	};

	this._logout = function() {
		LoginModule.deleteCookies();
		AgEvent.LOGOUT.publish();
		this._onLogOut();

		// fire an event to the server to log the user out  
		var params = {};
		this._makeRestRequest("/user/logout", "GET", params, this._handleLogout);
	};

	this._handleLogout = function(response) {
 	};

	/** set path to redirect when loging out */
	this.setLogoutPath = function(path) {
		this._logoutPath = path;
	};

	/** set the mode */
	this.setMode = function(mode) {
		this._mode = mode;
	};

	this.notifyServiceManager = function( command, object ){
		var flash = LoginModule.getFlashObject();
		flash.notifyServiceManager(command, object);
	}

	this._onLogIn = function() {
		if (this._status == LoginModule.isUserLoggedIn()) {
			// TODO: Remove after showdown
			if ( !LoginModule.getShowdownOptedIn() ){
				return; // not a logged in and not u13 showdown user so bail
			}
			//return;
		} else {
			this._status = true;
			if (typeof(isServiceManagerEnabled) != "undefined" && isServiceManagerEnabled) {
				//var userInfo = LoginModule.getUserInfo(false, null);
				this.notifyServiceManager("LOGIN");
			}
		}

		switch (this._mode) {
		case LoginModule.MODE_REFRESH_MODULES:
			this._page.updateForLoginChange();
			break;

		case LoginModule.MODE_REDIRECT:
			if (this._loginPath) {
				window.location = "http://" + window.location.hostname
						+ this._loginPath;
			}
			break;
		}
	};

	this._onLogOut = function() {
		if (this._status == LoginModule.isUserLoggedIn()) {
			// TODO: Remove after showdown
			this._page.updateForLoginChange();
			return;
		} else {
			this._status = false;
		}
		
		switch (this._mode) {
			case LoginModule.MODE_REFRESH_MODULES:
				if (typeof(isServiceManagerEnabled) != "undefined" && isServiceManagerEnabled) {
					this.notifyServiceManager("LOGOUT");
				}
				this._page.updateForLoginChange();
				break;

			case LoginModule.MODE_REDIRECT:
				if (this._logoutPath) {
					window.location = "http://" + window.location.hostname
							+ this._logoutPath;
				}
				break;
		}
	};

	this._handleCancel = function(e) {
		//bridge pattern
		e.preventDefault();
		if (this._redirect) {
			window.location = this._redirect;
		}
		this._enableForm();
		this._loginHide();
		AgEvent.CANCEL_LOGIN.publish();
	};

	this._loginHide = function() {
		this._loginDialogControl.hideDialog();
		this._cont.find(".errorMsg").hide().html('');
	};

	this._registerLink = function(e) {
		e.preventDefault();
		this._loginHide();
		var module = g_page.getModule("RegisterModule");
		module.register(this._args);
	};

	this._processLogin = function() {
		var params = {};

		if (this._sctkn) {
			params.scoreToken = this._sctkn;
		}
		if (this._scgid) {
			params.gameId = this._scgid;
		}
		this._makeRestRequest("/user/login", "POST", params, this._handleLogin, this._form);
	};

	this._handleFieldErrors = function(obj) {
		this._clearErrors();
		for ( var fielderror in obj) {
			if (obj[fielderror].field == "reCaptchaChallenge") {
				this._callCaptcha();
			}
			this._cont
					.find(".errorMsg")
					.prepend(
							'<div class="validation-message">' + obj[fielderror].message + '</div>');
		}
		this._cont.find(".errorMsg").show();
		this._enableForm();
	};

	this._handleGeneralErrors = function(obj) {
		this._clearErrors();
		if (typeof obj == "string") {
			this._cont.find(".errorMsg").append(
					'<div class="validation-message">' + obj + '</div>');
		} else {
			for ( var generalerror in obj) {
				this._cont
						.find(".errorMsg")
						.append(
								'<div class="validation-message">' + obj[generalerror].message + '</div>');
			}
		}
		this._cont.find(".errorMsg").show();
		this._enableForm();
	};

	this._clearErrors = function() {
		this._cont.find(".errorMsg").hide().empty();
	};
	this._disableForm = function() {
		var elm = this._cont.find(".button_primary");
		// style button as disabled
		elm.addClass("button_primary_disabled");
		// disable form submit flag
		this._submitBool = false;
	};
	this._enableForm = function() {
		var elm = this._cont.find(".button_primary");
		// restore enabled button
		elm.removeClass("button_primary_disabled");
		// enable form submit flag
		this._submitBool = true;
	};

	this._callCaptcha = function() {
		$.getScript("http://api.recaptcha.net/js/recaptcha_ajax.js",
				function() {
					Recaptcha.create(
							"6Lc_SAcAAAAAAGx9bjOU-srubELeT3EyyHR5S9sp",
							"recaptcha_div", {
								theme : "red",
								callback : function() {
									Recaptcha.focus_response_field();
								}
							});
				});
	};

	this._handleLogin = function(res) {
		if (res.returnCode == "Ok") {
			if (this._redirect) {
				window.location = this._redirect;
			}
			this._onLogIn();
			this._enableForm();
			this._loginDialogControl.hideDialog();
			$("#recaptcha_div").attr("class", "").empty();
			this._reCaptchaChallenge = null;
			this._reCaptchaResponse = null;
			AgEvent.LOGIN.publish();

																		// TODO: Remove after showdown
			if ( res.response != null && !res.response.emailVerified && LoginModule.getLoggedIn() ) {
				var module = g_page.getModule("RegisterModule");
				module.register();
				module._showConfirmation();
				$("#register_module").find("p.h1").html("Please Verify Your Email");
				$("#registration_conf").find("p.confMessage1").hide();
				$("#registration_conf").find("p.confMessage2").show();
				$("#registration_conf").find(".confirmEmail").html(res.response.email);
			}
		}
	};

	this._forgotPassword = function(e) {
		e.preventDefault();
		this._clearErrors();
		$("#login_password_fail").hide().empty();
		var params = {
			"username" : $("#login_usernameEmail").val()
		};
		this._makeRestRequest("/user/sendPassword", "POST", params,
				this._handlePasswordReminder);
	};
	this._handlePasswordReminder = function(res) {
		if (res.returnCode == "Ok") {
			this
					._handleGeneralErrors("An email has been sent to the account you signed up with. Please check this e-mail for your password.");
		}
	};

	/** @return list of request actions that can be handled by this module */
	this.getPageActionNames = function() {
		return [ "showLoginPopup" ];
	};
	/**
	 * handle request action
	 *
	 * @action name of action to invoke
	 * @params bean containing request parameters
	 *
	 */
	this.handlePageAction = function(action, params) {
		if (action == "showLoginPopup") {
			this._sctkn = $(document).getUrlParam("sctkn");
			this._scgid = $(document).getUrlParam("scgid");
			this._redirect = $(document).getUrlParam("redirect");
			this._gameInvitor = $(document).getUrlParam("gameInvitor");
			this.login();
		}
	};

}
LoginModule.NAME = "LoginModule";

LoginModule.prototype = new Module();
LoginModule.loginCookie = new CookieUtil();
LoginModule.hostname = window.location.hostname;
LoginModule.index = LoginModule.hostname.indexOf(".");
LoginModule.DOMAIN = LoginModule.hostname.substr(LoginModule.index);

LoginModule.MODE_REDIRECT = "redirect";
LoginModule.MODE_REFRESH_MODULES = "refreshModules";

LoginModule.USER_UUID_SESSION_COOKIE = "aguseruuidsc";
LoginModule.USER_ID_SESSION_COOKIE = "aguseridsc";
LoginModule.USER_NAME_SESSION_COOKIE = "agusername";
LoginModule.USER_EMAIL_SESSION_COOKIE = "aguseremail";
LoginModule.FACEBOOK_SESSION_COOKIE = "aguserfacebookid";
LoginModule.FACEBOOK_ONLY_SESSION_COOKIE = "aguserfacebookonly";
LoginModule.FACEBOOK_SESSION_NAME_COOKIE = "aguserfacebookname";
LoginModule.FACEBOOK_SESSION_AUTO_PUBLISH_COOKIE = "aguserfacebookautopublish";
LoginModule.FACEBOOK_IS_PROXY_EMAIL = "aguserfacebookisproxyemail";
LoginModule.FACEBOOK_FRIEND_AUTO_CONNECT = "aguserfriendautoconnect";

// TODO: Remove after showdown
LoginModule.LOGGED_IN = "loggedIn";
LoginModule.SHOWDOWN_OPTED_IN = "showdownOptedIn";


LoginModule.deleteCookie = function(key) {
	LoginModule.loginCookie.cookie(key, "", {
		domain : LoginModule.DOMAIN,
		expires : 0,
		path : "/"
	});
};

// TODO: Remove after showdown
LoginModule.getLoggedIn = function() {
	return LoginModule.loginCookie.cookie(LoginModule.LOGGED_IN);
};

// TODO: Remove after showdown
LoginModule.getShowdownOptedIn = function() {
	return LoginModule.loginCookie.cookie(LoginModule.SHOWDOWN_OPTED_IN);
};

LoginModule.getSessionUserUuid = function() {
	return LoginModule.loginCookie.cookie(LoginModule.USER_UUID_SESSION_COOKIE);
};

LoginModule.getUserId = function() {
	return LoginModule.loginCookie.cookie(LoginModule.USER_ID_SESSION_COOKIE);
};

LoginModule.getSessionUsername = function() {
	return LoginModule.loginCookie.cookie(LoginModule.USER_NAME_SESSION_COOKIE);
};

LoginModule.getSessionUserEmail = function() {
	return LoginModule.loginCookie.cookie(LoginModule.USER_EMAIL_SESSION_COOKIE);
};

LoginModule.getSessionFacebookId = function() {
	var facebookId = LoginModule.loginCookie.cookie(LoginModule.FACEBOOK_SESSION_COOKIE);
	var fbId = 0;
	if (facebookId) {
		fbId = facebookId;
	} else {
		fbId = com.ag.loginFB.uid;
	}
	// console.log("fb: " + fbId + ",cookie: " + facebookId);
	return fbId;
};

LoginModule.getSessionFacebookOnly = function() {
	return LoginModule.loginCookie
			.cookie(LoginModule.FACEBOOK_ONLY_SESSION_COOKIE);
};

LoginModule.getSessionFacebookIsProxyEmail = function() {
	return LoginModule.loginCookie
			.cookie(LoginModule.FACEBOOK_IS_PROXY_EMAIL);
};

LoginModule.getSessionFacebookName = function() {
	return LoginModule.loginCookie
			.cookie(LoginModule.FACEBOOK_SESSION_NAME_COOKIE);
};

LoginModule.getSessionFacebookHasAutoPublish = function() {
	return LoginModule.loginCookie
			.cookie(LoginModule.FACEBOOK_SESSION_AUTO_PUBLISH_COOKIE);
};

LoginModule.showLogin = function(args) {
	var module = g_page.getModule("LoginModule");
	module.login(args);
};
LoginModule._loginHide = function () {
	var module = g_page.getModule("LoginModule");
	module._loginHide();
}
LoginModule.getSessionFacebookFriendAutoConnect = function() {
	return LoginModule.loginCookie
	.cookie(LoginModule.FACEBOOK_FRIEND_AUTO_CONNECT);
};
LoginModule.isUserLoggedIn = function() {
	var sessionuuid = LoginModule.getSessionUserUuid();
	return sessionuuid != null && sessionuuid.length > 0;
};
LoginModule._onLogIn = function() {
	var module = g_page.getModule("LoginModule");
	module._onLogIn();
};
LoginModule.setLoginPath = function(path) {
	var module = g_page.getModule("LoginModule");
	module.setLoginPath(path);

};
LoginModule.deleteCookies = function() {
	LoginModule.deleteCookie(LoginModule.USER_UUID_SESSION_COOKIE);
	LoginModule.deleteCookie(LoginModule.USER_ID_SESSION_COOKIE);
	LoginModule.deleteCookie(LoginModule.USER_NAME_SESSION_COOKIE);
	LoginModule.deleteCookie(LoginModule.USER_EMAIL_SESSION_COOKIE);
	LoginModule.deleteCookie(LoginModule.FACEBOOK_SESSION_COOKIE);
	LoginModule.deleteCookie(LoginModule.FACEBOOK_ONLY_SESSION_COOKIE);
	LoginModule.deleteCookie(LoginModule.FACEBOOK_SESSION_NAME_COOKIE);
	LoginModule.deleteCookie(LoginModule.FACEBOOK_SESSION_AUTO_PUBLISH_COOKIE);
	LoginModule.deleteCookie(LoginModule.FACEBOOK_FRIEND_AUTO_CONNECT);

	// TODO: Remove after showdown
	// these two get set with no domain from java services
	LoginModule.loginCookie.cookie(LoginModule.LOGGED_IN, "", {
		domain : "",
		expires : 0,
		path : "/"
	});LoginModule.loginCookie.cookie(LoginModule.SHOWDOWN_OPTED_IN, "", {
		domain : "",
		expires : 0,
		path : "/"
	});
};

/**
 * Calls the specified callback function with the following user info: userId, userUUID, userName, userEmail
 * or returns nulls if the user is not logged in.  If requiresLogin is true, prompts for login first if not already logged in
 * @param requiresLogin boolean indicating whether or not to prompt the user to login if they are not logged in already
 * @param callbackFunctionName name of a function to call on the Flash object with userId, userUUID, userName and userEmail of the logged in user as parameters - or with nulls
 */
LoginModule.getUserInfo = function( requiresLogin, callbackFunctionName ) {

	// If the user is currently logged in, just return a userInfo object to the caller; no need to execute the callback function
	if ( LoginModule.isUserLoggedIn() || !requiresLogin ) {
		return LoginModule.returnUserInfo();

	// Otherwise spawn login screens
	} else {

		// Subscribe the callback function to the login/register events
		AgEvent.LOGIN.subscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );
		AgEvent.CANCEL_LOGIN.subscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );
		AgEvent.REGISTER.subscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );
		AgEvent.CANCEL_REGISTER.subscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );

		// Spawn the login screen
		LoginModule.showLogin();
	}
};

// jenkinsb 20100707

LoginModule.returnUserInfo = function ( callbackFunctionName ) {

	// Unsubscribe future login/register events from this callback
	AgEvent.LOGIN.unsubscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );
	AgEvent.CANCEL_LOGIN.unsubscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );
	AgEvent.REGISTER.unsubscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );
	AgEvent.CANCEL_REGISTER.unsubscribe( function() { LoginModule.returnUserInfo( callbackFunctionName ); } );

	var userInfo = {
		"signedInState": (LoginModule.isUserLoggedIn()) ? "SignedInStandard" : "NotSignedIn",
		"signedInStateCode": (LoginModule.isUserLoggedIn()) ? "SIS" : "NSI",
		"memberId": LoginModule.getUserId(),
		"uuId": LoginModule.getSessionUserUuid(),
		"email": LoginModule.getSessionUserEmail(),
		"screenName": LoginModule.getSessionUsername(),
		"fbId": LoginModule.getSessionFacebookId()
	};

	// If a callback function name was provided, send the userInfo back to that
	if ( typeof callbackFunctionName != 'undefined' ) {
		var flash = LoginModule.getFlashObject();

		eval("flash." +  callbackFunctionName + "( userInfo );" );

	// Otherwise just return the userInfo to the caller
	} else {
		return userInfo;
	}
};

LoginModule.getFlashObject = function() {
	var flashId = "FlashContent";  // REQUIRES flash game to have this ID

	// For IE
	if ( ! jQuery.support.opacity ) {
		return document.getElementById( flashId );
	// For other browsers
	} else {
		return eval( "document." + flashId );
	}
};

// shim object for new highscores implementation
com.ag.gameServices = {};
com.ag.gameServices.getUserInfo = LoginModule.getUserInfo;
