// Main
MSGI.namespace('page.signup', {
	/** for keeping track of password confirmation onblur */
	isFlyPasswordChecking: false,

	/** Initialize the page and attach events */
	init: function() {
		var page = this;
		$(document).ready(function() {
			MSGI.subscriber.authenticate(function(loggedIn) {
				if (loggedIn && !page.referredFromCampaign()) {
					page.redirectToMyInsider();
				} else {
					page.setupAll();
				}
			});
		});
	},
	
	setupAll: function() {
		this.setupReferrals();
		this.setupPage();
		this.setupEvents();
	},
	
	setupReferrals: function() {
		$.getScript('/js/msgi/page/signup.referrals.js');
	},

	setupPage: function() {
		this.prepopulateForm();
		this.addStatesToForm();
		this.addCountriesToForm();
	},
	
	setupEvents: function() {
		this.setupButtonEvents();
		this.setupFormEvents();
		this.setupFieldEvents();
	}
});


// Tracking & Referral Campaign
MSGI.namespace('page.signup', {
	// track signups coming from a promo URL (saved in promo cookie by home page)
	trackPromo: function(channelID, callback) {
		var promo = $.cookie('promo');
		if (promo) {
			$.cookie('promo', null);
			MSGI.promo.track('signup', channelID, promo, callback);
		} else {
			callback();
		}
	},

	referredFromCampaign: function() {
		return !!MSGI.getQueryParam('r');
	}
});


// Service
MSGI.namespace('page.signup', {
	/** Create the subscriber account */
	createAccount: function(callback) {
		var page = this;
		var form = $("#signup_form")[0];

		if (page.validateForm(form)) {
			// prepare a "subscriber" hash with data pulled from the signup form
			var subscriber = page.initSubscriberFromForm(form);
			
			// add a ref_id if a campaign referral code is in the URL
			var referralID = MSGI.getQueryParam('r');
			if (referralID) subscriber['ref_id'] = referralID;

			MSGI.channel.getInfo(MSGI.getChannelSlugFromURL(), function(channelID) {
				subscriber['channel_id'] = channelID;
				MSGI.subscriber.create(subscriber, function(response) {
					if (response.error) {
						if (response.error == MSGI.subscriber.create.EMAIL_ALREADY_EXISTS) {
							page.highlightLabel($('#email_label'));
							page.addNotice($('#email_notices'), 'This e-mail address is already registered. Would you like to <a href="/">log in</a>?');
							page.displayFixFieldsHeading();
						} else if (response.error == MSGI.subscriber.create.ERROR_CREATE_SUBSCRIBER) {
							$('#error_messages').html("There was an error creating your account.");
						}
						callback(false);
					} else {
						// fire off some Ajax calls to track this successful signup
						page.trackPromo(channelID, function() {
							page.trackReferralSignup(function() {
								// save subscriber's name in cookie, and let callback know signup is complete
								$.cookie('subscriber_name', subscriber.first_name);
								callback(true);
							});
						});
					}
				});
			});
		} else {
			page.displayFixFieldsHeading();
			callback(false);
		}
	}
});

