Login.LOGGED_IN_EVENT = 1;
Login.LOGGED_OUT_EVENT = 2;
Login.LOGIN_INIT_COMPLETE_EVENT = 3;

var isIndex;
//var eventManager;

function Login(auth_url, div_id, isIndex){
	if (typeof isIndex == 'undefined' ) isIndex = false;
	this.isIndex = isIndex;
	this.auth_url = auth_url;
	this.div_id = div_id;
	this.userName = null;
	this.userId = null;
	this.seed = null;
	this.loginImmediate = false;
	this.loginFormHTML = null;
	this.LOGIN_ACTION = "login";
	this.eventManager = new EventManager();
	this.eventManager.registerEventID(Login.LOGGED_IN_EVENT);
	this.eventManager.registerEventID(Login.LOGGED_OUT_EVENT);
	this.eventManager.registerEventID(Login.LOGIN_INIT_COMPLETE_EVENT);
}

Login.prototype.init = function() {
	var ajx = new Ajax.Request(
            this.auth_url,
            {
                method: 'post',
                parameters: 'action=get_user',
                onComplete: this.loginInitHandler.bind(this)
            });
}

Login.prototype.loginInitHandler = function(req) {
	var json_str = req.responseText;
	if(this.logger) { this.logger.info("loginInitHandler " + json_str); };
        var obj = eval('(' + json_str + ')');

	if (obj.result == 'success'){
		this.userName = obj.user;
		this.userId = obj.userId;
		this.showLoggedIn();
	} else {
		this.userName = null;
		this.userId = null;
		this.showLoginForm();
	}
	this.eventManager.triggerEvent(Login.LOGIN_INIT_COMPLETE_EVENT);

}

// The eventManager class is defined in kaMap. Could be a problem later on.
Login.prototype.addInitListener = function(obj, listenerFunc) {
	this.eventManager.registerForEvent(Login.LOGIN_INIT_COMPLETE_EVENT, obj, listenerFunc);
}

Login.prototype.removeInitListener = function(obj, listenerFunc) {
	this.eventManager.deregisterForEvent(Login.LOGIN_INIT_COMPLETE_EVENT, obj, listenerFunc);
}

// The eventManager class is defined in kaMap. Could be a problem later on.
Login.prototype.addLoginListener = function(obj, listenerFunc) {
	this.eventManager.registerForEvent(Login.LOGGED_IN_EVENT, obj, listenerFunc);
}

Login.prototype.removeLoginListener = function(obj, listenerFunc) {
	this.eventManager.deregisterForEvent(Login.LOGGED_IN_EVENT, obj, listenerFunc);
}

Login.prototype.addLogoutListener = function(obj, listenerFunc) {
	this.eventManager.registerForEvent(Login.LOGGED_OUT_EVENT, obj, listenerFunc);
}

Login.prototype.removeLogoutListener = function(obj, listenerFunc) {
	this.eventManager.deregisterForEvent(Login.LOGGED_OUT_EVENT, obj, listenerFunc);
}

Login.prototype.setLogger = function(logger){
	this.logger = logger;
}

Login.prototype.loggedIn = function(){
	if (!this.userName){
        return false;
    } else {
		return true;
	}
}

// This is ill-conceived. Alert should be handled elsewhere.
Login.prototype.isLoggedIn = function(){
	if (!this.userName){
        alert("You are not logged in. Please log in.");
        return false;
    } else {
		return true;
	}
}

Login.prototype.passwordKeyUp=function(e){
	var keyChar = e.which || e.keyCode;
	//if (this.logger) { this.logger.info("keyUp: " + keyChar ) };
	if (keyChar == 13){
	  this.sendLogin();
	}
	return true;
}

// Checks to see if we are already logged in and a few other details.
// Called when the user focuses on the user or password field after loading
Login.prototype.initForm=function(){
	// TODO Pass the name of the field in via the constructor
    if (this.logger) { this.logger.info("initForm") ; }
    var obj = this;

    if ($('login_form')){
        if ($('password')) {
            $('password').onkeyup=this.passwordKeyUp.bindAsEventListener(this);
        } else {
            if (this.logger) { this.logger.error("login form - no password field") ; }
        }
        $('username').onblur=this.getSeed.bindAsEventListener(this);
        $('login_form').onsubmit=this.sendLogin.bindAsEventListener(this);
        if(this.loginFormHTML == null){ // save the original form
            this.loginFormHTML = $(this.div_id).innerHTML;
        }
    }
}

// Ajax callback when requesting a logged in user
Login.prototype.handleInitRequest=function(req){
	var r = this.getJson(req);
	if (r.result == 'success'){
		this.userName = r.user;
		this.userId = r.userId;
		this.handleLoginSuccess();
	} else {
		$(this.div_id).innerHTML = this.loginFormHTML;
		$('password').onkeyup=this.passwordKeyUp;
	}
}

