jQuery( document ).ready( function( ){
	var short_months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
	                     'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
	
	
	var next_page_of_results = jQuery( '<span id="next-page-of-results-control" class="page-results-control disabled"><span class="number"></span><span class="arrow">&#x25BA;</span></span>' );
	var previous_page_of_results = jQuery( '<span id="previous-page-of-results-control" class="page-results-control disabled"><span class="arrow">&#x25C4;</span><span class="number"></span></span>' );
	
	var submit_button = jQuery( '#search-submit-button' );
	var updating = false;
	
	var checkbox_q = jQuery( '<input type="checkbox" />' );
	var checkbox_blog = jQuery( '<input type="checkbox" checked="checked" />' );
	var checkbox_playground = jQuery( '<input type="checkbox" checked="checked" />' );
	var checkbox_date = jQuery( '<input type="checkbox" />' );
	
	var date_selection_state = 'picked';
	
	
	var progress_indicator = function( ){
		submit_button.css( 'background-color', null );
		if( updating ){
			submit_button
				.css( 'background-color', '#005FD9' )
				.animate( { backgroundColor: '#A8D0FF' }, 250 )
				.animate( { backgroundColor: '#005FD9' }, 250, progress_indicator );
		}
	};
	
	
	
	
	//
	// new_query - 0: new, 1: next, 2: previous
	var update_results = function( form_values, new_query ){
		// indicate progress to the user
		updating = true;
		progress_indicator( );
		submit_button
				.blur( )
				.val( 'Updating...' );
		
		new_query = new_query === undefined? 0: new_query;
		
		jQuery.getJSON( '/super-search/', form_values,
			function( data ){
				submit_button.val( 'Update' );
				updating = false;
				var old_results = jQuery( '#search .results ol, #search .results .no-matches' );
				
				
				if( data.count > 0 ){
					var new_results = jQuery( '<ol></ol>' ).appendTo( '.results' );
					
					// Add results to new results
					for( var i=0; i<data.results.length; ++i ){
						var d = new Date( data.results[ i ].date );
						new_results.append( '<li><a href="'+data.results[ i ].url+'">'+data.results[ i ].title+'</a>  <small class="date">'+d.getFullYear( )+' '+short_months[ d.getMonth( ) ]+' '+d.getDate( )+'</small> <p>'+data.results[ i ].excerpt+'</p></li>' );
					}
				} else {
					var new_results = jQuery( '<div class="no-matches">No matches. <span class="try-another">Try another query.</span></div>' ).appendTo( '.results' );
				}

				// Animate transition
				var old_results_animate = { opacity: 0 };
				var new_results_css = { opacity: 0 };
				if( new_query == 1 ){ // next
					old_results_animate[ 'left' ] = '0px';
					new_results_css[ 'left' ] = '200px';
					
				} else if( new_query == 2 ){ // previous
					old_results_animate[ 'left' ] = '200px';
					new_results_css[ 'left' ] = '0px';
					
				} else { // new
					old_results_animate[ 'top' ] = '0px';
					new_results_css[ 'top' ] = '200px';
					
				}
				
				var animation_time = 500;
				
				
				old_results
					.animate(
						old_results_animate,
						animation_time*2,
						function( ) { old_results.remove( ); } 
					);
					
				new_results
					.css( new_results_css );
				setTimeout( function(){ 
					new_results
						.animate( 
							{ top: 0,
							  left: '100px',
							  opacity: 1 },
							animation_time*2
						);
					}, 
					animation_time );
				
					
				
				
				// Setup the next and previous
				
				// previous page
				if( data.has_previous ){
					previous_page_of_results
						.removeClass( 'disabled' )
						.unbind( 'click' )
						.click( function( e ){
							form_values[ 'page' ] = data.previous_page_number;
							update_results( form_values, 2 );
						} )
						.children( '.number' )
							.text( data.previous_page_number );
				} else {
					previous_page_of_results
						.addClass( 'disabled' )
						.unbind( 'click' )
						.children( '.number' )
							.text( '' );
				}
				
				// next page
				if( data.has_next ){
					next_page_of_results
						.removeClass( 'disabled' )
						.unbind( 'click' )
						.click( function( e ){
							form_values[ 'page' ] = data.next_page_number;
							update_results( form_values, 1 );
						} )
						.children( '.number' )
							.text( data.next_page_number );
				} else {
					next_page_of_results
						.addClass( 'disabled' )
						.unbind( 'click' )
						.children( '.number' )
							.text( '' );
				}
			} );
			
	};
	
	// Create the toggles
	
	// The show action for the toggle,
	// param toggleButton, the button to toggle
	var toggle_show_action = function( toggleButton ){
		if( !toggleButton.data( 'sub-showing' ) ){
			jQuery( toggleButton.data( 'sub' ) )
				.slideDown( );
			toggleButton
				.addClass( 'toggle-hide-button' )
				.removeClass( 'toggle-show-button' )
				.html( '&#x25B4;' )
				.attr( 'title', 'Hide' )
				.data( 'sub-showing', true );
		}
	};
	
	var toggle_hide_action = function( toggleButton  ){
		if( toggleButton.data( 'sub-showing' ) ){
			jQuery( toggleButton.data( 'sub' ) )
				.slideUp( );
			toggleButton
				.addClass( 'toggle-show-button' )
				.removeClass( 'toggle-hide-button' )
				.html( '&#x25BE;' )
				.attr( 'title', 'Show' )
				.data( 'sub-showing', false );
		}
	};
	
	var toggle_toggle_action = function( toggleButton ){
		if( toggleButton.data( 'sub-showing' ) ){
			toggle_hide_action( toggleButton );
		} else {
			toggle_show_action( toggleButton );
		}
	};
		
	// The toggles for the sub box sub options
	var toggle_buttons = { 'date': null, 'blog': null, 'playground': null };
	
	for( var i in toggle_buttons ){
		toggle_buttons[ i ] = jQuery( '<span class="toggle-button">&#x25BE;</span>' );
		var sub = jQuery( '#search-'+i+'-control-box .sub' ).before( toggle_buttons[ i ] ).hide( );
		toggle_buttons[ i ]
			.data( 'sub', sub )
			.data( 'sub-showing', false )
			.click( function( ){ toggle_toggle_action( jQuery( this ) ); } );
		
	}
		
		
		
		
		
	
	
	// Create the checkboxes
	// checkbox q
	jQuery( '#search-search-control-box label.header' )
		.prepend( checkbox_q );
	var input_q = jQuery( '#q' );
	var monitor_q_timeout_id = 0;
	var monitor_q = function( ){
		if( jQuery.trim( input_q.val( ) ) == '' ){
			checkbox_q.attr( 'checked', false );
		} else {
			checkbox_q.attr( 'checked', true );
		}
	};
	input_q
		.focus( function( e ){
			monitor_q( );
			monitor_q_timeout_id = setInterval( monitor_q, 500 ); 
		} )
		.blur( function( e ) {
			clearInterval( monitor_q_timeout_id );
			monitor_q( );
		} );
	
	
	// checkbox blog
	jQuery( '#search-blog-control-box label.header' )
		.prepend( checkbox_blog );
	
	
	// checkbox playground
	jQuery( '#search-playground-control-box label.header' )
		.prepend( checkbox_playground );
	
	
	// checkbox date
	jQuery( '#search-date-control-box label.header' )
		.prepend( checkbox_date );
	
	
	
	
	
	// add date picker
	( function( ){
		var is_digits = /[0-9]+/;
		
		var date_start_select = jQuery( '#date_start' ).hide( );
		var date_end_select = jQuery( '#date_end' ).hide( );
		
		var month_buttons = {};
		
		jQuery( '#search-date-control-box .sub label' ).hide( );
		
	   var min = false;
	   var max = false;
	   
	   date_start_select
	   	.children( 'option' )
	   	.each( function( ){
	   		if( is_digits.test( this.value ) && ( min === false || min > parseInt( this.value ) ) ){
	   			min = parseInt( this.value );
	   		} 
	   		
	   		if( is_digits.test( this.value ) && ( max === false || max < parseInt( this.value ) ) ){
	   			max = parseInt( this.value );
	   		}
	   	} );
		
		var min_year = parseInt( min / 100 );
		var min_month = parseInt( min % 100 );
		
		var max_year = parseInt( max / 100 );
		var max_month = parseInt( max % 100 );
		
		var date_picker = jQuery( '<ol class="date-range-picker"></ol>' )
			.appendTo( '#search-date-control-box .sub' );
		
		// First year
		var year_elem = jQuery( '<li><span class="year">'+min_year+'</span></li>' )
			.appendTo( date_picker );
		var months = jQuery( '<ol></ol>' )
			.appendTo( year_elem );
		for( var month=min_month; month<=12; ++month ){
			var month_elem = jQuery( '<li>'+short_months[ month-1 ]+'</li>' )
				.appendTo( months );
			month_buttons[ min_year*100 + month ] = month_elem;
			month_elem
				.data( 'year', min_year )
				.data( 'month', month );
		}
		
		// between years
		for( var year = min_year+1; year<max_year; ++year ){
			year_elem = jQuery( '<li><span class="year">'+year+'</span></li>' )
				.appendTo( date_picker );
			months = jQuery( '<ol></ol>' )
				.appendTo( year_elem );
			for( var month=1; month<=12; ++month ){
				var month_elem = jQuery( '<li>'+short_months[ month-1 ]+'</li>' )
					.appendTo( months );
				month_buttons[ year*100 + month ] = month_elem;
				month_elem
				.data( 'year', year )
				.data( 'month', month );
			}
		}
		
		// last year
		year_elem = jQuery( '<li><span class="year">'+max_year+'</span></li>' )
			.appendTo( date_picker );
		months = jQuery( '<ol></ol>' )
			.appendTo( year_elem );
		for( var month=1; month<=max_month; ++month ){
			var month_elem = jQuery( '<li>'+short_months[ month-1 ]+'</li>' )
				.appendTo( months );
			month_buttons[ max_year*100 + month ] = month_elem;
			month_elem
				.data( 'year', max_year )
				.data( 'month', month );
		}
		
		
		
		var select_date_range = function( a_year, a_month, b_year, b_month, selecting ){
			selecting = !!selecting;
			if( a_year < b_year || ( a_year == b_year && a_month < b_month ) ){
				var min_year = a_year;
				var min_month = a_month;
				var max_year = b_year;
				var max_month = b_month;
			} else {
				var min_year = b_year;
				var min_month = b_month;
				var max_year = a_year;
				var max_month = a_month;
			}
			
			// clear out the last selection
			for( var i in month_buttons ){
				if( !selecting ){
					month_buttons[ i ]
						.removeClass( 'in-range' )
						.removeClass( 'start-range' )
						.removeClass( 'end-range' );
				}
				month_buttons[ i ]
					.removeClass( 'in-selecting-range' )
					.removeClass( 'start-selecting-range' )
					.removeClass( 'end-selecting-range' );
			}
			
			if( selecting ){
				month_buttons[ min_year*100 + min_month ].addClass( 'start-selecting-range' );
				month_buttons[ max_year*100 + max_month ].addClass( 'end-selecting-range' );
			} else {
				month_buttons[ min_year*100 + min_month ].addClass( 'start-range' );
				month_buttons[ max_year*100 + max_month ].addClass( 'end-range' );
			}
			
			var year = min_year;
			var month = min_month;
			while(  year*100 + month <= max_year*100 + max_month ){
				if( selecting ){
					month_buttons[ year*100 + month ].addClass( 'in-selecting-range' );
				} else {
					month_buttons[ year*100 + month ].addClass( 'in-range' );
				}
				
				year = year + parseInt( month / 12 );
				month = ( month % 12 ) + 1;
			}
			
			if( !selecting ){
				date_start_select.val( min_year*100 + min_month );
					//.children( 'option[value='+( min_year*100 + min_month )+']')
						//.attr( 'checked', true );
				
				date_end_select.val( max_year*100 + max_month );
					//.children( 'option[value='+( max_year*100 + max_month )+']' )
					//	.attr( 'checked', true ); 
			}
		};
		
		
		
		
		
		// select all dates by default
		select_date_range( min_year, min_month, max_year, max_month );
		
		
		( function( ){
			
			
			var start_year = min_year;
			var start_month = min_month;
			
			date_picker
				.click( function( event ){
					var t = jQuery( event.target );
					if( t.data( 'year' ) ) {
						checkbox_date.attr( 'checked', true );
						
						var year = t.data( 'year' );
						var month = t.data( 'month' );
						
						if( date_selection_state == 'picked' ){
							date_selection_state = 'picking';
							start_year = year;
							start_month = month;
						} else {
							date_selection_state = 'picked';
							checkbox_date.attr( 'checked', true );
						}
						// we want to have this run both for the second click and well as the first click
						select_date_range( start_year, start_month, year, month );
					}
				} );
			date_picker
				.mouseover( function( event ){
					var t = jQuery( event.target );
					if( t.data( 'year' ) && date_selection_state == 'picking' ) {
						var year = t.data( 'year' );
						var month = t.data( 'month' );
						select_date_range( start_year, start_month, year, month, true );
					}
				} );
			} )( );
			
	} )( );
	
	
	jQuery( '#search' )
		.append( '<div class="results"><ol></ol></div>' )
		.append( next_page_of_results )
		.append( previous_page_of_results )

		.submit( function( e ){
			date_selection_state = 'picked'; // in case the user only wanted one month and didn't click it twice.
			
			var form_values = { };
			
			jQuery( '#search :checkbox:checked' )
				.each( function( ){
					if( !form_values[ this.name ] ){
						form_values[ this.name ] = [ ];
					}
					form_values[ this.name ].push( this.value );
				} );
			
			jQuery( '#search select' )
				.each( function( ){
					form_values[ this.name ] = jQuery( this ).val( );
				} );
			
			jQuery( '#search :text' )
				.each( function( ){
					form_values[ this.name ] = jQuery( this ).val( );
				} );
			
			if( !checkbox_q.attr( 'checked' ) ){
				form_values[ 'q' ] = '';
			}
			
			if( !checkbox_blog.attr( 'checked' ) ){
				form_values[ 'blog' ] = 'none';
			}
			
			if( !checkbox_playground.attr( 'checked' ) ){
				form_values[ 'playground' ] = 'none';
			}
			if( !checkbox_date.attr( 'checked' ) ){
				form_values[ 'date_start' ] = '';
				form_values[ 'date_end' ] = '';
			}
			
			update_results( form_values );
			
			e.stopPropagation( ); 
			return false;
		} )
		.submit( ); 
	
	
});