// Helpers
MSGI.namespace('page.signup', {
	/** prepopulate form with data saved in cookie after a failed login attempt */
	prepopulateForm: function() {
		var cookie = $.cookie('subscriber_data');
		if (!cookie) return;
		
		var user = jsonParse(cookie);
		var form = $("#signup_form")[0];
		if (user.email != "") form.email.value = user.email;
		if (user.password != "") form.password.value = user.the_password;

		$.cookie('subscriber_data', null);
	},

	/** Redirects to My Insider page */
	redirectToMyInsider: function() {
		document.location = 'my-insider.html';
	},

	/**
	 * Initialize a subscriber from the form.
	 * @param {object} form the signup form
	 * @returns {object} the subscriber object
	 */
	initSubscriberFromForm: function(form) {
		return {
			email: form.email.value,
			the_password: form.password.value,
			first_name: form.firstName.value,
			last_name: form.lastName.value,
			address: form.address1.value,
			address2: form.address2.value,
			state: $(form.state).val(),
			city: form.city.value,
			country: $(form.country).val(),
			postal_code: form.zip.value,
			agreed_to_terms: form.hasAgreedToTerms.checked,
			agreed_to_special_offers: form.hasAgreedToSpecialOffers.checked,
			ref_email: form.referral_email.value,
			ref_first_name: form.referral_first_name.value, 
			ref_last_name: form.referral_last_name.value 
		};
	},

	/**
	 * Check if the signup form is valid.
	 * @param {object} form the signup form
	 * @returns {boolean} true if valid; otherwise, false;
	 */
	validateForm: function(form) {
		var isValid = true;

		if (!this.checkEmail(form.email.value))                                                    { isValid = false; }
		if (!this.checkPassword(form.password.value))                                              { isValid = false; }
		if (!this.checkPasswordConfirmation(form.password.value, form.passwordConfirmation.value)) { isValid = false; }
		if (!this.checkFirstName(form.firstName.value))                                            { isValid = false; }
		if (!this.checkLastName(form.lastName.value))                                              { isValid = false; }
		if (!this.checkAddress1(form.address1.value))                                              { isValid = false; }
		if (!this.checkAddress2(form.address2.value))                                              { isValid = false; }
		if (!this.checkCity(form.city.value))                                                      { isValid = false; }
		if (!this.checkState($(form.state).val()))                                                 { isValid = false; }
		if (!this.checkZip(form.zip.value))                                                        { isValid = false; }
		if (!this.checkCountry($(form.country).val()))                                             { isValid = false; }
		if (!this.checkHasAgreedToTerms())                                                         { isValid = false; }
		if (!this.checkReferralEmail())                                                            { isValid = false; }

		return isValid;
	},

	/** Add states to the signup form */
	addStatesToForm: function() {
		var stateField = $("#state_id");
		for (var state in MSGI.form.stateList) {
			stateField.append("<option>" + state + "</option>");
		}
	},

	/** Add provinces to the signup form */
	addProvincesToForm: function() {
		var stateField = $("#state_id");
		for (var province in MSGI.form.provinceList) {
			stateField.append("<option>" + MSGI.form.provinceList[province] + "</option>");
		}
	},

	/** Add countries to the signup form */
	addCountriesToForm: function() {
		var countryField = $("#country_id");
		for (var country in MSGI.form.countryList) {
			countryField.append("<option>" + MSGI.form.countryList[country] + "</option>");
		}
		selectboxReplacement();
	},

	/** Displays the notice heading */
	displayFixFieldsHeading: function() {
		$('#error_messages').html("There is a problem with the form.  Please make the corrections shown below.");
		window.scrollTo(0, 200);
	},

	/** Highlights the input field */
	highlightLabel: function(label) {
		label.addClass('error');
	},

	/** Resets the label to the default */
	resetLabel: function(label) {
		label.removeClass('error');
	},

	/** Resets the notice messages to the default */
	resetNotices: function(list) {
		list.html('');
		list.css('display', 'none');
	},

	/** Resets the label and notices to the default */
	resetLabelAndNotices: function(label, list) {
		this.resetLabel(label);
		this.resetNotices(list);
	},

	/** Adds a notice to the list of notice messages */
	addNotice: function(list, notice) {
		list.append('<li>' + notice + '</li>');
		list.css('display', 'block');
	}
});

// Events
MSGI.namespace('page.signup', {
	/** Button Events */
	setupButtonEvents: function() {
		var page = this;
		var yesButton = '#createAccountYes_btn';
		var noButton = '#createAccountNo_btn';
		var buttons = $(yesButton).add(noButton);
		
		buttons.click(function() {
			var button = $(this);			
			MSGI.lock(function(unlock) {
				MSGI.widgets.button.animate(button);
				page.createAccount(function(success) {
					MSGI.widgets.button.stop(button);
					unlock();
					if (success) {
						if (button.is(yesButton)) {
							$.cookie('registering', true);
							document.location = "select-categories.html";
						} else if (button.is(noButton)) {
							document.location = "my-insider.html";
						}
					}
	            });
			});
			
			return false;
		});		
	},

	/** Form Events */
	setupFormEvents: function() {
		$('#signup_form').submit(function() {
			return false;
		});
	},

	/** Field Events */
	setupFieldEvents: function() {
		var page = this;
		$('#email_id').blur(function()                 { page.checkEmail(this.value); });
		$('#password_id').blur(function()              { page.checkPassword(this.value); });
		$('#passwordConfirmation_id').blur(function()  { page.checkPasswordConfirmation($('#password_id').val(), this.value); });
		$('#firstName_id').blur(function()             { page.checkFirstName(this.value); });
		$('#lastName_id').blur(function()              { page.checkLastName(this.value); });
		$('#address1_id').blur(function()              { page.checkAddress1(this.value); });
		$('#address2_id').blur(function()              { page.checkAddress2(this.value); });
		$('#city_id').blur(function()                  { page.checkCity(this.value); });
		$('#zip_id').blur(function()                   { page.checkZip(this.value); });
		$('#country_id').change(function()             { page.setStateField($(this).val()); });
		$('#referral_email_id').blur(function()        { page.checkReferralEmail(); });
		
		// use the native "onclick" event to resolve a conflict with the checkbox replacement library
		$('#was_referred_id')[0].onclick = function() {
			var fields = $('.referral .hidden');
			if (this.checked) {
				fields.slideDown(function() {
					fields.find('input:first').focus();
				});
			} else {
				fields.slideUp(function() {
					fields.find('input').val('');
					page.resetLabelAndNotices($('#referral_email_label'), $('#referral_email_notices'));
				});
			}
		};
		
		// use the native "onclick" event to resolve a conflict with the checkbox replacement library
		$('#hasAgreedToTerms_id')[0].onclick = function () { 
			page.checkHasAgreedToTerms();
		};

		// fix for bug #62 - make the checkbox's div.label behave like a <label>
		$('#hasAgreedToTerms_label').click(function(event) {
			// if the user clicked outside of the link inside the label
			if (!$(event.target).is('a')) {
				// toggle the checkbox's checked state
				var box = $('#hasAgreedToTerms_id');
				box.attr('checked', !box.attr('checked'));
				
				// manually kick off validation of checkbox
				page.checkHasAgreedToTerms();
				
				// stop click event from propagating
				event.stopImmediatePropagation();
			}
		});
	}
});

