/*
Class: 		Social Exchange Communication Tool (soXc)

Note: 	    The Detail Box requires an XHTML doctype.

Arguments:
        element 	- The container for soXc
        options 	- see Options below

Options:
		uDetail		- Holds user details for use within soXc
*/

var JSONP_Request = com.thenextspark.lib.sparktools.JSONP_Request;

var soXc = new Class({

    submitDetails: true,
    regProcess: 1,
    objectDetails: null,

    options: {
        signUp: Class.empty,
        signOut: Class.empty,
        uDetail: null,
        container: null,
        termsLink: null,
        objectID: 7,
        objectLabels: null,
        agentDetails: null,
        agentProfile: '',
        signUpSubmission: '',
        userUpdate: '',
        SOXComs: '',
        checkEmail: '',
        access: '',
        changePassword: '',
        emailSubjects: null,
        agentPic: '',
        activitiesText: '',
        forgottenPasswordURI: ''   //Used for the Forgotten Password Link
    },
    initialize: function(el, options) {
        this.setOptions(options);

	    // Validate required options
	    if (!el) {
	        throw new Error (
	            "container must be supplied to SoXc Panel"
	        );
		}

        this.options.container = $(el);
        if (this.uDetails()) this.user = this.options.uDetail;

		//Here we are initiating each of the modules required for the SoXc panel.
		this.initUser();
        this.initLogPanels();
        // this.initUser();
        this.initRegister();
        this.initAgents();

        this.initFooter();

        // if(window.supersleight) window.supersleight.limitTo('soxc');
    },
    /**
	*	Start of Action Box / User Profile Specific Functionality
	*
	*	Profile...
	* 	This panel is used as the SoXc header.
	*
	*	HTML Structure
	*	<div id="pd">
	*		<a href="#" class="signIn">Sign In</a>
	*	</div>
	*
	*/
    initLogPanels: function() {
        if (!this.pd) this.pd = new Element('div', { 'id': 'pd' }).injectTop(this.options.container);

        this.pd.empty();

        if (this.uDetails() == null) {
            if (this.pd.hasClass('loggedIn')) this.pd.removeClass('loggedIn');
            this.logTxt = new Element('a', { 'href': '#' }).setHTML('Sign In').addClass('signIn').injectInside(this.pd).onclick = this.openAB.bind(this, [this.logIn, 'signInLink']);
        } else {
            this.pd.addClass('loggedIn');
            this.logTxt = new Element('a', { 'href': '#' }).setHTML('Log Out').addClass('logOut').injectInside(this.pd).onclick = this.actionLogOut.bind(this);
            this.welTxt = new Element('span', { 'class': 'logName' }).setHTML('Hi <strong>' + this.uName().capitalize() + '</strong>').injectInside(this.pd).onclick = this.openProfile.bind(this, 'false'); ;

        }
    },
	/**
	*	Action Box...working title?
	*
	* 	This panel is the main container for all user interaction.
	*	It allows the user to;
	*   	Current
	*    		Sign In,
	*   		Sign Up
	*   		Update User Details
	*   		Be informed of available activities
	*
	*   	Future
	*   		Update Preferences
	*   		...
	*
	*	HTML Structure
	*	 <ul class="menu current">
	*   	<li id="signUpLink" class="signIn">Sign up</li>
	*   	<li class="signIn extra">or</li>
	*   	<li id="signInLink" class="signIn current">Sign in</li>
	*   </ul>
	*   <div id="ab">
	*   	<form id="signUp">
	*   		<div id="step01">
	*   			<div class="stepGuide"><!-- Form Intro Text --></div>
	*   			<div class="stepForm"><!-- Form Fields --></div>
	*   		</div>
	*   		<div id="step02" class="none">
	*   			<div class="stepGuide clearfix"><!-- Form Intro Text --></div>
	*   			<div class="stepForm"><!-- Form Fields --></div>
	*   			<div class="finishProfile"><!-- Form Notifiers and Sign Up Submit button --></div>
	*   		</div>
	*   	</form>
	*   	<form id="logIn" name="logIn">
	*   		<div class="stepGuide clearfix"><!-- Form Intro Text --></div>
	*   		<div class="stepForm"><!-- Form Fields --></div>
	*   	</form>
	*   </div>
	*
	*/
    initUser: function() {
        if (!this.abMenu) {
            this.abMenu = new Element('ul').addClass('menu').addEvents({ mouseenter: this.highlightAB.bind(this, true), mouseleave: this.highlightAB.bind(this, false) }).injectInside(this.options.container);
            this._abwrapper = new Element('div').injectInside(this.options.container);
            this.ab = new Element('div', { 'id': 'ab' }).addEvents({ mouseenter: this.highlightAB.bind(this, true), mouseleave: this.highlightAB.bind(this, false) }).injectInside(this._abwrapper);
        }
        this.abMenu.empty();
        this.ab.empty();

        this.ab.getParent().getStyle('height').toInt();

        if (this.uDetails() == null) {
            //This side of the if statement is building the Action Box for a none logged user.

			this.ab.removeProperty('style');
            this.ab.getParent().removeProperty('style');
			//Form to hold the Sign Up process.
            this.signUp = new Element('form', { 'id': 'signUp', 'name': 'signUp', 'action': this.options.signUpSubmission, 'method': 'get' }).injectInside(this.ab);

			//Form to hold the Sign In process.
			this.logIn = new Element('form', { 'id': 'logIn', 'name': 'logIn' }).addClass('none').injectInside(this.ab);

			//Creating the elements for the Action Box Menu
            this.abMenu.addClass('current');
            this.signUpLink = new Element('li', { 'id': 'signUpLink' }).setHTML('Sign up').addClass('signIn current').injectInside(this.abMenu).onclick = this.openAB.bind(this, [this.signUp, 'signUpLink']);
            this.signExtra = new Element('li').setHTML('or').addClass('signIn extra').injectInside(this.abMenu);
            this.signInLink = new Element('li', { 'id': 'signInLink' }).addClass('signIn').setHTML('Sign in').injectInside(this.abMenu).onclick = this.openAB.bind(this, [this.logIn, 'signInLink']);

			//Step 01 of the Sign Up Process.
			//The user enters a email address which is in then checked on the
			//next button to see if it exists in database
            this.step1 = new Element('div', { 'id': 'step01' }).injectInside(this.signUp);
            this._stepHold = new Element('div').addClass('stepGuide clearfix').injectInside(this.step1);
            this.step1Title = new Element('p').setHTML('Sign up to MySelection').injectInside(this._stepHold);
            this.step1guide = new Element('span', { 'class': 'steps' }).setHTML('Step 1 of 2').injectInside(this._stepHold);

            this.step1Form = new Element('div').addClass('stepForm').injectInside(this.step1);

            this.step1Text = new Element('h4').setHTML('Enter your email to begin').injectInside(this.step1Form);
            this.subSignUp = new Element('a').addClass('formButton signUp').setHTML('Sign Up').injectInside(this.step1Form).onclick = this.actionSignUp.bind(this, 1);

            this.startEmail = this.insertField('form', 'startEmail', 'Step 1', 'text', 'Enter your email here').injectInside(this.step1Form);

			//Step 02 of the Sign Up Process.
			//This is the last step in the Sign Up process.
            this.step2 = new Element('div', { 'id': 'step02' }).addClass('none').injectInside(this.signUp);

            this._step2Hold = new Element('div').addClass('stepGuide clearfix').injectInside(this.step2);
            this.step2Title = new Element('p').setHTML('Sign up to MySelection').injectInside(this._step2Hold);
            this.step2guide = new Element('span', { 'class': 'steps' }).setHTML('Step 2 of 2').injectInside(this._step2Hold);

            this.step2Form = new Element('div').addClass('stepForm').injectInside(this.step2);
            this.step2Text = new Element('h4').setHTML('Please add a few more profile details&hellip;').injectInside(this.step2Form);
            this.step2Extra = new Element('p').addClass('required').setHTML('* required').injectInside(this.step2Form);
            // this.nextStep	= new Element('a', {'href':'#'}).addClass('formButton next').setHTML('Next').injectInside(this.step2Form).onclick = this.actionSignUp.bind(this, 2);

            this.email = this.insertField('form hLabel', 'uEmail', 'Email/Username', 'text', ' ', true, { type: 'email', message: 'correct email address required' }).injectInside(this.step2Form);
            this.password = this.insertField('form hLabel', 'uPassword', 'Create a Password', 'password', 'Password', true, { type: 'length', setting: [6, 12], message: 'Password must be 6-8 Characters' }).injectInside(this.step2Form);
            this.confirm = this.insertField('form hLabel', 'confirm', 'Confirm Password', 'password', 'Confirm Password', true, { type: 'confirm', setting: 'field_uPassword', message: 'Confirmation password differs', customRequired: 'Oops' }).injectInside(this.step2Form);
            this.firstname = this.insertField('form hLabel', 'uFName', 'First Name', 'text', 'First Name', true, { type: 'general', setting: 1, message: 'Please Supply your First Name' }).injectInside(this.step2Form);
            this.lastname = this.insertField('form hLabel', 'uLName', 'Last Name', 'text', 'Last Name', true, { type: 'general', setting: 1, message: 'Please Supply your Last Name' }).injectInside(this.step2Form);
            this.phone = this.insertField('form hLabel', 'uLPhone', 'Phone Number', 'text', 'Phone Number').injectInside(this.step2Form);

			// if(this.getOption('termsLink') != null) {
            // 	this.termCheck	= new Element('input', {'type':'checkbox', 'id':'terms', 'value': 'terms', 'class':'none'}).injectInside(this.step2Form);
            // 	this.terms		= new Element('label', {'for': 'terms', 'class':'checkBox'}).setHTML('I Agree to the <a href="'+this.getOption('termsLink')+'" target="_blank">Terms and Conditions</a>').injectInside(this.step2Form);
            //  				this.terms.addEvent('click', function (){ this.termCheck.checked = !this.termCheck.checked; }.bind(this));
            // }
            //TODO: This at one point had a check to see if we wanted to show the terms and conditions check box.
			//		May need to look into at some point why it had been removed.
            this.termCheck = new Element('input', { 'type': 'checkbox', 'id': 'terms', 'value': 'terms', 'class': 'none' }).injectInside(this.step2Form);
            this.terms = new Element('label', { 'for': 'terms', 'class': 'checkBox', 'title': 'Please see Terms & Conditions in the footer' }).setHTML('I Agree to the Terms and Conditions').injectInside(this.step2Form);
            this.terms.addEvent('click', function(event) { ed = new Event(event).stop(); this.termCheck.checked = !this.termCheck.checked; if ($('terms').getNext().hasClass('required')) { $('terms').getNext().removeClass('required'); } } .bind(this));

            this.signUpRemberMe = new Element('input', { 'type': 'checkbox', 'id': 'signuprememberMe', 'value': 'rememberMe', 'class': 'none' }).injectInside(this.step2Form);
            this.signUpRemberMeLabel = new Element('label', { 'for': 'signuprememberMe', 'class': 'checkBox' }).setHTML('Remember me on Sign In').injectInside(this.step2Form);
            this.signUpRemberMeLabel.addEvent('click', function(event) { ed = new Event(event).stop(); this.signUpRemberMe.checked = !this.signUpRemberMe.checked; } .bind(this));

            this.finish = new Element('div').addClass('finishProfile').injectInside(this.step2);
            this.finButton = new Element('a').addClass('formButton finish').setHTML('Finish').injectInside(this.finish).onclick = this.actionSignUp.bind(this, 3);
            this.finText = new Element('p').setHTML('That&rsquo;s it! Click finish to complete.').injectInside(this.finish);

            //Elements for teh Sign In Panel
            this._logInHold = new Element('div').addClass('stepGuide clearfix').injectInside(this.logIn);
            this.step2Title = new Element('p').setHTML('Sign in to MySelection').injectInside(this._logInHold);
            this.step1guide = new Element('span', { 'class': 'steps' })
                .setHTML('<a href="' + this.options.forgottenPasswordURI + '" class="steps">Forgot my password</a>')
                .addEvent('click', function(event)
                          {
                              var ed = new Event(event).stop(); // stop event propogation
                              var email = $('field_logInUser').value;
                              var forgottenPasswordLocation = this.options.forgottenPasswordURI +
                                  ((email != "" && email != "Username") ? ("?email=" + email) : "");
                              location = forgottenPasswordLocation;
                          }.bind(this))
                .injectInside(this._logInHold);

            this.logInForm = new Element('div').addClass('stepForm').injectInside(this.logIn);

            this.logInText = new Element('h4').setHTML('Sign in or ').injectInside(this.logInForm);
            // this.joinFree	= new Element('span').setHTML(' ').injectInside(this.logInText);
            this.signUp2 = new Element('a', { 'class': 'joinNow' }).setHTML('Join free today').injectInside(this.logInText).onclick = this.openAB.bind(this, [this.signUp, 'signUpLink']);
            //Creating the Sign In submittion button then adding the functionality <this.actionLogIn> to it.
			this.submitLogIn = new Element('a', { 'href': '#' }).addClass('formButton submit').setHTML('submit').injectInside(this.logInForm).onclick = this.actionLogIn.bind(this, 'form');
            this.logInUser = this.insertField('form hLabel', 'logInUser', 'Username/Email', 'text', 'Username').injectInside(this.logInForm);
            this.logInPass = this.insertField('form hLabel', 'logInPass', 'Password', 'password', 'password').injectInside(this.logInForm);

            //Rememeber Me Input Box
            this.signInRemberMe = new Element('input', { 'type': 'checkbox', 'id': 'signinrememberMe', 'value': 'rememberMe', 'class': 'none' }).injectInside(this.logInForm);
            this.signInRemberMeLabel = new Element('label', { 'for': 'signinrememberMe', 'class': 'checkBox' }).setHTML('Remember me on Sign In').injectInside(this.logInForm);
            this.signInRemberMeLabel.addEvent('click', function(event) { ed = new Event(event).stop(); this.signInRemberMe.checked = !this.signInRemberMe.checked; } .bind(this));

            this.logError = new Element('p', { 'id': 'logError' }).injectInside(this.logInForm);

			//Adding the functionality to aid in dressing the checkbox using a custom stylesheet.
            $$('#soxc label.checkBox').each(function(label) {
                label.addEvent('click', function() {
                    if (label.hasClass('selected') != true) label.addClass('selected');
                    else label.removeClass('selected');
                });
            });

        } else {
			//This side of the if statement is building the Action Box for a logged user.

            this.abMenu.addClass('current');
			//Using Mootools <Fx.Slide> class to add the ability to close/open the Action box for a logged in user
            this.abfx = {
                profilePanel: new Fx.Slide(this.ab)
            };

            this.myProfile = new Element('li').setHTML('Your Profile').injectInside(this.abMenu).onclick = this.openProfile.bind(this, true);

			//Setting a Boolean so we know if the Profile is open or closed.
			this.profileState = true;

            // this.abHolder	= new Element('div').injectAfter(this.abMenu)
            this.abSubMenu = new Element('ul').addClass('subMenu').injectInside(this.ab);
            this.myActivity = new Element('li', { 'id': 'actSwitch' }).setHTML('My Activities').addClass('current').injectInside(this.abSubMenu).onclick = this.switchProfilePanels.bind(this, 'activities');
            this.myDetails = new Element('li', { 'id': 'detSwitch' }).setHTML('My Details').injectInside(this.abSubMenu).onclick = this.switchProfilePanels.bind(this, 'profile');
            //this.myPrefs	= new Element('li').setHTML('My Preferences').injectInside(this.abSubMenu);

            // this.ab.addClass('none');
            this.activitiesPanel = new Element('div', { 'id': 'myActivities', 'class': 'stepForm' }).setHTML(this.getOption('activitiesText')).injectInside(this.ab);


            this.profilePanel = new Element('div', { 'id': 'myProfile', 'class': 'none' }).injectInside(this.ab);
            this.uProfile = new Element('form', { 'id': 'userProfile', 'name': 'userProfile', 'action': this.options.userUpdate, 'method': 'get' }).injectInside(this.profilePanel);
            this.proHeading = new Element('h4').setHTML('Edit your current profile details&hellip;').injectInside(this.uProfile);

            this.saveProfile = new Element('div').addClass('saveProfile').injectInside(this.profilePanel);
            this.saveText = new Element('p').setHTML('&nbsp;').injectInside(this.saveProfile);
            this.saveButton = new Element('a').addClass('save disabled').setHTML('Save').injectAfter(this.saveText);

            this.email = this.insertField('form profile', 'uEmail', 'Email/Username', 'text', this.options.uDetail.uEmail, true, { type: 'email', message: 'correct email address required', update: true }).injectInside(this.uProfile);
            this.email.addEvent('keyup', this._changeSaveButtonState.bind(this));


            this.changePass = new Element('div', { 'id': 'changeHolder' }).injectInside(this.uProfile);
            this.passSlide = new Fx.Slide(this.changePass).hide();

            this.changePassword = new Element('p').addClass('changePassword').injectInside(this.uProfile);
            this.changeTxt = new Element('a', { 'id': 'changePassword', 'class': 'change' }).setHTML("Change Password").injectInside(this.changePassword);
            this.changeTxt.onclick = this.actionChangePassword.bind(this);

            this.firstname = this.insertField('form profile', 'uFName', 'First Name', 'text', this.options.uDetail.uFName, true, { type: 'general', setting: 1, message: 'Please Supply your First Name', update: true }).injectInside(this.uProfile);
            this.firstname.addEvent('keyup', this._changeSaveButtonState.bind(this));
            this.lastname = this.insertField('form profile', 'uLName', 'Last Name', 'text', this.options.uDetail.uLName, true, { type: 'general', setting: 1, message: 'Please Supply your Last Name', update: true }).injectInside(this.uProfile);
            this.lastname.addEvent('keyup', this._changeSaveButtonState.bind(this));
            this.phone = this.insertField('form profile', 'uLPhone', 'Phone Number', 'text', this.options.uDetail.uLPhone, false, { update: true }).injectInside(this.uProfile);
            this.phone.addEvent('keyup', this._changeSaveButtonState.bind(this));
        }
    },
    openProfile: function(toggle) {
        if((toggle == true && this.profileState == true) || (toggle == true && this.profileState == false))
		{
			this.abfx.profilePanel.toggle();
        	this.abMenu.toggleClass('current');
 			this.profileState = !!!this.profileState;

		} else if(toggle == 'false' && this.profileState == false)
		{
			this.abfx.profilePanel.slideIn();
        	this.abMenu.toggleClass('current');
 			this.profileState = !!!this.profileState;
		}
    },
	/**
	*	actionLogIn - <function>
	* 	Used to sign the user into SoXc.
	*
	*	USED: initUser <function>
	*
	*	TODO: 	This would be where the new code could be implemented to allow for the new Sign In method
	*			Would be good if we could retain this method so future would not be restricted to only one method for signing in.
	*			If SoXc widget was to be used in another website using another sign in method that is similar to the method currently used.
	*
	*/
    actionLogIn: function(from) {
        this.logError.empty();
		//Taking the password from the form and converting it to MD5 hash before sending via a HTTPrequest
        if (from == 'form') var details = [$('field_logInUser').value, MD5($('field_logInPass').value), $('signinrememberMe').checked];
        else if (from == 'signUp') var details = [$('field_uEmail').value, MD5($('field_uPassword').value), $('signuprememberMe').checked];

        //This address is being passed in via the SoXc initialize
        URI = this.options.access + '?uid=' + details[0] + '&pwd=' + details[1] + '&rememberme=' + details[2];

//         var request = new Json.Remote(URI, {
//             method: 'get',
//             onComplete: this.processLogIn.bind(this)
//         }).send();
        new JSONP_Request(
            {
                url: URI,
                method: 'get',
                onSuccess: this.processLogIn.bind(this)
            }
        ).send();
    },
	/**
	*	processLogIn - <function>
	* 	Processes the JSON return from actionLogIn to see if the user can be logged in or not.
	*
	*	USED: actionLogIn <function>
	*/
    processLogIn: function(obj) {
        if (obj.logged == false) {
            $('logError').setHTML(obj.errorMsg);
        }
        else {
            //Set the uDetail to the same as the newly returned JSON object
			this.options.uDetail = obj;
			//Set the iUserDetails Cookie so it can be used during a pageload event
            this.updateUserCookie(obj);

			//Open the Register Interest Panel if it was closed in a earlier process.
			//TODO: This will need to be updated at a later point as it will cause a JS error in living
			//		When the Register Interest panel maynot exist.
            this.riSlide.slideIn().chain(function() { $('ri').getParent().setStyle('height', 'auto'); });
			this.regButton.onclick = this.actionRegInterest.bind(this, 1);

			//Refresh the Log Panels
            this.initLogPanels();
			//Refresh the Action Box Panels
            this.initUser();

			//Run the signIn function in the options Object.
			//TODO: There should really be a check to see if this exists.
			//		Not sure what will happen if this not set.
			this.options.signIn();
        }
    },
	/**
	*	updateUserCookie - <function>
	* 	Updates the User Cookie so that the user details can be accessed on pageload without requiring the server.
	*
	*	USED: processLogIn
	*/
    updateUserCookie: function(obj) {
        var intDur = obj.RememberMe ? 3652 : 0;
        this.user = new Hash.Cookie('iUserDetails', { duration: intDur, domain: this.getOption('soxcCookieDomain'), path: '/' });
        this.user.extend(obj);

    },
	/**
	*	switchProfilePanels - <function>
	* 	Used to switch the panels in the Action Box
	*
	*	USED: initUser
	*/
    switchProfilePanels: function(panel) {
        $('ab').getParent().setStyle('height', 'auto');
        if (panel == 'profile') {
            $('actSwitch').removeClass('current');
            $('detSwitch').addClass('current');

            this.activitiesPanel.addClass('none');
            this.profilePanel.removeClass('none');
        } else if (panel == 'activities') {
            $('detSwitch').removeClass('current');
            $('actSwitch').addClass('current');
            this.profilePanel.addClass('none');
            this.activitiesPanel.removeClass('none');
        }
    },
	/**
	*	upPassword - <function>
	* 	Used for Updating the password in the Change Password Panel
	*
	*/
    upPassword: function() {

        var submit = [];

        $$('#changeHolder input').each(function(el, i) {
            if (el.title.test(/^required/i)) {
                if (el.alt.test(/^invalid/i)) {
                    submit.push(el);
                    el.getNext().addClass('required').setHTML(' * Required');
                }
            }
        });
        if ($('field_confirm').value != $('field_NewPassword').value) {
            $('field_confirm').getNext().addClass('required').setHTML(' * Oops');
            $('field_confirm').getNext().getNext().setHTML('Confirmation password differs');
            return;
        }
        if (submit.length != 0) return;

        updatePasswordURI = this.getOption('changePassword') + '?NewPassword=' + MD5($('field_NewPassword').value) + '&OldPassword=' + MD5($('field_OldPassword').value);

//         var updatePassRequest = new Json.Remote(updatePasswordURI, {
//             method: 'get',
//             onComplete: this.finPassword.bind(this)
//         }).send();
        new JSONP_Request(
            {
                url: updatePasswordURI,
                method: 'get',
                onSuccess: this.finPassword.bind(this)
            }
        ).send();
    },
	/**
	*	finPassword - <function>
	*
	*	USED:
	*/
    finPassword: function(obj) {
        if (obj && obj['Error'] == false) $('field_OldPassword').getNext().getNext().setHTML(obj['message']);
        else if (!obj || !obj['Changed'] || obj['Changed'] == true) {
            this.passSlide.toggle().chain(function() { $('changeHolder').empty(); this._changeSaveButtonState(); } .bind(this));
            $('changePassword').setHTML('Change Password');
            $('cancelChange').remove();
            this.changeTxt.onclick = this.actionChangePassword.bind(this);
        }
    },
	/**
	*	actionChangePassword - <function>
	*
	*	USED:
	*/
    actionChangePassword: function() {
        this.ab.getParent().setStyle('height', 'auto');

        this.currentPassword = this.insertField('form profile password', 'OldPassword', 'Current', 'password', '', true, { type: 'length', setting: [6, 12], message: 'Password must be 6-8 Characters' }).injectInside(this.changePass);
        this.currentPassword.addEvent('keyup', this._changeSaveButtonState.bind(this));
        this.updatePassword = this.insertField('form profile password', 'NewPassword', 'New Password', 'password', '', true, { type: 'length', setting: [6, 12], message: 'Password must be 6-8 Characters' }).injectInside(this.changePass);
        this.updatePassword.addEvent('keyup', this._changeSaveButtonState.bind(this));
        this.confirmPassword = this.insertField('form profile password', 'confirm', 'Confirm', 'password', '', true, { type: 'confirm', setting: 'field_NewPassword', message: 'Confirmation password differs' }).injectInside(this.changePass);
        this.confirmPassword.addEvent('keyup', this._changeSaveButtonState.bind(this));

        this.passSlide.toggle().chain(function() { $('changeHolder').getParent().setStyle('height', 'auto'); });
        this.cancelChange = new Element('a', { 'id': 'cancelChange', 'class': 'cancel' }).setHTML('Cancel').injectTop(this.changePassword).onclick = this.finPassword.bind(this);

        this.changeTxt.setHTML('Save Password').onclick = this.upPassword.bind(this);
    },
	/**
	*	highlightAB - <function>
	* 	Used to highlight on rollover the Action Box Panel
	*
	*	USED: initUser
	*/
    highlightAB: function(show) {
        if (show == true) {
            if (this.uDetails() != null) this.abSubMenu.addClass('hover');
            //this.abMenu.addClass('current');
            this.ab.addClass('hover');
        } else {
            if (this.uDetails() != null) this.abSubMenu.removeClass('hover');
            //this.abMenu.removeClass('current');
            this.ab.removeClass('hover');
        }
    },
    actionLogOut: function() {

        this.pd.empty();

        Cookie.remove('iUserId', { domain: this.getOption('soxcCookieDomain'), path: '/' });
        Cookie.remove('iUserDetails', { domain: this.getOption('soxcCookieDomain'), path: '/' });
        this.options.uDetail = null;

        this.initUser();
        this.initLogPanels();

        this.options.signOut();
    },
    actionProfile: function(type) {
        this.saveText.setHTML('&nbsp;');
        switch (type) {
            case 'update':
                var submit = [];

                if (this.emailCheck($('field_uEmail').value)) {
                    var tmp = '';

                    $$('#userProfile input').each(function(el, i) {
                        if (el.title.test(/^required/i)) {
                            if (el.alt.test(/^invalid/i)) {
                                submit.push(el);
                                el.getNext().addClass('required').setHTML(' * Required');
                            }
                        }
                    });
                    if ($('field_confirm') && $('field_confirm').value != $('field_NewPassword').value) {
                        $('field_confirm').getNext().addClass('required').setHTML(' * Required');
                        $('field_confirm').getNext().getNext().setHTML('Confirmation password differs');
                        return;
                    }
                    if (submit.length != 0) submit[0].focus();
                    else {

                        if ($('field_OldPassword')) this.upPassword();

                        $$('#userProfile input').each(function(el) {
                            if (el.type != 'password') {
                                tmp += '"' + el.name + '": "' + el.value + '", ';
                            }
                        });

                        tmp += '"ActionMode":"edit"';
                        var tmpObject = Json.evaluate('{' + tmp + '}');

                        this.updateUserCookie(tmpObject);

                        URI = this.uProfile.action + '?' + Object.toQueryString(tmpObject);

                        this._resetUserProfileOldValues();
                        this._changeSaveButtonState();
//                         var request = new Json.Remote(URI, {
//                             method: 'get',
//                             onComplete: this.processProfile.bind(this)
//                         }).send();
                        new JSONP_Request(
                            {
                                url: URI,
                                method: 'get',
                                onSuccess: this.processProfile.bind(this)
                            }
                        ).send();
                    }
                } else {
                    this.saveText.setHTML('<strong class="required">Valid Email Address Required</strong>');
                }
                break;
        }
    },
    processProfile: function(obj) {

    },
    actionSignUp: function(step) {
        if (this.emailErr) this.emailErr.remove();
        var submit = [];
        switch (step) {

            case 1:

                if (this.emailCheck($('field_startEmail').value)) {
                    URI = this.options.checkEmail + '?ActionMode=add&Email=' + $('field_startEmail').value;
                    var request = new Json.Remote(URI, {
                        method: 'get',
                        onComplete: this.checkDuplicateEmail.bind(this)
                    }).send();
//                     new JSONP_Request(
//                         {
//                             url: URI,
//                             method: 'get',
//                             onSuccess: this.checkDuplicateEmail.bind(this)
//                         }
//                     ).send();
                } else {
                    $('field_startEmail').getNext().setHTML(' Please supply valid email address');
                }

                break;
            case 2:
                $('field_uEmail').value = $('field_uEmail_label').value = $('field_startEmail').value;
                this.step1.addClass('none');
                this.step2.removeClass('none');

                break;
            case 3:
                if (!(this.emailCheck($('field_uEmail').value))) { //new
                    $('field_uEmail').getNext().addClass('required').setHTML(' * <small>Invalid Email</small>');
                    submit.push($('field_uEmail'));
                } else {
                    $('field_uEmail').setProperty('alt', '');
                }
                $$('#step02 input').each(function(el, i) {
                    if (el.title.test(/^required/i)) {
                        if (el.alt.test(/^invalid/i)) {
                            submit.push(el);
                            el.getNext().addClass('required').setHTML(' * Required');
                        }
                    }
                });

                //if(submit.length != 0) submit[1].focus();

                //if(this.getOption('termsLink') != null && !$('terms').checked) {
                if (!$('terms').checked) {
                    $('terms').getNext().addClass('required');
                    // alert('Please check Terms & Conditions before you submit details');
                    return;
                }
                if (submit.length == 0) {
                    var tmp = '';
                    $$('#signUp input').each(function(el) {
                        if (el.name.indexOf('_label') < 0) // the element is not a label element
                        {
                            if (el.name == 'uPassword' || el.name == 'confirm') {
                                tmp += '"' + el.name + '": "' + MD5(el.value) + '", ';
                            } else if (el.name == 'signuprememberMe') {
                                tmp += '"' + el.value + '": "' + el.checked + '", ';
                            } else {
                                if (el.value != 'Phone Number') tmp += '"' + el.name + '": "' + el.value + '", ';
                            }
                        }
                    });
                    tmp += '"ActionMode":"add"';

                    var tmpObject = Json.evaluate('{' + tmp + '}');

                    URI = this.signUp.action + '?' + Object.toQueryString(tmpObject);

//                     var request = new Json.Remote(URI, {
//                         method: 'get',
//                         onComplete: this.processSignUp.bind(this)
//                     }).send();
                    new JSONP_Request(
                        {
                            url: URI,
                            method: 'get',
                            onSuccess: this.processSignUp.bind(this)
                        }
                    ).send();
                }
                break;
        }
    },
    checkDuplicateEmail: function(obj) {
        if (obj.add == true) {
            this.actionSignUp(2);
        } else {
            $('field_startEmail').getNext().setHTML('This email already exists please choose another.');
        }
    },
    processSignUp: function(obj) {
        if (obj.added == true) {
            this.regButton.onclick = this.actionRegInterest.bind(this, 1);
            this.actionLogIn('signUp');
        } else if (obj.added == false) {
            alert(obj.message);
            $('field_uEmail').focus();
        }
    },
	/**
    *  Method: _changeSaveButtonState
    *  <div id="userProfile"> form input fields.  It checks to see
    *  whether any of the inputs are 'dirty', and sets the state of
    *  the save button appropriately.
    *
    */
    _changeSaveButtonState: function() {
        var dirty = false;
        $$('#userProfile input').each(function(inputElement) {
            dirty =
                dirty ||
                inputElement.value != inputElement.oldValue;
        });

        // Note: saveButton's class is checked to ensure we don't add
        // multiple events...
        if (dirty && this.saveButton.hasClass('disabled')) {
            // Enable Save button
            this.saveButton.removeClass('disabled');
            this.saveButton.addClass('enabled');
            this.saveButton.removeEvents('click');
            this.saveButton.addEvent(
                'click',
                this.actionProfile.bind(this, 'update')
            );
        }
        else if (!dirty && this.saveButton.hasClass('enabled')) {
            // Disable Save button
            this.saveButton.removeClass('enabled');
            this.saveButton.addClass('disabled');
            this.saveButton.removeEvents('click');
        }
    },
    /**
    *  Method: _resetUserProfileOldValues
    *  This private method is typically used to reset the 'old' values of the
    *  userProfile form inputs to their new values when the form data
    *  has been saved.
    *
    */
    _resetUserProfileOldValues: function() {
        $$('#userProfile input').each(function(inputElement) {
            inputElement.oldValue = inputElement.value;
        });
    },
    /*
	*	End of Action Box / User Profile Specific Functionality
	*
	*****************/

    /****************
	*	Start of Register Intereset Specific Functionality
	*
	*	initRegister - <function>
	* 	Used to build and Initiate the Register Interest
	*
	*	USED: initUser
	*/
    initRegister: function() {
        if (!this.ri) {
            this.riMenu = new Element('ul').addClass('menu active').addEvents({ mouseenter: this.highlightRI.bind(this, true), mouseleave: this.highlightRI.bind(this, false) }).injectInside(this.options.container);
            this.riTitle = new Element('li').setHTML('Enquire Now').injectInside(this.riMenu);
            this.ri = new Element('div', { 'id': 'ri' }).addEvents({ mouseenter: this.highlightRI.bind(this, true), mouseleave: this.highlightRI.bind(this, false) }).injectInside(this.options.container);

            this.riSlide = new Fx.Slide(this.ri);
            this.ri.getParent().addClass("section");
        } else {
            this.ri.empty();
        }

        var regItemTXT = (this.currentView) ? this.currentView['itemName'] : '&nbsp;';

        this.infoLine = new Element('p', { 'class': 'infoLine' }).setHTML('&nbsp;').injectInside(this.ri);
        this.regDetailHolder = new Element('div', { 'id': 'regDetail' }).addClass('').injectInside(this.ri);
        this.topShadow = new Element('div').addClass('topShadow').injectInside(this.regDetailHolder);
        var regItems = new Element('div').addClass('regItems').injectInside(this.regDetailHolder);
        this.regItem = new Element('div').setHTML(regItemTXT).addClass('regItem').injectInside(regItems);
        this.regExtra = new Element('div').addClass('regExtra').injectInside(regItems);
        var botShadow = new Element('div').addClass('botShadow').injectInside(this.regDetailHolder);
        //this.revealList = new Element('a').addClass('reveal').setHTML('More Details').injectInside(botShadow);

        this.regActionArea = new Element('div', { 'id': 'regActionArea' }).injectInside(this.ri);

        this.regSlide = new Fx.Slide(this.regActionArea).hide();

        this.regAction = new Element('p').addClass('actHolder ').injectInside(this.ri);
        this.regCancel = new Element('a', { 'class': 'cancel none' }).setHTML('Cancel').injectInside(this.regAction);
        this.regButton = new Element('a').addClass('step1').setHTML('Enquire Now').injectInside(this.regAction);

        this.regButton.onclick = this.actionRegInterest.bind(this, 1);

        this.regProcess = 1;
    },
	/**
	*	updateRegister - <function>
	* 	Used externally to SoXc class to update the content within it.
	*
	*	EXAMPLE: When a item is selected outside SoXc details can be sent to RYI panel so when/if the user
	*			 clicks the Register Interest button RYI has all it needs to process Interest.
	*
	*	USED: External to SoXc
	*/
    updateRegister: function(objectKey, primaryKey, strName, extras) {
        this.resetRegInterest();
        var labelObj = this.getOption('objectLabels');
        var labelTxt = 'item';

        if (labelObj) {
            if (objectKey in labelObj) labelTxt = labelObj[objectKey];
        }
    
        if(labelTxt=='Project')
        {
          this.infoLine.setHTML('Enquire now!');
        }
        else
        {
        this.infoLine.setHTML('Enquire about this ' + labelTxt + ' now!');
        }
        if (this.regProcess == 1) {
            this.regItem.setHTML(strName);
            this.currentView = { objKey: objectKey, primKey: primaryKey.toInt(), itemName: strName };
            if (extras) this.currentView = $merge(this.currentView, extras);
        }
        else if (this.regProcess == 3) {
            this.currentView = { objKey: objectKey, primKey: primaryKey.toInt(), itemName: strName };
            if (extras) this.currentView = $merge(this.currentView, extras);
            this.actionRegInterest(3);
        }
    },
	actionRegInterest: function(step, action) {
        if (this.uDetails()) {
            if (action) this.callback = action;
            switch (step) {
                case 1: this.actionRegStepOne(this); break;
                case 2: this.processRegStepTwo(this); break;
                case 3: this.resetRegInterest(this); break;
            }
        } else {
            this.riSlide.slideOut();
            this.openAB(this.logIn, 'signInLink');
        }
    },
    actionRegStepOne: function() {
        if (this.uDetails()) {
            this.ri.addClass('active');
            this.regForm = new Element('form', { 'id': 'regInterest', 'name': 'regInterest', 'action': this.options.signUpSubmission, 'method': 'get' }).injectInside(this.regActionArea);
            var title = new Element('h4').setHTML('Please reply to me at&hellip;').injectInside(this.regForm);
            this.regEmail = this.insertField('form', 'email', 'Email', 'text', this.options.uDetail.uEmail, true, { update: true }).injectInside(this.regForm);
            this.regPhone = this.insertField('form', 'phone', 'Phone', 'text', this.options.uDetail.uLPhone, false, { update: true }).injectInside(this.regForm);
            this.regComment = new Element('textarea').addClass('field').injectInside(this.regForm);
            if (this.getOption('termsLink') != null) {
                this.termsCond = new Element('p', { 'class': 'terms' }).injectInside(this.regForm);
                this.termsLink = new Element('a', { 'href': this.getOption('termsLink') }).setHTML('Terms &amp; Conditions').injectInside(this.termsCond);
            };
            this.regCancel.removeClass('none').onclick = this.resetRegInterest.bind(this, 'cancel');

            this.regSlide.toggle().chain(function() { $('regActionArea').getParent().setStyle('height', 'auto'); });
            this.regButton.addClass('step2');

            this.regButton.onclick = this.actionRegInterest.bind(this, 2);
            this.regProcess = 2;
        }
    },
    processRegStepTwo: function() {

        if (this._error) this._error.remove();

        // EstateId, Param, Email, Phone, Text, MessageType
        if (!this.emailCheck($('field_email').value)) {
            $('field_email').getNext().getNext().setHTML('Valid email address is required');
            return;
        }
        var tmp = '';
        //Grab the details form the Registr Of Interest form.
        $$('#regInterest input').each(function(el) {
            tmp += '"' + el.name.capitalize() + '": "' + el.value + '", ';
        });
        tmp += '"Text":' + '"' + this.regComment.value + '",';

        //Sending this parameter so the JSON nows what to do with details
        tmp += '"MessageType":"ROI",';

        tmp += '"Param":' + '"' + this.currentView.objKey + ',' + this.currentView.primKey + '|"';
	tmp =tmp.replace(/[\n|\r|\r\n]/g,"\\r\\n");
        var queryObject = Json.evaluate('{' + tmp + '}');

        var roiURI = this.getOption('SOXComs') + '?' + Object.toQueryString(queryObject) + '&object=' + Object.toQueryString(this.currentView);

        //Commented as a work around for Issue 303 & Issue 273
        // var roiRequest = new Json.Remote(roiURI, {
        // 	method: 'get',
        // 	onComplete: this.actionRegStepTwo.bind(this)
        // }).send();

        // Work around for Issue 303 & Issue 273
        var roiRequest = new Json.Remote(roiURI, {
            method: 'get'
        }).send();

        //I'm creating the object here temporalily so that I don't need to change the actionRegStepTwo function.
        var tmpObj = {};
        tmpObj.sent = true;
        tmpObj.message = 'saveregistered';

        this.actionRegStepTwo(tmpObj);
        ///End work around for Issue 303 & Issue 273
    },
    actionRegStepTwo: function(obj) {
        if (obj.sent == true) {
            if (this.regForm) {
                //this.regActionArea.remove();
                if($$('p.thanksText').length < 1) this.thankText = new Element('p', { 'class': 'thanksText' }).injectInside(this.ri);
				this.thankText.setHTML('Our sales team will be in contact with you.');
                this.infoLine.setHTML('<strong>Thankyou!</strong> Your enquiry in the below properties has been submitted.');
                this.regSlide.toggle();
                this.topShadow.addClass('estate');
                if (this.currentView.estateName) this.topShadow.setText(this.currentView.estateName);
                $$(this.regAction, this.revealList, this.regCancel).addClass('none');
            }
            this.regProcess = 3;
            if (this.callback && obj['message']) this.callback(obj['message'].toLowerCase(), this.currentView);
        } else if (obj.sent == false) {
            this._error = new Element('p', { 'class': 'error' }).injectAfter(this.regAction);
            this._error.setHTML(obj.message2);
        };
    },
    cancelRegInterest: function() {
        this.regSlide.toggle();
        this.resetRegInterest();
    },
    resetRegInterest: function(method) {
        if (this._error) this._error.remove();
        if (this.regTimer) this.regTimer = $clear(this.regTimer);
        if (method == 'cancel') {
            this.regSlide.toggle();
            this.regCancel.addClass('none');
        }
        if($$('p.thanksText').length > 0)this.thankText.empty();
        this.infoLine.setHTML('Enquire about this property now!');
        this.regActionArea.empty();
        this.topShadow.removeClass('estate');
        this.topShadow.setText('');
        $$(this.regAction, this.revealList).removeClass('none');
        this.regButton.removeClass('step2').onclick = this.actionRegInterest.bind(this, 1);

        this.ri.removeClass('active');
        this.regProcess = 1;
    },
    highlightRI: function(show) {
        if (show == true) {
            // this.apMenu.addClass('current');
            this.ri.addClass('hover');
        } else {
            // 	this.apMenu.removeClass('current');
            this.ri.removeClass('hover');
        }
    },
    /*
	*	End of Register Intereset Specific Functionality
	*
	*****************/

    /****************
	*	Start of Contact Agent Specific Functionality
	*
	*	initAgents - <function>
	* 	Used to build and Initiate the Contact Agents Panel
	*
	*	USED: initUser
	*/
    initAgents: function() {
        if (!this.ap) {
            this.apMenu = new Element('ul').addClass('menu').addClass('active').addEvents({ mouseenter: this.highlightAP.bind(this, true), mouseleave: this.highlightAP.bind(this, false) }).injectInside(this.options.container);
            this.ap = new Element('div', { 'id': 'ap' }).addEvents({ mouseenter: this.highlightAP.bind(this, true), mouseleave: this.highlightAP.bind(this, false) }).injectInside(this.options.container);
        }
        this.apTitle = new Element('li').setHTML('Project Sales Manager').injectInside(this.apMenu);
        this.apText = new Element('p').setHTML('Our Project Sales Manager for the Estate is&hellip;').addClass('stepGuide').injectInside(this.ap);

        this.apDetails = new Element('div').addClass('apDetails').injectInside(this.ap);
        this.agPic = new Element('img').addClass('agPic').injectInside(this.apDetails);
        this.agTitle = new Element('h3').injectInside(this.apDetails);
        // this.agProfile	 = new Element('p').addClass('agProfile').injectInside(this.apDetails);
        this.agPhone = new Element('p').setHTML('Phone ').addClass('agPhone').injectInside(this.apDetails);
        this.agPhoneNum = new Element('span').injectInside(this.agPhone);
        this.agEmail = new Element('div', { 'id': 'agEmail' }).injectInside(this.apDetails);
        this.agEmailTop = new Element('div').addClass('agEmail_top').injectInside(this.agEmail);
        this.agEmailMid = new Element('div').addClass('agEmail_middle').injectInside(this.agEmail);

        this.agEmailForm = new Element('div', { id: 'agentEmail' }).injectInside(this.agEmailMid);
        this.emailSlide = new Fx.Slide(this.agEmailForm).hide();

        this.agEmailBot = new Element('div').addClass('agEmail_bottom').injectInside(this.agEmail);
        this.agMessage = new Element('p').injectInside(this.agEmailMid);
        this.agEmailLink = new Element('a').addClass('emailMe').injectInside(this.agMessage);
    },
	/**
	*	showAgent - <function>
	*	Here we getting a call external to SoXc to gather agent information from the server
	*
	*	USED: Externally to SoXc
	*/
    showAgent: function(objectID, primaryKey) {
        var key = primaryKey ? primaryKey : '';
        URI = this.getOption('agentProfile') + '?ObjectId=' + objectID + '&primaryKey=' + key;
        var request = new Json.Remote(URI, {
            method: 'get',
            onComplete: this.processShowAgent.bind(this)
        }).send();
    },
	/**
	*	processShowAgent - <function>
	*	Here we populate the Agent Profile panel with the JSON object returned frow showAgent
	*
	*	USED: showAgent
	*
	*	FUTURE: For the Living club this is where we would want to maybe combine the method of initAgent & processShowAgent
	*			to allow for multiple agent returns. At the moment using this method will only allow for one agent to
	*			be shown at one tme.
	*
	*/
    processShowAgent: function(obj) {
        if (obj) {
           var located = obj.Located[0] ? obj.Located[0]['OBJ_strname'] : 'Estate';
            var tence = (located.toLowerCase() != 'lot') ? 'the' : 'this';

            this.apText.setHTML('Our Project Sales Manager for ' + tence + ' ' + located + ' is&hellip;');

            var agent = obj.Agents.length ? obj.Agents[0] : obj.Agents;
            this.options.agentDetails = agent;
            this.objectDetails = obj.Located[0];

            this.agTitle.setHTML(agent.EMP_strFirstName + ' ' + agent.EMP_strLastName);
            // this.agProfile.setHTML(agent.EMP_strFirstName + '&rsquo;s Profile');
            this.agPhoneNum.setHTML(agent.EMP_strWorkPh);
            this.agPic.setProperty('src', this.getOption('agentPic') + agent.EMP_nId + '/' + agent.employeepicture + '&w=100&h=80&mode=resizefit');
            this.agEmailLink.setHTML('Ask me a question&hellip; Email me').onclick = this.initEmailAgent.bind(this);
        }
    },
	/**
	*	initEmailAgent - <function>
	*	This function is used to populate the contact form into the panel.
	*
	*	USED:
	*
	*/
    initEmailAgent: function() {
        if (!this.emailForm) {
            this.emailForm = new Element('form', { 'id': 'emailAgent', 'name': 'emailAgent', 'action': this.options.SOXComs, 'method': 'get' }).injectInside(this.agEmailForm);
            if(this.getOption('emailSubjects')) {

				if($type(this.getOption('emailSubjects')) == 'string') {
					new Element('p', {'class':'emailSubject'}).setHTML(this.getOption('emailSubjects')).injectInside(this.emailForm);
				} else if($type(this.getOption('emailSubjects')) == 'object') {
					new Element('p').setHTML('Your message relates to&hellip;').injectInside(this.emailForm);
					this.insertCheckBox(this.options.emailSubjects, true).injectInside(this.emailForm);
				}

			}
            this.emailTo = new Element('p').setHTML('To: ' + this.options.agentDetails.EMP_strFirstName + ' ' + this.options.agentDetails.EMP_strLastName).injectInside(this.emailForm);
            this.emailComment = new Element('textarea').addClass('field').injectInside(this.emailForm);
            var emailAddress = this.options.uDetail ? this.options.uDetail.uEmail : '';
            this.email = this.insertField('form', 'emailTo', 'Your Email:', 'text', emailAddress, true, { type: 'email', message: 'correct email address required', update: true }).injectInside(this.emailForm);

            this.emailActions = new Element('p').addClass('actions').injectInside(this.emailForm);
            this.clearEmail = new Element('a').addClass('clearEmail').setHTML('Clear').injectInside(this.emailActions).onclick = this.cancelEmail.bind(this);
            this.submitEmail = new Element('a').addClass('sendEmail').setHTML('Send').injectInside(this.emailActions).onclick = this.processEmailAgent.bind(this);

            this.agFX = {
                eForm: this.emailForm.effect('opacity', { duration: 500 })
            };
        } else {
            this.agFX.eForm.start(1);
        }
        this.agEmailLink.addClass('none');
        this.emailSlide.toggle().chain(function() { $('agentEmail').getParent().setStyle('height', 'auto'); });
    },
	/**
	*	processEmailAgent - <function>
	*	Function called when the user clicks on the send button.
	*	We gather all the form elements in a JSON object then submit via Json.Remote function
	*	send the details to the server
	*
	*	USED:
	*
	*/
    processEmailAgent: function() {

        if (!this.emailCheck($('field_emailTo').value)) {
            $('field_emailTo').getNext().getNext().setHTML('Valid email address is required');
            return;
        }

        tmpEmail = '"Param":' + '"' + this.objectDetails.OBJ_nId + ',' + this.options.agentDetails.EMP_nId.toInt() + '|",';
        tmpEmail += '"Email":' + '"' + $('field_emailTo').value + '",';
        tmpEmail += '"Text":' + '"' + this.emailComment.value + '",';
        tmpEmail += '"RelatesTo": "';
        $$('#emailAgent input[type="checkbox"]').each(function(el, i) {
            if (el.checked == true) tmpEmail += el.value + ',';
        });
        tmpEmail += '", "MessageType":' + '"SC"';
	tmpEmail=tmpEmail.replace(/[\n|\r|\r\n]/g,"\\r\\n");
        var queryObject = Json.evaluate('{' + tmpEmail + '}');

        var scURI = this.options.SOXComs + '?' + Object.toQueryString(queryObject);

        var roiRequest = new Json.Remote(scURI, {
            method: 'get',
            onComplete: this.endEmailProcess.bind(this)
        }).send();
    },
	/**
	*	cancelEmail - <function>
	*	This function is called if the user wishes to cancel the Contact process at anytime.
	*
	*	USED:
	*
	*/
    cancelEmail: function(args) {
        this.agFX.eForm.start(0);
        this.emailSlide.toggle();
        if (!this.emailThanks) this.emailThanks = new Element('span').injectInside(this.agMessage);
        this.emailThanks.setHTML('&nbsp;');
        //
        this.emailTimer = this.resetEmailPanel.delay(500, this);
    },
	/**
	*	endEmailProcess - <function>
	*	When the server sends back a response it is marked as complete then calls the endEmailProcess
	*	to animate the contact back down to a compact state
	*
	*	USED:
	*
	*/
    endEmailProcess: function() {
        this.agFX.eForm.start(0);
        this.emailSlide.toggle();
        if (!this.emailThanks) this.emailThanks = new Element('span').injectInside(this.agMessage);
        this.emailThanks.setHTML('Thankyou for message we\'ll be in contact soon');
		//Set a timer in motion so that after a elapsed time we reset the panel.
        this.emailTimer = this.resetEmailPanel.delay(2500, this);
    },
	/**
	*	resetEmailPanel - <function>
	*	Here we reseting the contact panel by deleting form elements and stopping the timer
	*	that is used to reset the state in endEmailProcess
	*
	*	USED: showAgent
	*
	*/
    resetEmailPanel: function() {
        this.emailThanks.empty();
        this.agEmailLink.removeClass('none');
        this.emailTimer = $clear(this.emailTimer);
    },
	/**
	*	highlightAP - <function>
	*	Used to highlight on rollover the Agent Profile Panel
	*
	*	USED: showAgent
	*
	*/
    highlightAP: function(show) {
        if (show == true) {
            // this.apMenu.addClass('current');
            this.ap.addClass('hover');
        } else {
            // 	this.apMenu.removeClass('current');
            this.ap.removeClass('hover');
        }
    },
    /*
	*	End of Contact Agent Specific Functionality
	*
	*****************/

	/**
	*	setDetails - <function>
	* 	Not Sure Why I'm using this.
	* 	Currently used in Apartments, Home and Land for MySelection.
	*	I have a feeling a partial thought process that was not completed.
	*	May be able to delete but not sure.
	*
	*	USED: NIL
	*/
    setDetails: function(obj) {

    },

    /****************
	*	Start of Footer Specific Functionality
	*
	*/
    initFooter: function() {
        this.footer = new Element('div').addClass('soxcFooter').injectInside(this.options.container);
    },
    /*
	*	End of Footer Specific Functionality
	*
	*****************/

    /****************
	*	Start of General Functionality
	*
	*	openAB - <function>
	*	Used to open the Action box to Sign Up or Sign In
	*
	*	EXAMPLE: If the user isn't signed in and they click Register Interest button.
	*			 The RYI panel closes and Action Box opens to the Sign In state.
	*
	*
	*	USED: Throughtout SoXc
	*
    */
   	openAB: function(el, link) {
       $$('#ab form').addClass('none');
       if (el.hasClass('none')) el.removeClass('none');

       $$('.menu li').removeClass('current');
       $(link).addClass('current');

        if (link == 'signUpLink') {
            $('field_startEmail').value = 'Enter your email to begin';
            if (this.step1.hasClass('none') == true) {
                $$(this.step1, this.step2, this.step3).addClass('none');
                this.step1.removeClass('none');
            }
        }

    },
	/**
	*	insertField - <function>
	* 	Used to create text input fields through SoXc.
    *	To allow a central control point for validation, details and functionality
	*
	*	HTML Structure
	*	<p class="form">
	*   	<label for="field_" > <!-- Label Text --> </label>
	*   	<input id="field_label" />
	*   	<input id="field_" style="display: none;"/> <!-- Introduced as a wok around for a bug IE -->
	*   	<span class="errorLog"/>
	*   </p>
	*
	*
	*	USED:
	*/
    insertField: function(className, name, labelTxt, type, value, required, options) {
        var tmp = new Element('p').addClass(className);

        var label = new Element('label', { 'for': 'field_' + name, 'id': 'label_' + name }).setHTML(labelTxt).injectInside(tmp);

        var _update = false;

        if (options) {
            _update = ('update' in options) ? true : false;
            var _status = ('update' in options) ? 'update' : 'invalid';
        }
        var required = required ? 'required' + ' ' + options['type'] : null;

        var fieldLabel = new Element('input', { 'type': 'text', 'id': 'field_' + name + '_label', 'name': '', 'value': value, 'title': required }).injectInside(tmp);
        var fieldData = new Element('input', { 'type': type, 'id': 'field_' + name, 'name': name, 'value': value, 'title': required }).injectInside(tmp).setStyle('display', 'none');

        // remember the old value - used by _changeSaveButtonState
        fieldLabel.oldValue = value; // _changeSaveButtonState doesn't discriminate against labels!
        fieldData.oldValue = value;

        if (required) {
            var require = new Element('span').setHTML('*').injectInside(tmp);
            fieldData.setProperty('alt', _status);
        }

        var errorLog = new Element('span', { 'class': 'errorLog' }).injectInside(tmp);

        fieldLabel.addEvent('focus', function() { this.setStyle('display', 'none'); fieldData.setStyle('display', 'inline').focus(); });

        fieldData.addEvents({
            focus: function() {
                if (this.value == value && _update == false) {
                    this.value = '';
                    //					this.type = type;
                }
            },
            blur: function() {
                if (this.value == '' && _update == false) {
                    //					this.type = 'text';
                    this.setStyle('display', 'none');
                    fieldLabel.setStyle('display', 'inline');
                    this.value = value;
                    if (required) {
                        this.setProperty('alt', 'invalid');
                        require.addClass('required').setHTML('* Required');
                    }
                }
                else if (required) {
                    switch (options['type']) {
                        case 'length':
                            if (this.value.length < options['setting'][0] || this.value.length > options['setting'][1]) {
                                tmp.getLast().setHTML(options['message']);
                            } else {
                                this.setProperty('alt', '');
                            }
                            break;
                        case 'confirm':
                            if (this.value != $(options['setting']).value) {
                                this.setProperty('alt', 'invalid');
                                require.addClass('required').setHTML('* Oops');
                                tmp.getLast().setHTML(options['message']);
                            } else {
                                this.setProperty('alt', '');
                            }
                            break;
                        default:
                            if (this.value.length < options['setting']) {
                                this.setProperty('alt', 'invalid');
                                tmp.getLast().setHTML(options['message']);
                            } else {
                                this.setProperty('alt', '');
                            }
                            break;
                    }
                }
            },
            keyup: function() {
                if (required) require.removeClass('required').setHTML('*');
                tmp.getLast().setHTML('');

            }
        });
        return tmp;
    },
	/**
	*	insertCheckBox - <function>
	* 	Used to create text input fields through SoXc.
    *	To allow a central control point for validation, details and functionality
	*
	*	HTML Structure
	*	<input type="checkbox" id="_checkBox" value="rememberMe" />
	*	<label for="_checkBox" class="checkBox"> <!-- Label Text --> </label>
	*
	*	USED:
	*/
    insertCheckBox: function(obj, hideFields) {

        var chkTmp = new Element('p').addClass('checkBox clearfix');

        var inputClass = hideFields ? 'none' : '';

        obj.subjects.each(function(subject) {
            var field = new Element('input', { 'type': 'checkbox', 'id': subject.label.toLowerCase(), 'value': subject.value.toLowerCase() }).addClass(inputClass).injectInside(chkTmp);
            var label = new Element('label', { 'for': subject.label.toLowerCase() }).addClass('checkBox').setHTML(subject.label).injectInside(chkTmp);
            label.addEvent('click', function(event) { ed = new Event(event).stop(); field.checked = !field.checked; });

            label.addEvents({
                click: function(el) {
                    if (this.hasClass('selected')) this.removeClass('selected');
                    else this.addClass('selected');
                }
            });
        });
        return chkTmp;
    },
	/**
	*	emailCheck - <function>
	* 	Used to create text input fields through SoXc.
    *	To allow a central control point for validation, details and functionality
	*
	*	RETURN - Boolean
	*
	*	USED: insertField
	*/
    emailCheck: function(str) {
        var at = "@";
        var dot = ".";
        var lat = str.indexOf(at);
        var lstr = str.length;
        var ldot = str.indexOf(dot);

        if (str.indexOf(at) == -1) return false;
        if (str.indexOf(at) == -1 || str.indexOf(at) == 0 || str.indexOf(at) == lstr) return false;
        if (str.indexOf(dot) == -1 || str.indexOf(dot) == 0 || str.indexOf(dot) == lstr) return false;
        if (str.indexOf(at, (lat + 1)) != -1) return false;
        if (str.substring(lat - 1, lat) == dot || str.substring(lat + 1, lat + 2) == dot) return false;
        if (str.indexOf(dot, (lat + 2)) == -1) return false;
        if (str.indexOf(" ") != -1) return false;

        return true;
    },
	/**
	* 	getOption - <function>
	* 	Used to any option that is kept within SoXc.
	*
	*	RETURN -
	*
	*	USED: Throughout SoXc
	*/
    getOption: function(option) {
        return this.options[option];
    },
	/**
	* 	setActivities - <function>
	* 	Doesn't appear to be used. Wont delete just yet incase.
	*
	*	USED: Throughout SoXc
	*/
	setActivities: function(txt) {
        this.activitiesPanel.setHTML(txt);
    },
	/**
	* 	uDetails - <function>
	* 	Used to return the user details for use within the Application.
	* 	Also used to check if the user is in a logged in state.
	*
	*	RETURN - Object
	*
	*	USED: Internally & Externally from SoXc
	*
	*	Primary use was to hold the user details in a logged state.
	*	if the user is not logged in uDetails is set to null
	*
	*/
    uDetails: function() {
        return this.options.uDetail;
    },
	/**
	* 	uName - <function>
	* 	Used to return the first name of the logged user.
	*
	*	RETURN - Object
	*
	*	USED: Throughout SoXc
	*/
    uName: function() {
        if (this.options.uDetail) return this.options.uDetail.uFName;
        else null;
    },
	/**
	* 	uName - <function>
	* 	Used to return the ID of the logged user.
	*
	*	RETURN - Interger
	*
	*	USED: Throughout SoXc
	*/
    uId: function() {
        if (this.options.uDetail) return this.options.uDetail.userID;
        else return -1;
    }


    /*
	*	End of SoXc General Functionality
	*
	*****************/
});
soXc.implement(new Events);
soXc.implement(new Options);
