/* 
 * McomSSOUser class to store user data
 */
function McomSSOUser(userName, passwordHash, fullName, active) {
	
	/*
     * *** member properties ***
     */
     
	this.userName 		= null;
	this.passwordHash 	= null;
	this.fullName 		= null;
	this.active         = null;
	this.avatarUrl      = null;
		
	//set member properties from parameters
	if (userName && userName != "") { 		
	                                        this.userName 		= userName;
	                                        this.avatarUrl      = ssoConfig.ssoAvatarUrlPattern.replace(/{username}/g, this.userName);
	}
	if (passwordHash && passwordHash != "") this.passwordHash 	= passwordHash;
	if (fullName && fullName != "")		    this.fullName 		= fullName;
	this.active         = (active) ? true : false;
	
}


/* 
 * OAuthUser class to store user data
 */
function OAuthUser(id, userName, firstName, lastName, token) {
    /*
     * *** member properties ***
     */
     
	this.id 		= null;
	this.userName 	= null;
	this.firstName 	= null;
	this.lastName 	= null;
	this.token	    = null;
	this.avatarUrl  = null;
		
	//set member properties from parameters
	if (id 	        && id != "") {		    
	                                        this.id 		    = id;
	                                        this.avatarUrl      = ssoConfig.oAuthAvatarUrlPattern.replace(/{id}/g, this.id);
	}
	if (userName    && userName != "") 	    this.userName 	    = userName;
	if (firstName   && firstName != "") 	this.firstName 	    = firstName;
	if (lastName    && lastName != "") 	    this.lastName 	    = lastName;
	if (token       && token != "") 	    this.token 	        = token;
}



/* 
 * class providing access to the medienhaus.com SSO
 */