// Validation
MSGI.namespace('page.signup', {
	/** Run email validations and display notices if neeeded to correct the field */
	checkEmail: function(email) {
		var isValid = true;
		this.resetLabelAndNotices($('#email_label'), $('#email_notices'));

		if (!MSGI.form.validateEmail(email)) {
			this.addNotice($('#email_notices'), "The email must be of the form user@example.com");
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(email, 128)) {
			this.addNotice($('#email_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#email_label'));
		}

		return isValid;
	},

	/** Run password validations and display notices if neeeded to correct the field */
	checkPassword: function(password) {
		var isValid = true;
		this.resetLabelAndNotices($('#password_label'), $('#password_notices'));

		if (!MSGI.form.validatePresenceOfValue(password)) {
			this.addNotice($('#password_notices'), "This field is required.");
			isValid = false;
		} else {
			if (!MSGI.form.validateMinimumLength(password, 6)) {
				this.addNotice($('#password_notices'), "The minimum length is 6 characters.");
				isValid = false;
			}
			if (!MSGI.form.validateMaximumLength(password, 10)) {
				this.addNotice($('#password_notices'), "The maximum length is 10 characters.");
				isValid = false;
			}
		}
		if (!isValid) {
			this.highlightLabel($('#password_label'));
		}

		return isValid;
	},

	/** Run password confirmation validations and display notices if neeeded to correct the field */
	checkPasswordConfirmation: function(password, passwordConfirmation) {
		var page = this;
		var isValid = true;
		this.resetLabelAndNotices($('#passwordConfirmation_label'), $('#passwordConfirmation_notices'));

		if (!MSGI.form.validatePasswordConfirmation(password, passwordConfirmation)) {
			this.highlightLabel($('#passwordConfirmation_label'));
			this.addNotice($('#passwordConfirmation_notices'), "The passwords do not match.");
			isValid = false;
		}

		// Events for correcting the password on the fly
		if (!this.isFlyPasswordChecking) {
			$('#password_id').keyup(function()             { page.checkPasswordConfirmation(this.value, $('#passwordConfirmation_id').val()); });
			$('#passwordConfirmation_id').keyup(function() { page.checkPasswordConfirmation($('#password_id').val(), this.value); });
			this.isFlyPasswordChecking = true;
		}

		return isValid;
	},

	/** Run first name validations and display notices if neeeded to correct the field */
	checkFirstName: function(firstName) {
		var isValid = true;
		this.resetLabelAndNotices($('#firstName_label'), $('#firstName_notices'));

		if (!MSGI.form.validatePresenceOfValue(firstName)) {
			this.addNotice($('#firstName_notices'), "This field is required.");
			// this.addNotice($('#firstName_notices'), 'Only letters, numbers, certain special characters '
			// 										+ '<a href="#" class="tooltip" title=\''
			// 										+ '! " # $ % &  ( ) * + , -'
			// 										+ '\'>(?)</a>  are permitted.');
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(firstName, 128)) {
			this.addNotice($('#firstName_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#firstName_label'));
		}

		return isValid;
	},

	/** Run last name validations and display notices if neeeded to correct the field */
	checkLastName: function(lastName) {
		var isValid = true;
		this.resetLabelAndNotices($('#lastName_label'), $('#lastName_notices'));

		if (!MSGI.form.validatePresenceOfValue(lastName)) {
			this.addNotice($('#lastName_notices'), "This field is required.");
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(lastName, 128)) {
			this.addNotice($('#lastName_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#lastName_label'));
		}

		return isValid;
	},

	/** Run address1 validations and display notices if neeeded to correct the field */
	checkAddress1: function(address1) {
		var isValid = true;
		this.resetLabelAndNotices($('#address1_label'), $('#address1_notices'));

		if (!MSGI.form.validatePresenceOfValue(address1)) {
			this.addNotice($('#address1_notices'), "This field is required.");
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(address1, 128)) {
			this.addNotice($('#address1_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#address1_label'));
		}

		return isValid;
	},

	/** Run address2 validations and display notices if neeeded to correct the field */
	checkAddress2: function(address2) {
		var isValid = true;
		this.resetLabelAndNotices($('#address2_label'), $('#address2_notices'));

		if (!MSGI.form.validateMaximumLength(address2, 128)) {
			this.addNotice($('#address2_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#address2_label'));
		}

		return isValid;
	},

	/** Run city validations and display notices if neeeded to correct the field */
	checkCity: function(city) {
		var isValid = true;
		this.resetLabelAndNotices($('#city_label'), $('#city_notices'));

		if (!MSGI.form.validatePresenceOfValue(city)) {
			this.addNotice($('#city_notices'), "This field is required.");
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(city, 128)) {
			this.addNotice($('#city_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#city_label'));
		}

		return isValid;
	},

	/** Run state validations and display notices if neeeded to correct the field */
	checkState: function(state) {
		var isValid = true;
		this.resetLabelAndNotices($('#state_label'), $('#state_notices'));

		if (!this.isRegionField() && !MSGI.form.validatePresenceOfValue(state)) {
			this.addNotice($('#state_notices'), "This field is required.");
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(state, 128)) {
			this.addNotice($('#state_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#state_label'));
		}

		return isValid;
	},

	/** Run zip validations and display notices if neeeded to correct the field */
	checkZip: function(zip) {
		var isValid = true;
		this.resetLabelAndNotices($('#zip_label'), $('#zip_notices'));

		if (!MSGI.form.validatePresenceOfValue(zip)) {
			this.addNotice($('#zip_notices'), "This field is required.");
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(zip, 128)) {
			this.addNotice($('#zip_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#zip_label'));
		}

		return isValid;
	},

	/** Run country validations and display notices if neeeded to correct the field */
	checkCountry: function(country) {
		var isValid = true;
		this.resetLabelAndNotices($('#country_label'), $('#country_notices'));

		if (!MSGI.form.validatePresenceOfValue(country)) {
			this.addNotice($('#country_notices'), "This field is required.");
			isValid = false;
		}
		if (!MSGI.form.validateMaximumLength(country, 128)) {
			this.addNotice($('#country_notices'), "The maximum length is 128 characters.");
			isValid = false;
		}
		if (!isValid) {
			this.highlightLabel($('#country_label'));
		}

		return isValid;
	},

	/** Run hasAgreedToTerms validations and display notices if neeeded to correct the field */
	checkHasAgreedToTerms: function() {
		var hasAgreed = $('#hasAgreedToTerms_id').attr('checked');
		var label = $('#hasAgreedToTerms_label');
		var notices = $('#hasAgreedToTerms_notices');

		this.resetLabelAndNotices(label, notices);

		if (!hasAgreed) {
			this.highlightLabel(label);
			this.addNotice(notices, "Please agree to the Terms and Conditions.");
			return false;
		}

		return true;
	},
	
	checkReferralEmail: function() {
		// skip validation if user did not fill out the referrer section
		if (!$('#was_referred_id').is(':checked')) return true;
	
		var field = $('#referral_email_id');
		var email = field.val();
		var label = $('label[for='+ field.attr('id') +']');
		var notice = $('#referral_email_notices');
		
		this.resetLabelAndNotices(label, notice);

		if (!MSGI.form.validateEmail(email)) {
			this.addNotice(notice, "The email must be of the form user@example.com");
			this.highlightLabel(label);
			return false;
		}
		
		return true;
	},

	/** Set the state/province field according to the selected country */
	setStateField: function(country) {
		var page = this;
		if (country == "United States") {
			$('#state_or_region_label').html('State');
			$('#state_or_region_input').html('<select id="state_id" name="state" tabindex="8"></select>');
			$('#state_label .required').html('*');
			page.addStatesToForm();
			page.checkState($('#state_id').val());
		} else if (country == "Canada") {
			$('#state_or_region_label').html('Province');
			$('#state_or_region_input').html('<select id="state_id" name="state" tabindex="8"></select>');
			$('#state_label .required').html('*');
			page.addProvincesToForm();
			page.checkState($('#state_id').val());
		} else {
			$('#state_or_region_label').html('Region');
			$('#state_or_region_input').html('<input id="state_id" name="state" type="text" tabindex="8" class="field" />');
			$('#state_label .required').html('');
			$('#state_id').blur(function() { page.checkState(this.value); });
		}
	},

	/** is there a region field (instead of state or province) */
	isRegionField: function() {
		return $('input#state_id')[0] != null;
	}
});
