	
	/**
	 * @author
	 * dbeam@aegworlwide.com
	 * 
	 * @internal
	 * Season of Giving (SOG) prototype / class
	 * 
	 */

	var SOG =
	{
		// primitives & constants
		'errorMessage':'<span style="text-align:center;line-height:100px;display:block;">Failed to load events.</span>',
		'noEventsMessage':'<span style="text-align:center;line-height:100px;display:block;">There are no events at this time.</span>',
		'queries': [ ],
		
		// functions
		'assignInfoHandlers': function( el )
		{
			// assign click handlers
			$( '.sog-slider' ).each( function( )
			{
				var	opener		= $( this ),
					copy		= opener.find( '.sog-copy' );
					// images		= opener.find( '.sog-images' ),
					// imagesPad	= ( images.html( ).length > 0 ? 20 : 0 );
				
				opener.prev( ).find( '.sog-expander, .sog-title' ).click( function( )
				{
					// dynamically resize descriptions (affects height)
					// copy.css( { 'width': opener.width( ) - images.width( ) - imagesPad + 'px' } );
					
					var	srcEl		= $( this ),
						expandImg	= /img/i.test( this.nodeName ) ? srcEl : srcEl.parent( ).next( ).find( 'img.sog-expander' ),
						openHeight	= copy.height( ) + 15; // Math.max( copy.height( ),images.height( ) );
					
					// if not open
					if( opener.height( ) < openHeight )
					{
						expandImg.attr( 'src', '../img/sog_collapse_button.gif' );
						opener.animate( { 'height': openHeight + 'px' }, 300 );
					}
					else // close it
					{
						expandImg.attr( 'src', '../img/sog_expand_button.gif' );
						opener.animate( { 'height': '0px' } );
					}
		
					// try to avoid lag
					return false;
				} );
			} );
		},
		
		'buildEventList': function( jsonData )
		{
			if( !( jsonData instanceof Array ) ){ jsonData = [ jsonData ]; }
		
			for( var htmlContent = linksHTML = '', i = 0; i < jsonData.length; ++i, linksHTML = '' )
			{
				if( jsonData[ i ].links !== null )
				{
					for( var j = 0; j < jsonData[ i ].links.length; ++j )
					{
						if( jsonData[ i ].links[ j ].link_type_id != 12 )
						{
							linksHTML += ' | <a href="' + jsonData[ i ].links[ j ].url + '" target="_blank">' + jsonData[ i ].links[ j ].label + '</a>';
						}
					}
				}
				else { linksHTML = ''; }
				
				htmlContent +=	'<span class="sog-header">' +
									'<table id="sog-event-' + jsonData[ i ].id + '">' +
										'<th>' +
											'<span class="sog-date">' + jsonData[ i ].date + '</span>' +
											'<span class="sog-title">' + jsonData[ i ].title + '</span>' + 
											'<span class="sog-expander"><u>EVENT INFO</u></span> ' + linksHTML +
										'</th>' +
										'<td><img src="img/sog_expand_button.gif" class="sog-expander" /></td>' +
									'</table>' +
								'</span>' +
								
								'<span class="sog-slider charitydiv">' +
									'<span class="sog-copy">' + jsonData[ i ].description + '</span>' +
								'</span>';
			}
		
			$( '.sog-wrapper' ).html( htmlContent );
		},
		
		'fromMySQLDate': function( dateStr )
		{
			var	dates = dateStr.split( /-/ );
			return( new Date( dates[ 0 ], ( parseInt( dates[ 1 ] ) - 1 ), dates[ 2 ] ) );
		},
		
		'getFutureEvents': function( startTime, callback )
		{
			var	startDate = startTime || new Date;
			
			$( '.sog-daterange' ).html( 'Upcoming Events' );
			
			// we already did that query
			if( startDate in SOG.queries )
			{
				SOG.parseJSONResponse( SOG.queries[ startDate ] );
				if( typeof callback == 'function' ){ callback( SOG.queries[ startDate ] ); }
			}
			
			// if we haven't sent an XHR for this date range
			else
			{
				// get the JSON data via AJAX
				SOG.storeEventList
				(
					function( response )
					{
						// cache the response client-side
						SOG.queries[ startTime ] = response;
						
						// try to parse
						SOG.parseJSONResponse( response );
						
						// if a callback was sent, call it now!
						if( typeof callback == 'function' ){ callback( response ); }
					},
					
					// XHR GET params (put directly into $.get)
					{ 'start': startTime }
				);
			}
		},
		
		'getWeeklyEvents': function( startTime, callback )
		{
			var	startDate	= startTime || new Date( );
			var endDate		= new Date( startDate.getFullYear( ), startDate.getMonth( ), startDate.getDate( ) + 6 ); // + 1 week + 604800000
			
			$( '.sog-daterange' ).html( startDate.getMonth( ) + 1 + '/' + startDate.getDate( ) + ' - ' + ( endDate.getMonth( ) + 1 ) + '/' + endDate.getDate( ) );

			// we already did that query
			if( startDate + ' - ' + endDate in SOG.queries )
			{
				SOG.parseJSONResponse( SOG.queries[ startDate + ' - ' + endDate ] );
				if( typeof callback == 'function' ){ callback( SOG.queries[ startDate + ' - ' + endDate ] ); }
			}
			
			// if we haven't sent an XHR for this date range
			else
			{
				SOG.storeEventList
				(
					function( response )
					{
						// cache on client-side
						SOG.queries[ startDate + ' - ' + endDate ] = response;
						
						// try to parse
						SOG.parseJSONResponse( response );
						
						// if there was a callback sent, do it now!
						if( typeof callback == 'function' ){ callback( response ); }
					},
					
					// XHR GET params (put directly into $.get)
					{ 'start': SOG.toMySQLDate( startDate ), 'end': SOG.toMySQLDate( endDate ) }
				);
			}
		},
		
		'hideAllDetails': function( ) { $( '.sog-slider' ).animate( { 'height':'0px' }, 300 ); return false; },
		
		'parseJSONResponse': function( response )
		{
			try // to eval
			{
				if( response[ 0 ] === false )
				{
					$( '.sog-wrapper' ).html( SOG.errorMessage );
					$( '.sog-hideall-button' ).css( { 'display':'none' } );
				}
				else if( response[ 0 ] === null )
				{
					$( '.sog-wrapper' ).html( SOG.noEventsMessage );
					$( '.sog-hideall-button' ).css( { 'display':'none' } );
				}
				else // success
				{
					SOG.buildEventList( response );
					SOG.assignInfoHandlers( );
					$( '.sog-hideall-button' ).css( { 'display':'inline' } );
				}
			}
			
			// JSON malformed or some other failure
			catch( e ){ $( '.sog-wrapper' ).html( SOG.errorMessage ); return false; }
		},
		
		// ?parse=the&query=string&hopefully
		'queryStr': function( searchArg )
		{
			// if empty query string
			if( window.location.search == '' ){ return( typeof searchArg != 'undefined' ? false : [ ] ); }
			
			// split the query string by the & char
			var rawGets = window.location.search.substr( 1 ).split( '&' );
			
			for( var gets = { }, i = 0; i < rawGets.length; ++i )
			{
					// split the raw (param=val) by = (which is optional)
				var	get = rawGets[ i ].split( '=' ),
				
					// check if [] at end (query string array)
					getArray = /\[\]$/.test( get[ 0 ] ),
					
					// store the key name
					keyName = get[ 0 ].replace( /\[\]$/, '' ),
				
					// check if there's a value (not just a ?flag&), else a boolean( true )
					valOrBool = ( typeof get[ 1 ] != 'undefined' ? get[ 1 ] : true );
					
				// we have a param[] array
				if( getArray )
				{
					if( !( gets[ keyName ] instanceof Array ) ){ gets[ keyName ] = [ ]; }
					gets[ keyName ].push( valOrBool );
				}
				
				// write (or overwrite) the old value (this is default behavior afaik)
				else { gets[ keyName ] = valOrBool; }
			}

			// if we were searching for something
			if( typeof searchArg != 'undefined' ){ return( typeof gets[ searchArg ] != 'undefined' ? gets[ searchArg ] : false ); }
			
			// if we weren't searching for something, return every param
			return( gets );
		},
		
		'storeEventList': function( callback, params )
		{
			callback = ( typeof callback == 'function' ? callback : function(){} );
			// if( typeof SOG.loadingText != 'undefined' && $( '.sog-wrapper' ).html( ) != SOG.loadingText ){ $( '.sog-wrapper' ).html( SOG.loadingText ); };
			$.get( '../ajax/getSOGEvents.php', params || {}, function( response ){ callback( response ); }, 'json' );
		},
		
		'toMySQLDate': function( dateObj )
		{
			return( dateObj.getFullYear( ) + '-' + ( dateObj.getMonth( ) + 1 ) + '-' + ( dateObj.getDate( ) < 10 ? '0' : '' ) + dateObj.getDate( ) );
		}
	};