Login.prototype.getSeed=function(evt){
	if (this.logger) { this.logger.info("getSeed") };
	var obj = this;
	if(!this.seed) {
		var seedLoader = new Ajax.Request(
			this.auth_url,
			{
				method: 'post',
				parameters: "action=seed",
				onComplete: function(origReq) {
					obj.handleSeed(origReq); },
				onFailure: obj.loginError
			});
	} else {
		if (this.logger) { this.logger.info ("Existing seed id: " + this.seed.id + ", seed: " + this.seed.seed) };
	}
}

Login.prototype.handleSeed=function(origReq){
	//if (this.logger) { this.logger.info("handleSeed()") };
	try {
		this.seed = this.getJson(origReq);
	} catch(err){
		if (this.logger) { this.logger.error("Error receiving seed: " + resp); }
	}
	if (this.loginImmediate){
		this.loginImmediate = false;
		this.validateLogin();
	}
}

Login.prototype.sendLogin=function(){
	//if (this.logger) { this.logger.info("sendLogin() called") };
	retval = false;
	if (!this.seed){
		this.loginImmediate = true;
		this.getSeed();
	} else {
		this.validateLogin();
		this.seed = null;
	}

	return retval;
}



Login.prototype.validateLogin=function(){
	//if (this.logger) { this.logger.info("validateLogin() called") };
	if (this.userName != null){
		//if (this.logger) { this.logger.info("validateLogin() - already has login"); }
		return;
	}
	var temp_username = $F("username");
	var temp_password = $F("password");
	temp_password = hex_md5(temp_username + temp_password);
	//if (this.logger) { this.logger.info("seed -> " + seed.seed); }
	//if (this.logger) { this.logger.info("hex_md5(temp_username + temp_password) -> " + temp_password); }
	if (temp_username != '' && temp_password != '') {
		hash = hex_md5(temp_password + this.seed.seed);
		var params = "action=login&seedId=" + this.seed.id +
			"&hash=" + hash	+ "&userName=" + temp_username;
		//if (this.logger) { this.logger.info("login params: " + params); }
		var obj = this;
		var loginLoader = new Ajax.Request(
			this.auth_url,
			{
				method: 'post',
				parameters: params,
				onComplete: function(r) {
					obj.handleLoginResult(r); },
				onFailure: this.loginError
			});
	} else {
		alert("Empty username or password.");
	}
}

Login.prototype.showLoginForm=function(){
    $('logout').hide();
    $('login-retry').hide();
    $('login_title').show();
    $('login_form').show();
    $('login_form').onsubmit = this.sendLogin.bindAsEventListener(this);
    if ($('username')) {
        $('username').onfocus = this.initForm.bind(this);
    }
    if ($('password')) {
        $('password').onfocus = this.initForm.bind(this);
    }
}

Login.prototype.showLoggedIn = function(){
    var div = $(this.div_id);
    $('login_title').hide();
    $('login_form').hide();
    $('login-retry').hide();
    $('logout').show();
    $('login-msg').innerHTML = "Logged in as " + this.userName + ". "
}

Login.prototype.showRetry = function(){
    $('login-retry-link').onclick = this.showLoginForm.bind(this);
    $('login_title').hide();
    $('login_form').hide();
    $('logout').hide();
    $('login-retry').show();
}

Login.prototype.showLoginFormOld=function(){
    var form = document.createElement('form');
    form.style.whiteSpace="nowrap";
    form.id = 'login_form';
    form.name = 'login_form';
    form.action = this.sendLogin;
    form.style.verticalAlign = "bottom";

    var div1=document.createElement('div');
    //div1.setAttribute('align','right');
    div1.style.whiteSpace="nowrap";

    if(this.isIndex=='true'){
            div1.style.color="white";
    }
    div1.style.display="inline";
    var span = document.createElement('span');
    span.className = 'logintext';
    div1.appendChild(span);
    var txt1=document.createTextNode('Client Login ');
    span.appendChild(txt1);
    form.appendChild(div1);

    var userField = document.createElement('input');
    userField.id = 'username';
    userField.name = 'username';
    userField.type = 'text';
    userField.size = 8;
    userField.style.width = '8em';
    userField.style.verticalAlign = 'bottom';
    userField.onfocus = this.initForm.bind(this);

    form.appendChild(userField);
    //this.addBreak(form);

    var passwordField = document.createElement('input');
    passwordField.id = 'password';
    passwordField.name = 'password';
    passwordField.type = 'password';
    passwordField.size = 8;
    passwordField.style.width = '8em';
    passwordField.style.verticalAlign = 'bottom';
    passwordField.onfocus = this.initForm.bind(this);

    form.appendChild(passwordField);
    //this.addBreak(form);


    if(this.isIndex=='true'){
        var a1=document.createElement('a');
        a1.onclick=function(){login.sendLogin()};
        a1.onmouseover=function(){MM_swapImage('Image1','','images/button_go_ov.gif',1)};
        a1.onmouseout=function(){MM_swapImgRestore()};
        a1.setAttribute('href','#');
        var img1=ce('img','Image1');
        img1.setAttribute('width','22');
        img1.style.marginTop="2px";
        img1.setAttribute('height','22');
        img1.setAttribute('border','0');
        img1.setAttribute('alt','Go');
        img1.setAttribute('src','images/button_go.gif');
        img1.style.verticalAlign = "bottom";
        a1.appendChild(img1);
        form.appendChild(a1);
    } else{
        var loginLink = document.createElement('a');
        loginLink.href = '#';
        loginLink.onclick = this.sendLogin.bind(this);
        var loginText = document.createTextNode('Login');
        loginLink.appendChild(loginText);
        form.appendChild(loginLink);
    }



	//form.appendChild(fieldset);

	WU.removeChildren($(this.div_id));
	$(this.div_id).appendChild(form);

	if (this.userName != null){
		userField.value = this.userName;
        passwordField.focus();
		passwordField.select();
	} else {
		// Try the cookie
		var loginid = getCookie('loginid');
		if (loginid != null){
			userField.value = loginid;
            passwordField.focus();
			passwordField.select();
		} else {
            userField.focus();
			userField.select();
		}
	}

}