function McomSSO(contentTargets, useOAuth) {

    var that = this;

    /*
     * *** member properties ***
     */
    this.showActiveForm = null;                         //a reference to a method showing the active form/dialogue that needs to be displayed
    this.formPreference = null;                         //a reference to a method showing the form/dialogue that is preferred by the user via his click action
    this.handleErrors   = null;                         //a reference to an error handler for the active form/dialogue
    this.ssoUser        = null;                         //holds an active McomSSOUser if logged in
    this.oAuthUser      = null;                         //holds an active OAuthUser if logged in 
    this.useOAuth       = (useOAuth) ? true : false;    //wether to allow OAuth-Connectivity or not
    this.isTriggered    = false;                        //marks if there is an actively triggered login process
    this.contentTargets = contentTargets;               //reference to an array of jquery selectors used to show user status information
    this.connectionMode = 'connect'                     //mode of connection: either user registers new McomSSOUser or user connects to existing one
    
    
    
    /*
     * *** privileged public member methods *** 
     */
     
    /*
     * read the user data from the SSOSessionCookie 
     * returns a McomSSOUser or null
     */
    this.readSSOCookie = function () {
    
        var ssoCookie = null;           //cookie data
        var ssoUser = null;             //McomSSOUser object to be returned
        
        var ssoCookieValues = null;     //array to hold all key/value pairs read from ssoCookie
        var ssoUserName = null;         //username read from ssoCookie
		var ssoPasswordHash = null;     //password hash (token) read from ssoCookie
		var ssoFullName = null;         //full name read from ssoCookie
		var ssoActive = null;           //active/inactive status read from ssoCookie
		
		
		//get the sso cookie
        ssoCookie = that.getCookie('SsoSessionCookie');
        //no cookie? let's get outa here!
        if (ssoCookie == null) return null;	
        
        //read the ssoCookie content into an array via split on '&'
        ssoCookieValues = ssoCookie.split(/\&/);
        
        //cycle through ssoCookieValues array
        for (var i = 0; i < ssoCookieValues.length; i++) {
            //create an array holding the current key/value pair via split on '='
            var value = ssoCookieValues[i].split(/\=/);
            if (value[0] == 'username') {
                ssoUserName     = value[1].replace(/ /, '\\20');
            }
			if (value[0] == 'passwordhash') {
			    ssoPasswordHash = value[1] + '==';
            }
            if (value[0] == 'fullname')	{
			    ssoFullName		= decodeURI(value[1]).replace(/\+/g,' ');
            }
			if (value[0] == 'active') {
			    ssoActive       = (value[1] == 'True') ? true : false;
            }
        }
        
        //create new instance of McomSSOUser if the cookie states him as active and not guest
		if (ssoUserName != 'guest') {
			ssoUser = new McomSSOUser(ssoUserName, ssoPasswordHash, ssoFullName, ssoActive);
		}
		return ssoUser;
    } 
     
     
     
    /*
     * grabs a cookie with a given name
     * returns the cookie content or null
     */
    this.getCookie = function (cookiename) {
    
        var searchphrase = cookiename + "=";    //seachphrase to look for in document.cookie
        var i=0;                                //incremental counter for search document.cookie
        var cook = null;                        //the result which will be returned
        while (i < document.cookie.length) {
				if (document.cookie.substring(i, i + searchphrase.length) == searchphrase){
					 var end = document.cookie.indexOf(";", i + searchphrase.length);
					 end = (end > -1) ? end : document.cookie.length;
					 cook = unescape(document.cookie.substring(i + searchphrase.length, end));
				}
				i++;
		 }
		return cook;
    }
    
    /*
     * public callback method to do action after the oAuthLoginStatus has been checked
     */
    this.onOAuthGetLoginStatus = function (response, isTriggered) {
        that.isTriggered = isTriggered;
     

        switch (response.status) {  
            case 'connected':
                //user is already logged in via oAuth and has authorized our app - cool, isn' it?
                
                // ask the oAuth api and set the oAuthUser
                // @todo for future release: we might need to be able to use api's other than facebook
                if (typeof(FB.api) !== 'undefined') {
                    FB.api('/me', function(response) {
                        var oAuthCookie = null;         //cookie data
                        var oAuthCookieValues = null;   //array to hold all key/value pairs read from oAuthCookie
                        var oAuthToken = null;          //token read from oAuthCookie
                        
                        //read the oAuthCookie to retrieve the token
                        oAuthCookie = that.getCookie('fbs_' + ssoConfig.oAuthAppId);
                        oAuthCookie = oAuthCookie.replace(/\"/g, '');
                        oAuthCookieValues = oAuthCookie.split(/\&/);
                        for (var i = 0; i < oAuthCookieValues.length; i++) {
                            var value = oAuthCookieValues[i].split(/\=/);
                            if (value[0] == 'access_token') oAuthToken 	= value[1];      
                        }
                        
                        
                        if (oAuthToken != null) {
                            //set the oAuthUser if we got everything
                            that.oAuthUser = new OAuthUser(response.id, response.name, response.first_name, response.last_name, oAuthToken);
                            
                            //check the local connection via webservice
                            //we wil only do something if nobody is logged in
                            if (that.ssoUser == null || that.ssoUser.active == false){
                                $.ajax({               
                                    url: ssoConfig.ssoServicePath + ssoConfig.ssoServiceOAuthCheckConnectionMethod,
                                    data: { facebookProfileId: that.oAuthUser.id, facebookAppId: ssoConfig.oAuthAppId },
                                    success: that.onOAuthCheckConnection,
                                    dataType: "xml"
                                });
                            }
                                                                               
                        }
                        
                    });
                }
            break;
            default:
                //user is not logged in via oAuth or has not authorized our app  
                that.oAuthUser = null;
                //toggle the login form as active form
                that.showActiveForm = that.showLoginForm;
                
            break; 
        }
     }
     
     
    /*
     * public callback method to do action after the oAuthConnection has been checked
     */
    this.onOAuthCheckConnection = function(data, textStatus, xmlHttpRequest) {
        var connectedUserName;  //the username of the local connected McomSSOUser
        
        connectedUserName = $(data).children("string").text()
        //either we have local connection yet or not
        
        
        if (connectedUserName == '') {
                  
        
            //we did not store any connection in our local sso for this oAuthUser
            // - so the connect form or the register form needs to be toggled as active form
            if (that.ssoUser != null && that.ssoUser.active == false) {
                // - if we have a user that recently logged out (SSOSessionCookie is there, but inactive)
                // we show a connect form
                that.showActiveForm = that.showOAuthConnectForm
            } else {
                // - otherwise we show a registration form
                that.showActiveForm = that.showOAuthRegisterForm;
            }
            
            //check form preferences on basis of what button the user clicked
            // - if user clicked a login-style button, he might already have a local user account
            //   - show the connect form
            // - if user clicked a registration style button, he might not have a local user account
            //   - show the registration form
            if (that.formPreference != null) {
                that.showActiveForm = that.formPreference;
            }
            
            
            
            
            
            //if the user is activily trigering this process, we want actual show the form
            if(that.isTriggered) {
                that.showActiveForm();
            }
            
        } else {
            //maybe our user is already logged in locally?
            if (that.ssoUser != null && that.ssoUser.active == true && that.ssoUser.userName == connectedUserName) {
                //@todo: I am not sure if that really can be the case here - do nothing for the moment
            } else {
                //let's try to log the user in locally!
                that.authenticateViaOAuthToken();                
            }
        }
        
    }
    
    
    
    /*
     * authenticates an existing McomSSOUser with credentials
     */ 
    this.authenticateViaCredentials = function(ssoUserName, ssoPassword, ssoKeepLoggedIn) {
        
        try {
        $.ajax({
            url: ssoConfig.ssoServicePath + ssoConfig.ssoServiceSSOLoginMethod,
            data: {user: ssoUserName, pass: ssoPassword, bKeepLoggedIn: ssoKeepLoggedIn },
            success: that.onAuthenticateViaCredentials, 
            dataType: "xml"
        });
        }
        catch (e) {
            //alert("Login failed!");  	
        }
        
    }
     
    /*
     * public callback method to do action after authenticateViaCredentials has been called
     */
    this.onAuthenticateViaCredentials = function (data, textStatus, xmlHttpRequest) {
        
        authenticatedUserName = $(data).find('user > user-name').text();
        if (authenticatedUserName != '') {
            //login successfull, reload page
            location.reload();
        } else {
            //handle errors
            that.handleErrors(data);
        }
        
    } 
    
    
    /*
     * login an active OAuthUser user using his OAuthToken
     */
    this.authenticateViaOAuthToken = function() {
        if (that.oAuthUser != null) {
            $.ajax({               
                url: ssoConfig.ssoServicePath + ssoConfig.ssoServiceOAuthLoginMethod,
                data: { facebookProfileId: that.oAuthUser.id, facebookAppId: ssoConfig.oAuthAppId, authToken: that.oAuthUser.token},
                success: 
                        function(data, textStatus, XMLHttpRequest) {
                            if (data.getElementsByTagName("user")[0]) {
                                //login successfull
                                location.reload();
                            }
                        },
                dataType: "xml"
            });
        }
    }
    
     
     
    /*
     * authenticates an existing McomSSOUser with credentials and connects to a given OAuthUser
     */ 
    this.authenticateForOAuthConnection = function(ssoUserName, ssoPassword, ssoKeepLoggedIn) {
        
        try {
        $.ajax({
            url: ssoConfig.ssoServicePath + ssoConfig.ssoServiceOAuthSetConnectionMethod,
            data: {user: ssoUserName, pass: ssoPassword, facebookProfileId: that.oAuthUser.id, facebookAppId: ssoConfig.oAuthAppId , bKeepLoggedIn: ssoKeepLoggedIn },
            success: that.onAuthenticateForOAuthConnection, 
            dataType: "xml"
        });
        }
        catch (e) {
            //alert("Login failed!");  	
        }
    }
    
    
    /*
     * public callback method to do action after authenticateForOAuthConnection has been called
     */
    this.onAuthenticateForOAuthConnection = function(data, textStatus, xmlHttpRequest) {
        
        returnCode = $(data).children("int").text()
        
        if (returnCode == '1') {
            // login and connection successfull, show preferences dialogue
            // - get the local sso user if available
            that.ssoUser = that.readSSOCookie();
            
            // - show the preferences dialogue
            that.showActiveForm = that.showOAuthPreferencesForm;
            that.showActiveForm();
        }
        else {
            //handle errors
            that.handleErrors(data);
        }
        
    }
    
    
    /*
     * register a new McomSSOUser and connect with a given OAuthUser
     */
    this.registerForOAuthConnection = function(ssoUserName, ssoPassword, ssoFirstName, ssoLastName, ssoEmail, ssoMarketing, ssoTermsAndConditions) {
        
        try {
            $.ajax({
                url: ssoConfig.ajaxServicePath + ssoConfig.ajaxServiceSignUpMethod,
                data: {username: ssoUserName, password: ssoPassword, firstname: ssoFirstName, lastname: ssoLastName, email: ssoEmail, marketing: ssoMarketing, termsandconditions: ssoTermsAndConditions, fbid: that.oAuthUser.id, fbtoken: that.oAuthUser.token},
                success: that.onRegisterForOAuthConnection,
                dataType: "json"
            });
        }
        catch (e) {
            alert("SignUp failed: " + e);  	
        }
        
    }
    
    
    /*
     * public callback method to do action after authenticateForOAuthConnection has been called
     */
    this.onRegisterForOAuthConnection = function(data, textStatus, xmlHttpRequest) {
        if (data.errors == null && data.user != null) {
            // registration and connection successfull, show preferences dialogue
            // - get the new sso user from the response data
            
            that.ssoUser = new McomSSOUser(data.user.username, data.user.password, data.user.fullname, data.user.active);
            
            // - show the preferences dialogue
            that.showActiveForm = that.showOAuthPreferencesForm;
            that.showActiveForm();
            
        } else {
            //handle errors
            that.handleErrors(data);
        }
    }
    
    
    /*
     * set preferences of the connected McomSSOUser (avatar image only at the moment)
     */
    this.setOAuthPreferences = function (oAuthUseAvatar) {
        switch (oAuthUseAvatar) {
            case 'true':
                try {
                    $.ajax({
                        url: ssoConfig.ajaxServicePath + ssoConfig.ajaxServiceSetIconMethod,
                        data: {username: that.ssoUser.userName, password: that.ssoUser.passwordHash, fbid: that.oAuthUser.id, fbtoken: that.oAuthUser.token},
                        success: that.onSetOAuthPreferences,
                        dataType: "json"
                    });
                }
                catch (e) {
                    //alert("setOAuthPreferences failed."); 
                    $.modal.close();
                    location.reload(); 	
                }
                
                break;
                
            default:
                $.modal.close();
                location.reload();
                break;
        }
    }
    
    /*
     * public callback method to do action after setOAuthPreferences has been called
     */
    this.onSetOAuthPreferences = function (data) {
        // show the confirmation dialogue
        that.showActiveForm = that.showOAuthConfirmationForm;
        that.showActiveForm();
    }
    
    /*
     * close confirmation dialogue and reload page
     */
    this.confirmConnection = function () {
        //in any case: let's get outa here
        $.modal.close();
        location.reload();
    }
    
    
    /*
     * logout the user
     */
    this.logout = function () {
	
		if (that.useOAuth && that.oAuthUser != null) {
		    FB.logout(function(response) {
                try {
                    $.ajax({
                        url: ssoConfig.ssoServicePath + ssoConfig.ssoServiceSSOLogoutMethod,
                        success: that.onLogout, 
                        dataType: "xml"
                    });
                }
                catch (e) {
                    alert("Logout failed!");  	
                }
		    });
		}
		else {
	        try {
                $.ajax({
                    url: ssoConfig.ssoServicePath + ssoConfig.ssoServiceSSOLogoutMethod,
                    success: that.onLogout, 
                    dataType: "xml"
                });
            }
            catch (e) {
                alert("Logout failed!");  	
            }
		}
    }
    
    /*
     * public callback method to do action after logout has been called
     */
    this.onLogout = function(data) {

        //in any case: let's get outa here
        $.modal.close();

        if (ssoConfig.redironlogout != undefined) {
            window.location = ssoConfig.redironlogout;
        } else {
            location.reload();
        }
    }
    
    
    /*
     * display the login form
     */
    this.showLoginForm = function () {

        // 1. check on possible prerequisites (i.e. user needs to be logged out)
        // - assign the correct error handler
        that.handleErrors = that.handleLoginFormErrors;
        // - remove any error messages
        $('#McomSSOLoginForm .SSOFieldMessage').text('');
        $('#McomSSOLoginForm .SSOFieldMessage').hide();
        
        // @todo
        
        // 2. close all other modal windows
        $.modal.close()

        // 3. attach submit/click events on the proper elements
        // attach click event on the OAuthLoginButton
        $('#McomSSOLoginForm #OAuthLoginButton').unbind();
        $('#McomSSOLoginForm #OAuthLoginButton').click( function () {
            FB.login(function(response) {
                //call the onOAuthGetLoginStatus method as
                that.onOAuthGetLoginStatus(response, true);
            //}, {perms:'email'});
            });
        });
        // attach submit event to login form
        $('#McomSSOLoginForm').unbind();
        $('#McomSSOLoginForm').submit( function () {
            that.authenticateViaCredentials($('#SSOUserLogin').val(), $('#SSOPasswordLogin').val(), document.getElementById('SSOKeepLoggedInLogin').checked);
            return false;
         });
        
        // 4. use simplemodal to display a prerendered dialog in modal window
        $('#McomSSOLoginForm').modal({
	        zIndex: 5001
        });
    }
    
    /*
     * error handler for showLoginForm
     */
    this.handleLoginFormErrors = function (returnData) {
         // first: remove any possible old error messages
        $('#McomSSOLoginForm .SSOFieldMessage').text('');
        $('#McomSSOLoginForm .SSOFieldMessage').hide();
    
        // display standard error
        $('#McomSSOLoginForm .SSOFieldMessage').text(ssoConfig.ssoLoginErrorMessage);
        $('#McomSSOLoginForm .SSOFieldMessage').addClass('Error');
        $('#McomSSOLoginForm .SSOFieldMessage').removeClass('Success');
        $('#McomSSOLoginForm .SSOFieldMessage').show();
    }
    
    
    /*
     * display the form to connect an active OAuthUser user with an existing McomSSOUser
     */
    this.showOAuthConnectForm = function () {
        // 1. check on possible prerequisites (i.e. OAuthUser needs to be active)
        // - assign the correct error handler
        that.handleErrors = that.handleOAuthConnectFormErrors;
        // - assign the correct connectionMode
        that.connectionMode = 'connect';
        // - remove any error messages
        $('#McomOAuthConnectForm .SSOFieldMessage').text('');
        $('#McomOAuthConnectForm .SSOFieldMessage').hide();
        // @todo
        
        // 2. close all other modal windows
        $.modal.close()
        
        // 3. prefill some form fields and placeholder
        // set avatar image
        $('#McomOAuthConnectForm .OAuthAvatar').attr('src', that.oAuthUser.avatarUrl);
        // set user fullname for salutation
        $('#McomOAuthConnectForm .OAuthUsername').text($('#McomOAuthConnectForm .OAuthUsername').text().replace(/{username}/g, that.oAuthUser.userName));;
        
        // 4. attach submit/click events on the proper elements
        // attach submit event to the form
        $('#McomOAuthConnectForm').unbind();
        $('#McomOAuthConnectForm').submit(function () {
            that.authenticateForOAuthConnection($('#SSOUserConnect').val(), $('#SSOPasswordConnect').val(), document.getElementById('SSOKeepLoggedInConnect').checked);
            return false;
        });
        
        // attach click event to the #SSORegisterConnect link
        $('#SSORegisterConnect, #SSORegisterTopConnect').unbind();
        $('#SSORegisterConnect, #SSORegisterTopConnect').click(function () {
            that.showOAuthRegisterForm();
            return false;
        });

        // 5. use simplemodal to display a prerendered dialog in modal window
        $('#McomOAuthConnectForm').modal({
	        zIndex: 5001
        });
    }
    
    /*
     * error handler for showOAuthConnectForm
     */
    this.handleOAuthConnectFormErrors = function (returnData) {
         // first: remove any possible old error messages
        $('#McomOAuthConnectForm .SSOFieldMessage').text('');
        $('#McomOAuthConnectForm .SSOFieldMessage').hide();
    
        // display standard error
        $('#McomOAuthConnectForm .SSOFieldMessage').text(ssoConfig.ssoLoginErrorMessage);
        $('#McomOAuthConnectForm .SSOFieldMessage').addClass('Error');
        $('#McomOAuthConnectForm .SSOFieldMessage').removeClass('Success');
        $('#McomOAuthConnectForm .SSOFieldMessage').show();
    }
    
    
    /*
     * display the form to register an new McomSSOUser and connect it with an active OAuthUser
     */    
    this.showOAuthRegisterForm = function () {
        
        // 1. check on possible prerequisites (i.e. OAuthUser needs to be active)
        // - assign the correct error handler
        that.handleErrors = that.handleOAuthRegisterFormErrors;
        // - assign the correct connectionMode
        that.connectionMode = 'register';
        // - remove any error messages
        $('#McomOAuthRegisterForm .SSOFieldMessage').text('');
        $('#McomOAuthRegisterForm .SSOFieldMessage').hide();
        //@todo
        
        // 2. close all other modal windows
        $.modal.close()
        
        // 3. prefill some form fields and placeholder
        //set avatar image
        $('#McomOAuthRegisterForm .OAuthAvatar').attr('src', that.oAuthUser.avatarUrl);
        //set user fullname for salutation
        $('#McomOAuthRegisterForm .OAuthUsername').text($('#McomOAuthRegisterForm .OAuthUsername').text().replace(/{username}/g, that.oAuthUser.userName));
        //prefill #SSOFirstNameSignUp formfield
        $('#SSOFirstNameSignUp').val(that.oAuthUser.firstName);
        //prefill #SSOLastNameSignUp formfield
        $('#SSOLastNameSignUp').val(that.oAuthUser.lastName);
        
        
        // 4. attach submit/click events on the proper elements
        // attach submit event to the form
        $('#McomOAuthRegisterForm').unbind();
        $('#McomOAuthRegisterForm').submit(function () {
            that.registerForOAuthConnection($('#SSOUserSignUp').val(), $('#SSOPasswordSignUp').val(), $('#SSOFirstNameSignUp').val(), $('#SSOLastNameSignUp').val(), $('#SSOEmailSignUp').val(), document.getElementById('SSOMarketingSignUp').checked, document.getElementById('SSOTermsAndConditionsSignUp').checked);
            return false;
        });
        
        //attach click event to the #SSORegisterConnect link
        $('#SSOLoginSignUp, #SSOLoginTopSignUp').unbind();
        $('#SSOLoginSignUp, #SSOLoginTopSignUp').click(function() {
            that.showOAuthConnectForm();
            return false;
        });
        
        //atach blur/keydown events to the input fields for validation
        $('#SSOFirstNameSignUp, #SSOLastNameSignUp, #SSOEmailSignUp, #SSOPasswordSignUp').unbind();
        $('#SSOFirstNameSignUp, #SSOLastNameSignUp, #SSOEmailSignUp, #SSOPasswordSignUp').blur(function() {
            inputField = this;
            that.validateOAuthRegisterForm(inputField.id);
        });
        
        $('#SSOUserSignUp').unbind();
        $('#SSOUserSignUp').keydown(function(e) {
            inputField = this;           
            if (that.isValidChar(e)) {
                that.validateOAuthRegisterForm(inputField.id);
                return true;
            }
            return false;
        });
        
        // 5. use simplemodal to display a prerendered dialog in modal window
        $('#McomOAuthRegisterForm').modal({
	        zIndex: 5001
        });
        //set focus on #SSOEmailSignUp formfield
        $('#SSOEmailSignUp').focus();
    }
    
    
    /*
     * validation handler for showOAuthRegisterForm
     */
    this.validateOAuthRegisterForm =  function (fieldId) {
        switch(fieldId) {
            case 'SSOFirstNameSignUp':
                that.validateName(fieldId);
                break;
            case 'SSOLastNameSignUp':
                that.validateName(fieldId);
                break;
            case 'SSOEmailSignUp':
                that.validateEmail(fieldId);
                break;
            case 'SSOUserSignUp':
                that.validateUser(fieldId);
                break;
            case 'SSOPasswordSignUp':
                that.validatePassword(fieldId);
                break;
        }
    }
    
    /*
     * validation handler firstname/lastname
     */
    this.validateName = function (fieldId) {
    
        fieldNode = $('#' + fieldId);
        msgNode = $('#' + fieldId).closest('fieldset').find('p.SSOFieldMessage');
    
        if (fieldNode.val().replace(/ /g, "") != '') {
            msgNode.text(ssoConfig.validateOk);
            
            msgNode.addClass('Success');
            msgNode.removeClass('Error');
            
            msgNode.show();
        } else {
            msgNode.text(ssoConfig.validateSSOInputRequired);
            
            msgNode.addClass('Error');
            msgNode.removeClass('Success');
            
            msgNode.show();
        }
    }
    
    /*
     * validation handler email
     */
    this.validateEmail = function (fieldId) {
        fieldNode = $('#' + fieldId);
        msgNode = $('#' + fieldId).closest('fieldset').find('p.SSOFieldMessage');
        descNode = $('#' + fieldId).closest('fieldset').find('p.SSOFieldDescription');
        
        emailFilter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        
        if (fieldNode.val().search(emailFilter) > -1) {
            msgNode.text(ssoConfig.validateOk);
            
            msgNode.addClass('Success');
            msgNode.removeClass('Error');
            
            descNode.hide();
            msgNode.show();
        } else {
            msgNode.text(ssoConfig.validateEmailNotValid);
            
            msgNode.addClass('Error');
            msgNode.removeClass('Success');
            
            descNode.hide();
            msgNode.show();
        }
    }
    
    /*
     * validation handler username
     */
    this.validateUser = function (fieldId) {
        if (that.availabilityTimeout != 0) {
			window.clearTimeout(that.availabilityTimeout);
		}
		that.availabilityTimeout = window.setTimeout(function() {
		    that.checkUsername(fieldId);
		},500);
    }
    

    /*
     * validation handler username - helper that checks on valid key input
     */
    that.isValidChar = function (e) {
    	var key;
	    var isCrtl = false;
	    var isShift = false;

	    if (window.event) {
		    key = e.keyCode;
		    isCrtl = window.event.crtlKey;
		    isShift = window.event.shiftKey;
	    } else if (e.which) {
		    key = e.which;
		    isCrtl = e.crtlKey;
		    isShift = e.shiftKey;
	    }

	    return ((key == 35 || key == 36 || key == 37 || key == 39 || key == 9 || key == 8 || key == 46) || // navigation items
			    (key >= 65 && key <= 90) || // a-z|A-Z
			    (!isShift && key >= 48 && key <= 57) || // 0-9
			    key == 109 || key == 95 || key == 189 // -_
		       );
    }


    
    /*
     * validation handler username - helper that checks, if the username is still available
     */
    that.checkUsername = function (fieldId) {
        
        fieldNode = $('#' + fieldId);
        msgNode = $('#' + fieldId).closest('fieldset').find('p.SSOFieldMessage');
        descNode = $('#' + fieldId).closest('fieldset').find('p.SSOFieldDescription');
        
        if (fieldNode.val().search(/[^A-Za-z0-9\_\-]/) > -1 || fieldNode.val() == '' || fieldNode.val().length < 4 || fieldNode.val().length > 32) {
            msgNode.text(ssoConfig.validateUsernameNotValid);
            
            msgNode.addClass('Error');
            msgNode.removeClass('Success');
            
            descNode.hide();
            msgNode.show();
            return;
        } else {
            msgNode.text(ssoConfig.validateChecking);
            
            msgNode.removeClass('Error');
            msgNode.removeClass('Success');
            
            descNode.hide();
            msgNode.show();
            
            
            $.post(ssoConfig.ssoServicePath + ssoConfig.ssoServiceSSOPublicProfileMethod,
                {'user':fieldNode.val(),'caller':''},
                function(response) {
				    if (response.indexOf('SnpeWebServiceError') > -1) {                       
                        msgNode.text(ssoConfig.validateOk);
                        
                        msgNode.addClass('Success');
                        msgNode.removeClass('Error');
                        
                        descNode.hide();
                        msgNode.show();
				    } else {                        
                        msgNode.text(ssoConfig.validateUsernameNotValid);
                        
                        msgNode.addClass('Error');
                        msgNode.removeClass('Success');
                        
                        descNode.hide();
                        msgNode.show();
				    }
			    }, 'text');
            
        }
    }
    
    /*
     * validation handler password
     */
    this.validatePassword = function (fieldId) {
        fieldNode = $('#' + fieldId);
        msgNode = $('#' + fieldId).closest('fieldset').find('p.SSOFieldMessage');
        descNode = $('#' + fieldId).closest('fieldset').find('p.SSOFieldDescription');
        
        if (fieldNode.val().replace(/ /g, "").length >= 6) {
            msgNode.text(ssoConfig.validateOk);
            
            msgNode.addClass('Success');
            msgNode.removeClass('Error');
            
            descNode.hide();
            msgNode.show();
        } else {
            msgNode.text(ssoConfig.validatePasswordTooShort);
            
            msgNode.addClass('Error');
            msgNode.removeClass('Success');
            
            descNode.hide();
            msgNode.show();
            
        }
    }
    
    /*
     * error handler for showOAuthRegisterForm
     */
    this.handleOAuthRegisterFormErrors = function (returnData) {
        // first: do the javascript validation       
        that.validateOAuthRegisterForm('SSOFirstNameSignUp');
        that.validateOAuthRegisterForm('SSOLastNameSignUp');
        that.validateOAuthRegisterForm('SSOEmailSignUp');
        that.validateOAuthRegisterForm('SSOUserSignUp');
        that.validateOAuthRegisterForm('SSOPasswordSignUp');

        
        if (returnData.errors.length > 0) {
            var msgNode = null;
            var descNode = null;
        
            // cycle through the errors array and display each error at the correspondent field
            for (var i = 0; i < returnData.errors.length; i++) {
                if (returnData.errors[i].field != null) {
                    switch (returnData.errors[i].field) {
                        case "firstname":
                            msgNode = $('#McomOAuthRegisterForm .SSOFirstNameSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOFirstNameSignUp .SSOFieldDescription');
                            break;
                        case "lastname":
                            msgNode = $('#McomOAuthRegisterForm .SSOLastNameSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOLastNameSignUp .SSOFieldDescription');
                            break;
                        case "email":
                            msgNode = $('#McomOAuthRegisterForm .SSOEmailSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOEmailSignUp .SSOFieldDescription');
                            break;
                        case "username":
                            msgNode = $('#McomOAuthRegisterForm .SSOUserSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOUserSignUp .SSOFieldDescription');
                            break;
                        case "password":
                            msgNode = $('#McomOAuthRegisterForm .SSOPasswordSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOPasswordSignUp .SSOFieldDescription');
                            break;
                        case "marketing":
                            msgNode = $('#McomOAuthRegisterForm .SSOMarketingSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOMarketingSignUp .SSOFieldDescription');
                            break;
                        case "termsandconditions":
                            msgNode = $('#McomOAuthRegisterForm .SSOTermsAndConditionsSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOTermsAndConditionsSignUp .SSOFieldDescription');
                            break;
                        //take the last field as default
                        default:
                            msgNode = $('#McomOAuthRegisterForm .SSOTermsAndConditionsSignUp .SSOFieldMessage');
                            descNode = $('#McomOAuthRegisterForm .SSOTermsAndConditionsSignUp .SSOFieldDescription');
                            break;
                    }
                } else {
                    //general error
                    //take the last field as fallback
                    msgNode = $('#McomOAuthRegisterForm .SSOTermsAndConditionsSignUp .SSOFieldMessage');
                    descNode = $('#McomOAuthRegisterForm .SSOTermsAndConditionsSignUp .SSOFieldDescription');
                }
                
                msgNode.text(returnData.errors[i].msg);
                
                msgNode.addClass('Error');
                msgNode.removeClass('Success');
                
                descNode.hide();
                msgNode.show();
            }
        }
        
        
        
    }

    /*
     * display the form to set preferences of the connected McomSSOUser (avatar image only at the moment)
     */    
    this.showOAuthPreferencesForm = function () {
    
        // 1. check on possible prerequisites (i.e. OAuthUser needs to be active)
        //@todo
        
        // 2. close all other modal windows
        $.modal.close()
    
        
        // 3. prefill some form fields and placeholder
        //set user fullname for salutation
        $('#McomOAuthPreferencesForm .OAuthUsername').text($('#McomOAuthPreferencesForm .OAuthUsername').text().replace(/{username}/g, that.oAuthUser.userName));
        //set OAuthAvatar image src
        $('#McomOAuthPreferencesForm .OAuthAvatar').attr('src', that.oAuthUser.avatarUrl);
        //set SSOAvatar image src
        $('#McomOAuthPreferencesForm .SSOAvatar').attr('src', that.ssoUser.avatarUrl.replace(/{size}/g, 'small'));
        
        
        // 4. attach submit/click events on the proper elements
        // atach click events to the avatar images
        $('#McomOAuthPreferencesForm .OAuthAvatarChooser img, #McomOAuthPreferencesForm .OAuthAvatarChooser label').unbind();
        $('#McomOAuthPreferencesForm .OAuthAvatarChooser img, #McomOAuthPreferencesForm .OAuthAvatarChooser label').click(function () {
            $('#OAuthPreferenceOAuthUseAvatar').val('true');
            $('#McomOAuthPreferencesForm .SSOAvatar').removeClass('Active');
            $('#McomOAuthPreferencesForm .OAuthAvatar').addClass('Active');
        });
        
        $('#McomOAuthPreferencesForm .SSOAvatarChooser img, #McomOAuthPreferencesForm .SSOAvatarChooser label').unbind();
        $('#McomOAuthPreferencesForm .SSOAvatarChooser img, #McomOAuthPreferencesForm .SSOAvatarChooser label').click(function () {
            $('#OAuthPreferenceOAuthUseAvatar').val('false');
            $('#McomOAuthPreferencesForm .OAuthAvatar').removeClass('Active');
            $('#McomOAuthPreferencesForm .SSOAvatar').addClass('Active');
        });
        
        // attach submit event to the form
        $('#McomOAuthPreferencesForm').unbind();
        $('#McomOAuthPreferencesForm').submit(function () {
            that.setOAuthPreferences($('#OAuthPreferenceOAuthUseAvatar').val());
            return false;
        });
        
        // 5. use simplemodal to display a prerendered dialog in modal window
        $('#McomOAuthPreferencesForm').modal({
	        zIndex: 5001
        });
        
    }
    
    /*
     * display a confirmation dialogue to the user depending on wether a new user or an existing user was connected
     */ 
    this.showOAuthConfirmationForm = function () {
        // 1. check on possible prerequisites (i.e. OAuthUser needs to be active)
        // - assign the correct error handler
        //@todo
        // - remove any error messages
        //@todo
        
        // 2. close all other modal windows
        $.modal.close()
        
        // 3. show the correct message
        if (that.connectionMode == 'register') {
            $('#McomOAuthConfirmation .RegistrationComplete').show();
            $('#McomOAuthConfirmation .ConnectionComplete').hide();
        } else {
            $('#McomOAuthConfirmation .RegistrationComplete').hide();
            $('#McomOAuthConfirmation .ConnectionComplete').show();
        }
        
        // 4. attach submit/click events on the proper elements
        // attach submit event to the form
        $('#McomOAuthConfirmation').unbind();
        $('#McomOAuthConfirmation').submit(function () {
            that.confirmConnection();
            return false;
        });
        
        // 5. use simplemodal to display a prerendered dialog in modal window
        $('#McomOAuthConfirmation').modal({
	        zIndex: 5001
        });
        
        
    }
    
    
    /*
     * display user status information
     */  
    this.displayUserStatus = function () {
        //if logged in, try to show username, icon etc.
        if (that.ssoUser != null && that.ssoUser.active) {
            
            // fill user info nodes
            $(that.contentTargets.userName).text(that.ssoUser.fullName);
            $(that.contentTargets.profileLink).attr('href', ssoConfig.ssoProfileUrlPattern.replace(/{username}/, encodeURI(that.ssoUser.userName)));
            $(that.contentTargets.profileAvatar).attr('src', that.ssoUser.avatarUrl.replace(/{size}/g, 'tiny'));
        
            // hide content fragment for login functionality
            $(that.contentTargets.fragmentLoggedOut).hide();
            // show content fragment for logout functionality
            $(that.contentTargets.fragmentLoggedIn).show();
        } else {
            // hide content fragment for logout functionality
            $(that.contentTargets.fragmentLoggedIn).hide();
            // show content fragment for login functionality
            $(that.contentTargets.fragmentLoggedOut).show();
        }
    }
    
    
    /*
     * *** private member methods *** 
     */
    
    
    /*
     * initialize everything 
     */
    var ssoInitialize = function () {
        //get the local sso user if available
        that.ssoUser = that.readSSOCookie();   
        
        //check on oAuthConnectionStatus if enabled
        if (useOAuth && typeof(FB.getLoginStatus) !== 'undefined') {
             FB.getLoginStatus(function(response) {
                that.onOAuthGetLoginStatus(response);
            });
        }
        
        //per default the login form is our default form
        that.showActiveForm = that.showLoginForm;
        
        //set event handlers
        // - login button
        if (typeof(that.contentTargets.loginButton) !== 'undefined') {
            $(that.contentTargets.loginButton).unbind();
            $(that.contentTargets.loginButton).click(function () {
                that.showActiveForm();
                return false;
            });
        } 
        
        // - short-cut to OAuthConnectForm
        if (typeof(that.contentTargets.showOAuthConnectButton) !== 'undefined') {
            $(that.contentTargets.showOAuthConnectButton).unbind();
            $(that.contentTargets.showOAuthConnectButton).click( function () {
                FB.login(function(response) {
                    that.formPreference = that.showOAuthConnectForm;
                    that.onOAuthGetLoginStatus(response, true);
                });
            });
        } 
        
        // - short-cut to OAuthRegisterForm
        if (typeof(that.contentTargets.showOAuthRegisterButton) !== 'undefined') {
            $(that.contentTargets.showOAuthRegisterButton).unbind();
            $(that.contentTargets.showOAuthRegisterButton).click( function () {
                FB.login(function(response) {
                    that.formPreference = that.showOAuthRegisterForm;
                    that.onOAuthGetLoginStatus(response, true);
                });
            });
        }
        
        
        
        // - logout button
        if (typeof(that.contentTargets.logoutButton) !== 'undefined') {
            $(that.contentTargets.logoutButton).unbind();
            $(that.contentTargets.logoutButton).click(function () {
                that.logout();
                return false;
            });
        }
        
        // - try to show user status
        that.displayUserStatus();
        
    }
    
    
    
    
    /*
     * *** stuff done on construction ***
     */
     
     ssoInitialize();
     
}






