jQuery( document ).ready(
	function( ){
		// Vars
		var commentsArea = jQuery( '#comments' );
		var form = undefined;
		var addingMessage = undefined;
		var submitButton = undefined;
		var inputs = undefined;
		var already_submitting = false;
		
		
		// If there is no comment area, then no need for a form
		if( commentsArea.size( ) < 1 ){
			return;
		}
		
		jQuery.get( 'new-comment/', {}, new_comment_callback, 'json' );
		
		
		// Functions
		
		/**
		 * The callback for the new comment form.
		 */
		function new_comment_callback( data, textStatus ){
			// Check if the a comment form was returned
			if( textStatus != 'success' || !data.the_comment_form ){
				return;
			}
			
			setup_the_comment_form( data.the_comment_form );
		};
		
		
		
		/**
		 * This sets up the comment form
		 */
		function setup_the_comment_form( the_comment_form ){
			// Initialize the vars
			form = jQuery( '<form method="post" action="add-comment/" id="add-comment-form"></form' ).appendTo( commentsArea );
			addingMessage = jQuery( '<div class="adding-comment-message">Adding comment</div>' );
			submitButton = jQuery( '<input type="submit" value="Add comment" name="add-comment" id="add-comment-button"/>' );
			
			
			// Create the actually form
			form.append( the_comment_form.belongs_to.element )
			    .append( the_comment_form.nounce.element )
			    .append( 
			       jQuery( '<div class="bio-info"></div>' )
			          .append( the_comment_form.author_name.label )
			          .append( the_comment_form.author_name.element )
			          .append( the_comment_form.author_email.label )
			          .append( the_comment_form.author_email.element )
			          .append( the_comment_form.author_website.label )
			          .append( the_comment_form.author_website.element )
			       )
			    .append( 
			       jQuery( '<div class="body"></div>' )
			          .append( the_comment_form.body.label )
			          .append( the_comment_form.body.element )
			       )
			     .append(
			        jQuery( '<div class="submit"></div>' )
			           .append( submitButton )
			     );
			
			inputs = form.find( ':input' );
			form.submit( form_submission );
			if( jQuery.autogrow ){
				jQuery( '#id_body' ).autogrow( );
			}
			
		};
			
			
		/**
		 * Validates the comment form fields after submit
		 */
		function validate_form( ){
			var validateText = /\S/;
			var validateEmail = /^\s*\S+@\S+\.\S{2}\S*\s*$/;
			var validateUrl = /^\s*http(s)?:\/\/[^\s\/\\]+\.\w{2}\w*(\/(.*)?)?\s*$/;
			
			var nameField = jQuery( '#id_author_name' );
			var emailField = jQuery( '#id_author_email' );
			var websiteField = jQuery( '#id_author_website' );
			var bodyField = jQuery( '#id_body' );
			
			var errors = {};
			var hasErrors = false;
			
			if( !validateText.test( nameField.val( ) ) ){
				hasErrors = true;
				errors.author_name = 'You need to provided your name.'
			}
			
			if( !validateText.test( bodyField.val( ) ) ){
				hasErrors = true;
				errors.body = 'You need to provided a comment.'
			}
			
			if( !validateEmail.test( emailField.val( ) ) ){
				hasErrors = true;
				errors.author_email = 'You need to provided an email address.'
			}
			
			if( websiteField.val( ) != 'http://' && websiteField.val( ) != '' && !validateUrl.test( websiteField.val( ) ) ){
				hasErrors = true;
				errors.author_website = 'If you provide a website address, it needs to be a valid URL.'
			}
			
			return { errors: errors, hasErrors: hasErrors };
		};
		
		
		/** 
		 * Handles when the comment form is submitted.
		 */
		function form_submission( event ){	
			// Prevent double submissions
			if( already_submitting ){
				event.stopPropagation( );
				return false;
			}
					
			already_submitting = true;
						
			// Validate
			var validation = validate_form( );
			var hasErrors = validation[ 'hasErrors' ];
			var errors = validation[ 'errors' ];
			
			// Handle errors if any
			
			// First remove any error messages from the last time the form was attempted to be submitted
			form.find( '.error' )
			    .removeClass( 'error' )
			    .next( '.error-message' ).remove( );
			
			// If errors, add error messages and stop submission
			if( hasErrors ){
				for( error in errors ){
					jQuery( '#id_'+error )
						.addClass( 'error' )
						.after( '<span class="error-message">'+errors[ error ]+'</span>' );
				}
							
				already_submitting = false; // Unlock the form so they can correct and submit it again
				
				event.stopPropagation( );
				return false;
			}
			
			return submit_the_form( event );	
		};
		
		
		/**
		 * Changes the UI to indicate the form is being submitted.
		 */
		function indicate_form_is_being_submitted( ){
			submitButton.val( 'Adding comment' );
			form.append( addingMessage );
			addingMessage.css(
					{ top: '150px',
					  opacity: 0
					}
				).animate(
					{ top: '50px',
					  opacity: 1
					},
					300
				);
		};
		
		
		
		/**
		 * This handles the actually submission of the form.
		 */
		function submit_the_form( event ){
			indicate_form_is_being_submitted( );
			
			
			// Prepare the form values to be submitted
			var values = {};
			inputs.each( function(){ 
					var t = jQuery( this );
					values[ t.attr( 'name' ) ] = t.val( );
				} );
			
			// POST the form
			jQuery.post( form.attr( 'action' ), values, form_ajax_submit_callback, 'json' );
			
			event.stopPropagation( );
			return false;
		};
		
		
		
		/**
		 * Take care of the UI for the form is submitted.
		 */
		function indicate_form_is_submitted( ){
			submitButton.val( 'Add comment' );
			addingMessage
				.animate(
					{ top: '-50px',
					  opacity: 0
					},
					300,
					function(){ addingMessage.remove( ); }
				);
		};
		
		
		
		/**
		 * Takes care of the UI to display a success message.
		 */
		function show_success_message( new_comment ){
			var successMessage = jQuery( '<span class="success-message">Your comment is added</span>' );
			form.append( successMessage );
			
			successMessage.css(
					{ top: '150px',
					  opacity: 0
					}
				).animate(
					{ top: '50px',
					  opacity: 1
					},
					400
				).animate(
					{ top: '-50px',
					  opacity: 0
					},
					400,
					function( ){ 
						new_comment.slideDown( 'slow' );
						successMessage.remove( ); 
						
					}
				);
		};
		
		
		
		/**
		 * Handles the UI for the error message for submitting the form.
		 */
		function display_the_errors( message, the_errors ){
			var failureMessage = jQuery( '<div class="failure-message">'+message+'</div>' );
			var errorList = jQuery( '<ul></ul' ).appendTo( failureMessage );
							
							for( error_field in the_errors ){
								switch( error_field ){
									case 'nounce':
									case 'belongs_to':
										errorList.append( '<li>Try reloading the page and try again.</li>' );
										break;
									
									case 'body':
										errorList.append( '<li>You cannot leave comment field empty.</li>' );
										break;
										
									case 'author_name':
										errorList.append( '<li>You need to give a name.</li>' );
										break;
										
									case 'author_email':
										errorList.append( '<li>You need to give an email address. It will be kept private.</li>' );
										break;
									
									case 'author_website':
										errorList.append( '<li>Your website URL, if you give one, needs to be a proper URL.</li>' );
										break;
									
									default:
										errorList.append( '<li>I have no idea what just went wrong.</li>' );
										break;
								}
							}
							
							failureMessage.append( jQuery( '<span class="close">Close</span>' )
								.click(
									function( ){
										failureMessage
											.animate(
											{ top: '-50px',
											  opacity: 0
											},
											400,
											function( ){ failureMessage.remove( );  }
										);
									}
								) );
							form.append( failureMessage );
							
							
							failureMessage.css(
									{ top: '150px',
									  opacity: 0
									}
								).animate(
									{ top: '50px',
									  opacity: 1
									},
									400
								);
										
										
		}
		
		
		
		
		/**
		 * The callback for the AJAX submission of the comment form.
		 */
		function form_ajax_submit_callback( data, textStatus ){
			indicate_form_is_submitted( );	
			
			
			// Check first the HTTP status
			if( textStatus == 'success' ){
				// Check the comment submission status
				if( data[ 'the_status' ] == 'success' && data.the_new_comment ){
									
					// Add comment
					var new_comment_html = '<tr id="comment-'+data.the_new_comment.id+'">';
					new_comment_html += '<td headers="comments-link-to"><a href="#comment-41">#comment-'+data.the_new_comment.id+'</a></td>';
					new_comment_html += '<td headers="comments-user-icon"><img width="80" height="80" alt="{Avatar Icon}" src="'+data.the_new_comment.gravatar+'"/></td>';
					if( data.the_new_comment.author_website ){
						new_comment_html += '<td headers="comments-name"><a href="'+data.the_new_comment.author_website+'">'+data.the_new_comment.author_name+'</a></td>';
					} else {
						new_comment_html += '<td headers="comments-name">'+data.the_new_comment.author_name+'</td>';
					}
					
					var date_created = new Date( Date.parse( data.the_new_comment.date_created ) );
					new_comment_html += '<td headers="comments-date">0 minutes ago</td>';
					new_comment_html += '<td headers="comments-comment">'+data.the_new_comment.body+'</td>';
					new_comment_html += '</tr>';
					var new_comment = jQuery( new_comment_html ).hide( );
					
					jQuery( '#comments table tbody' ).append( new_comment );
					
					show_success_message( new_comment );
					
										
					var ready_form_for_next_time = function( data, textStatus ){ 
						if( textStatus == 'success' ){
							form.find( '#id_body' ).val( '' );
							form.find( '#id_nounce' ).val( jQuery( data.the_comment_form.nounce.element ).val( ) );
							already_submitting = false;
						}
					};
					
					jQuery.get( 'new-comment/', {}, ready_form_for_next_time, 'json' );
					
				} else {	
					already_submitting = false;
					display_the_errors( 'The comment was not added.', data[ 'the_errors' ] );
				}
			} else {
				already_submitting = false;
				display_the_errors( 'A network error prevented your comment from being added. Try again', {} );
															
			}
		};
		
	}
);