function ce(tag,name){
    if (name && window.ActiveXObject){
      element = document.createElement('<'+tag+' name="'+name+'">');
    }else{
      element = document.createElement(tag);
      element.setAttribute('name',name);
    }
    return element;
    };

Login.prototype.addBreak = function(el){
    if (this.useBreaks){
        var br = document.createElement('br');
        el.appendChild(br);
    }
}

Login.prototype.logout=function(){
	//if (this.logger) { this.logger.info("Logging out with: " + this.auth_url); }
	var logoutLoader = new Ajax.Request(
		this.auth_url,
		{
			method: 'post',
			parameters: 'action=logout',
			onComplete: this.handleLogout.bind(this),
			onFailure: this.logoutError.bind(this),
			onException: this.logoutError.bind(this)
		});
	this.userName = null;
	this.showLoginForm();
}

Login.prototype.handleLoginResult=function(req){
	//if (this.logger) { this.logger.info("handleLoginResult"); }
	try{
		var login = this.getJson(req);
		//if (this.logger) { this.logger.info("Response text: " + req.responseText);}
		if (login.result == 'fail'){
			this.handleLoginFailure();
		} else {
			//if (this.logger) { this.logger.info("Parsed Result: " + login.result + ", Username: " + login.userName); }
			this.userName = login.userName;
			this.userId = login.userId;
			this.handleLoginSuccess();
		}
	} catch (err) {
		if (this.logger) { this.logger.error("Error receiving login result. " + err + " Response:" +
			  req.responseText); }
		this.handleLoginFailure();
	}
}

Login.prototype.handleLoginSuccess=function(){
	this.showLoggedIn();
	this.eventManager.triggerEvent(Login.LOGGED_IN_EVENT);
}

Login.prototype.handleLoginFailure=function(){
	// TODO Make this use showLoginForm. Must add a login failed message.
	this.showRetry();
	// We'll need a new seed because the server deleted the old one
	this.userName = null;
	this.getSeed();
}

Login.prototype.handleLogout=function(req){
	var r = this.getJson(req);
	if (this.logger) { this.logger.info("handleLogout: " + req.responseText); }
	if (r.result != 'success') {
		alert("Logout error: " + req.responseText);
	} else {
		this.eventManager.triggerEvent(Login.LOGGED_OUT_EVENT);
	}
}

Login.prototype.getJson=function(request){
	try {
		var resp = request.responseText;
		var func = new Function("return " + resp);
		return func();
	} catch(err){
		if (this.logger) { this.logger.error("Error parsing response: " + request.responseText); }
	}
}

Login.prototype.seedError=function(){
	if (this.logger) {
		this.logger.error("error getting seed!"
			  +"\nreadyState: "+seedLoader.readyState
			  +"\nstatus: "+seedLoader.status
			  +seedLoader.getAllResponseHeaders ?
				"\nheaders: "+seedLoader.getAllResponseHeaders()
				: "");
	}
}

Login.prototype.loginError=function(req){
	if (this.logger) {
		this.logger.error("error logging in!"
			  +"\nreadyState: " + req.readyState
			  +"\nstatus: " + req.status
			  +seedLoader.getAllResponseHeaders ?
				"\nheaders: "+seedLoader.getAllResponseHeaders()
				: "");
	}
}

Login.prototype.logoutError=function(req){
	if (this.logger) {
            msg = "error logging out!"
                      +"\nreadyState: " + req.readyState
                      +"\nstatus: " + req.status
                      + req.getAllResponseHeaders ?
					  "\nheaders: " + req.getAllResponseHeaders()
					  : "";
            this.logger.error(msg);
	} else {
		alert("error logging out!");
	}
}
