/**
 * @author Filip Michalowski / Fi Stockholm
 */
Namespace.create("ng.modules.bookingForm");

ng.modules.bookingForm.BookingForm = function () {

	//private variables:
	var moduleContainer;
	var moduleData;
	
	var exhibitDropDownMenu;
	var eventMonthDropDownMenu;
	var eventDayDropDownMenu;
	var eventYearDropDownMenu;
	var eventSpeakerDropDownMenu;
	var formType;
	var form;

	//private methods:
	
	/**
	 * 
	 */
	var draw = function() {
				
		initializeForm();
		
	};	
	
	/**
	 * 
	 */
	var initializeForm = function() {
		
		var content = moduleContainer.find("div.content");
		form = moduleContainer.find("form");
		formType = form.find("input[name='formtype']").val();
		
		form.find("input[type!='hidden'][name!='formtype']").val("");
		
		if (formType === "exhibit") {					
			exhibitDropDownMenu = form.find("select.exhibit");			
		}
		else 
			if (formType === "speaker") {	
			
				eventMonthDropDownMenu = form.find("select.month");
				eventDayDropDownMenu = form.find("select.day");
				eventYearDropDownMenu = form.find("select.year");
				eventSpeakerDropDownMenu = form.find("select.speaker");	
				eventSpeakerDropDownMenu.find("option").eq(0).attr("selected","selected");
				eventSpeakerDropDownMenu.removeAttr("multiple");				
				eventSpeakerDropDownMenu.css("height","25px");
				form.find("a.addSpeaker").removeAttr("style");
				moduleContainer.find("div.speakerListInactive").attr("className","speakerList");
				eventSpeakerCount = eventSpeakerDropDownMenu.find("option").length;		
				moduleContainer.find("div.customSpeaker").addClass("nodisplay");		
				
				// shows custom speaker input field if user has selected last option
				eventSpeakerDropDownMenu.change(function() {
					var selected = form.find("select.speaker option:selected");					
					if (parseInt(selected.val()) === form.find("select.speaker option").length - 1) {						
						showCustomSpeakerInput();
						
						// "disable" the "Add Speaker" button
						form.find("a.addSpeaker").fadeTo("fast", 0.5).css("cursor","default").attr("title", "");
					} else {
						// "enable" the "Add Speaker" button
						form.find("a.addSpeaker").fadeTo("fast", 1).css("cursor","pointer").attr("title", "Add Speaker");
					}
				});  
				
				// adds event listener for a "Add Speaker" button
				form.find("a.addSpeaker").click( function() {
					addSpeakerClickHandler();					
				});			
				
				//create speakerlist holder
				var speakerList = $("<ul></ul>").addClass("speakerList");
				moduleContainer.find("div.speakerList").append(speakerList);	
				
			} else {
				return;
			}
		
		// rollover/down states for submit button
		form.find("input[name='submitBt']").mouseover(function() {
			var src = $(this).attr("src");
			src = src.split("_out").join("_over");
			$(this).attr("src", src);
		});
		form.find("input[name='submitBt']").mouseout(function() {
			var src = $(this).attr("src");
			src = src.split("_over").join("_out");
			src = src.split("_down").join("_out");
			$(this).attr("src", src);
		});
		form.find("input[name='submitBt']").mousedown(function() {
			var src = $(this).attr("src");
			src = src.split("_over").join("_down");
			$(this).attr("src", src);
		});
		form.find("input[name='submitBt']").mouseup(function() {
			var src = $(this).attr("src");
			src = src.split("_down").join("_over");
			$(this).attr("src", src);
		});
		
		// submit event handler
		form.submit(function() {
			
			if (validateForm() === false) {				
				return false;
			} else {
				$(this).find("div.errorMessage").addClass("nodisplay");
			}
			
		  // remove event listener
		  form.find("a.addSpeaker").unbind();
		  
          // capture *all* the fields in the
          // form and submit it via ajax.         
          var inputs = [];
          $(':input', this).each(function() {
            inputs.push(this.name + '=' + escape(this.value));
          })
		            
          // join our inputs using '&' to a query string
          jQuery.ajax({
		  	type: "GET",
            data: inputs.join('&'),
			dataType: "text",
            url: this.action,
            timeout: 12000,
            error: function(r) {
				$(this).unbind();
				createErrorScreen(r);
            },
            success: function(r) {
				//$(this).unbind();              
				//createErrorScreen(r);
				$(this).unbind();              
				createConfirmationScreen(r);
            }
          }) // checkout http://jquery.com/api for more syntax and options on this method.
          		  
          // re-test...
          // by default - we'll always return false so it doesn't redirect the user.
          return false;
        })
	};
	
	
	var addSpeakerClickHandler = function() {		
		var selected = form.find("select.speaker option:selected");					
		if (parseInt(selected.val()) !== form.find("select.speaker option").length - 1) {						
			addSpeakerToList();
		}
	};
	
	/**
	 * 
	 */
	var createConfirmationScreen = function(r) {
		
		form.addClass("nodisplay");
		var screen = moduleContainer.find("div.confirmationScreen");
		
		//screen.find("p.message").html(r);		
		screen.removeClass("nodisplay");
		
		// adds event listener for a "New Booking Request" button
		screen.find("a.newBooking").click( function() {
			$(this).unbind();		
			resetForm();
			screen.addClass("nodisplay");			
			form.removeClass("nodisplay");
		});
	}
	
	/**
	 * 
	 */
	var createErrorScreen = function(r) {
		
		form.addClass("nodisplay");
		var screen = moduleContainer.find("div.errorScreen");
		
		//screen.find("p.message").html(r);
		screen.removeClass("nodisplay");
		
		// adds event listener for a "Try Again" button
		screen.find("a.tryAgain").click( function() {
			$(this).unbind();	
			resetForm();
			screen.addClass("nodisplay");				
			form.removeClass("nodisplay");
		});
	}
	
	var resetForm = function() {
		
		form.find("input[type!='hidden'][name!='formtype']").val("");
		form.find("textarea").val("");
		if (formType === "speaker") {
			eventSpeakerDropDownMenu.val("0");
			//eventMonthDropDownMenu.val("0");
			//eventDayDropDownMenu.val("0");
			//eventYearDropDownMenu.val("0");
			hideCustomSpeakerInput();
			form.find("a.addSpeaker").fadeTo("fast", 1).css("cursor", "pointer").attr("title", "Add Speaker");
			form.find("ul.speakerList").html("");
			// adds event listener for a "Add Speaker" button
			form.find("a.addSpeaker").click(function(){
				addSpeakerClickHandler();
			});
		} else if (formType === "exhibit") {
			exhibitDropDownMenu.val("0");
		}
	};
	var validEmail = function(value) {
		// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
		return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
    };
	
	/**
	 * 
	 */
	var validateForm = function() {
		var usernameinput = moduleContainer.find("input[name='username']");
		var username = usernameinput.val();
		var emailinput = moduleContainer.find("input[name='emailfrom']");
		var email = emailinput.val();
		var errorMessage = moduleContainer.find("div.errorMessage");
		
		var formValid = true;
		
		//if (email === "" || emailinput.hasClass("textinputerror")) {
		if (!validEmail(email) || emailinput.hasClass("textinputerror")) {
			formValid = false;
			emailinput.removeClass("textinput").addClass("textinputerror").val("Enter your e-mail");
			errorMessage.removeClass("nodisplay").html("<p>Please enter your e-mail.</p>");
			emailinput.focus(function() {
				$(this).unbind();
				$(this).removeClass("textinputerror").addClass("textinput").val("");
			});
		};
				
		if (username === "" || usernameinput.hasClass("textinputerror")) {
			formValid = false;
			usernameinput.removeClass("textinput").addClass("textinputerror").val("Enter your name");
			errorMessage.removeClass("nodisplay").html("<p>Please enter your name.</p>");
			usernameinput.focus(function() {
				$(this).unbind();
				$(this).removeClass("textinputerror").addClass("textinput").val("");				
			});
		};		
				
		return formValid;
	};
	
	/**
	 * 
	 */
	var addSpeakerToList = function(){
		var speakerData = {
			speakerName: moduleContainer.find("select.speaker option:selected").text()
		};
		
		var speakerList = moduleContainer.find("ul.speakerList");
		var speakerItem = $("<li></li>");
		var speakerContent = $.tmpl(ng.modules.bookingForm.BookingFormTemplates.SelectedSpeaker, speakerData);
		
		speakerItem.append(speakerContent);
		speakerList.append(speakerItem);
		
		speakerItem.find("a.removeSpeaker").click( function() {
				$(this).parent().remove();
			}
		);
		
		// add onmousedown support
		speakerItem.find("a.removeSpeaker").mousedown(function(){
			$(this).addClass("down");
		});
		speakerItem.find("a.removeSpeaker").mouseup(function(){
			$(this).removeClass("down");
		});
		speakerItem.find("a.removeSpeaker").mouseout(function(){
			$(this).removeClass("down");
		});
	};
	
	/**
	 * 
	 */
	var showCustomSpeakerInput = function(){
		moduleContainer.find("div.customSpeaker").removeClass("nodisplay");	
		
		//change height of left part of form to adjust the border
		moduleContainer.find("div.left").css("padding-bottom", "67px");
		
		var customspeakerinput = moduleContainer.find("input[name='selectedcustomspeaker']");
		customspeakerinput.focus(function() {
				$(this).unbind();
				$(this).val("");				
		});
	};
	
	/**
	 * 
	 */
	var hideCustomSpeakerInput = function(){
		moduleContainer.find("div.customSpeaker").addClass("nodisplay");
	}

	//the returned object here will become ng.modules.bookingForm.BookingForm:
	return  {
		
		// public methods
		
		init: function (container, data) {
			moduleContainer = container;
			moduleData = data;
			
			draw();
		}

	};
}(); // the parens here cause the anonymous function to execute and return


/**
 * Markup templates for the BookingForm
 */
ng.modules.bookingForm.BookingFormTemplates = 
{	
	
	SelectedSpeaker: "<div><span>#{speakerName}</span><a class=\"removeSpeaker\" title=\"Remove speaker\">Remove speaker</a><input type=\"hidden\" name=\"selectedspeaker[]\" value=\"#{speakerName}\" /></div>"						
						
};

// enumerable form types
ng.modules.bookingForm.FormType = {
	
	Exhibit : "exhibit",
	
	Speaker : "speaker"
	
}