

var FeaturedAttractions = Class.create({		
	initialize: function(params){
	  	
		this.slides = $$(params['slides']);
		this.thumbs = $$(params['thumbs']);							

		// Ensure we have what we need
		if ((this.slides.length < 1) || (this.thumbs.length < 1))  { 
			return false; 
		}

		// Speed of slideshow
		this.delay = 5000;
		
		this.current_slide = null;		
		this.looping = true;
		this.animating = false;

		this.prepare_slides_and_thumbs();

		// Start the slide show
		setTimeout(this.loop.bind(this),this.delay);
	},


	// Hide all but the first slide
	prepare_slides_and_thumbs: function() {

		// Extract the name from the img src (ie: '/images/thumb_family.jpg' becomes 'family')
		this.thumbs.each(function(thumb, index){			
			thumb.attraction_index = index;
			thumb.id = 'thumb_' + index;
		}.bind(this));

		
		// Extract the name from the img src (ie: '/images/slide_family.jpg' becomes 'family')
		this.slides.each(function(slide, index){
			slide.attraction_index = index;
			slide.id = 'slide_' + index;
		}.bind(this));
		

		// Prepare slides and thumbs
		this.slides.each( function(slide) {

			// Get the thumb for this slide
			var thumb = $('thumb_'+slide.attraction_index);			
			slide.thumb = thumb;
			
			// While we're at it, set the slide for this thumb too
			thumb.slide = slide;
			
			// Also, all slides should be absolute (this isn't done in the css because initial page loads looks nicer this way)
			slide.setStyle({ position:'absolute' });
			
			// First Slide
			if (!slide.previous()) {				
				// Set current slide to this one
				this.current_slide = slide;
				// Set its thumb active
				thumb.addClassName('active');													
			
			// Not first slide
			} else {
				// Hide all these slides since they're not the first
				slide.setStyle({ display:'none' });	
			}
			
			// Last slide
			if (!slide.next()) {					
				// Set next slide to the first one (so it wraps around)
				slide.next_slide = slide.up().firstDescendant();																			
				
				
			// Not last slide
			} else {				
				// Set the next slide for the slideshow
				slide.next_slide = slide.next();
			}
			
		}.bind(this));		

		
		// Each thumb needs behavior
		this.thumbs.each( function(thumb){
			
			// Observe the click of each thumb
			thumb.down('a').observe('click', function(e){
				e.stop();
				
				// Turn off the slideshow loop
				this.looping = false;
				
				// Activate the chosen slide
				this.activate(thumb.slide);	
							
			}.bind(this));
		}.bind(this));
		
		// Allow overflow because there is a bit of extra room for the descriptions
		this.slides.first().up('ul').setStyle({ overflow:'visible' });		
	},
	
	
	activate: function(next_slide) {
		
		// Ensure a different slide was chosen
		if (this.current_slide.id == next_slide.id) { return false; }
		
		// Don't start a new animation if there is currently one happening
		if (this.animating) { return false; }
		this.animating = true;
		
		// Fade out the current slide and deactivate its thumb
		this.current_slide.thumb.removeClassName('active');
		Effect.Fade(this.current_slide);
				
		// Appear the new slide and activate its thumb
		next_slide.thumb.addClassName('active');
		Effect.Appear(next_slide, { afterFinish:function(){
			this.animating = false;
		}.bind(this)});
				
		// Update what the current slide is
		this.current_slide = next_slide;
	},
	
	loop: function() {
		
		// If looping is turned off, get out of here
		if (!this.looping) { return false; }
		this.animating = true;
		
		// Fade out the current slide and deactivate its thumb
		this.current_slide.thumb.removeClassName('active');
		Effect.Fade(this.current_slide);
		
		// Appear the new slide and activate its thumb		
		this.current_slide.next_slide.thumb.addClassName('active');
		Effect.Appear(this.current_slide.next_slide, { afterFinish:function(){
			this.animating = false;
		}.bind(this)});		
		
		// Update what the current slide is
		this.current_slide = this.current_slide.next_slide;
		
		// Do it all again 
		setTimeout(this.loop.bind(this),this.delay);
	}
	
});




var EventSubscription = Class.create({
			
	initialize: function(params){	  
		this.events = $$(params['events']);
		this.login = ($$(params['login']).length>0) ? true:false;
		this.notice = $$(params['notice']).first();
		
		// Ensure we have what we need
		if (this.events.length < 1) { 
			return false; 
		}
		
		// Login notice
		if (this.notice) {		  
		  // First hide the notice
		  new Effect.Fade(this.notice);		  
		  // Hide the notice when close is clicked
		  this.notice.down('a.close-window').observe('click',function(e){		  
		    new Effect.Fade(this.notice);
		    e.stop();
		  }.bind(this));
		}	
    
    // Set ajax behaviour for subscribe links
    this.events.each(function(event){
      event.down('a.subscribe-link-add').observe('click',this.subscribe.bind(this));
      event.down('a.subscribe-link-remove').observe('click',this.subscribe.bind(this));
    }.bind(this));
    
    // Toggle on subcribed events (if user is logged in)
    if (this.login) {
  		new Ajax.Request('/upcoming/events-as-json?by=user', {
  		  method: 'get',
  		  onSuccess: function(transport) {

          transport.responseJSON.each(function(event){ 
            this.toggle_subscription('event_'+event.id, 'on');
          }.bind(this));

  	    }.bind(this)
  	  });
  	}
	},
	
	subscribe: function(e) {
	  e.stop();
	  var link = Event.element(e);		  
	  var event = link.up('.upcoming-event');	  
	  
		if(this.login){
		  
  	  if (link.hasClassName('busy')) {
  	    return false;
  	  } else {
  	    link.addClassName('busy');
  	  }
  	  
  	  // Trigger the highlight -- needs colors specified here, unfortunately
  	  if (event.hasClassName('subscribed-event')){
        new Effect.Highlight(event, {endcolor:'#FFFFFF', restorecolor:'#FFFFFF', duration:2});
  	  } else {
  	    new Effect.Highlight(event, {endcolor:'#F3F3F5', restorecolor:'#F3F3F5', duration:2});
  	  }
      
      // Request this page with the ajax flag to make the page return much faster
      new Ajax.Request(link.href+'&ajax=1', {
			  method: 'get',
			  onSuccess: function(request) {
				  this.toggle_subscription(event);
				  link.removeClassName('busy');
			  }.bind(this)
			});
		
		// NOT LOGGED
		}else{
        if (!this.notice) { return }
        
        this.notice.setStyle({ 
          left: link.cumulativeOffset().first() - this.notice.getWidth() - 10 +'px',
          top:  link.cumulativeOffset().last() - this.notice.getHeight() + 42 +'px' 
        });
        new Effect.Appear(this.notice);
        new Effect.Highlight(this.notice.down('div'));
		}
	},

  toggle_subscription: function(event) {
	  if ($(event)) {
	    
	    // If force is set to on or off, do that
	    var force = (arguments[1]) ? (arguments[1]) : null;
	    switch(force) {
	      case 'on':
	        $(event).addClassName('subscribed-event');	        
	        return;
	        
	      case 'off':
	        $(event).removeClassName('subscribed-event');	        
	        return;	        
	    }

      // Otherwise, toggle the class
      if ($(event).hasClassName('subscribed-event')) {
        $(event).removeClassName('subscribed-event');
      } else {
        $(event).addClassName('subscribed-event');
      }

    }    
  }
	
});


var EventFilter = Class.create({
			
	initialize: function(params){		
		this.events = $$(params['events']);
		this.filters = $$(params['filters']);		
		
		// Ensure we have what we need
		if ((this.events.length < 1) || (this.filters.length < 1)) { 
			return false; 
		}
		
		// Create a hook to place filter notifications
		if (!$('filter_notification')) {
		  $$('h1').first().insert({after:'<div id="filter_notification"><a href="#all">[x]<span class="pretext">Filtered by "</span><span class="filter"></span><span class="postext">"</span></a></div>'});
		}
		$('filter_notification').hide();
		
		// Build list of filters (class names) actually in use
		this.active_filters = this.active_filters();

		// All of the filter link get click events
		this.filters.each(function(a){
			var event_filter = this.event_filter(a);						
			a.addClassName(event_filter);
			
			if (this.active_filters.include(event_filter)) {	
			
				a.observe('click', function(e){

					// Filter the events when clicked
					this.filter_events(a);			
					e.stop();

				}.bind(this));
			
			} else {
				a.up().addClassName('inactive-filter');
				a.up().update(a.innerHTML);
				return;
			}	
				
		}.bind(this));		
		
		// Filter the events based on the location bar (bookmarkable hash)
		this.filter_events();
		
		// Set click event for notification to unfilter all events			
		$('filter_notification').down('a').observe('click',this.unfilter_events.bind(this));
						
	},


	// Get all the unique class names used by all the events
	active_filters: function() {
		var classNames = [];
		this.events.each(function(div){			
			classNames = classNames.concat($w(div.className));
		}.bind(this));
		return classNames.uniq();
	},

	// Pass link to filter by, else it will use the location hash
	filter_events: function() {
		var link = (arguments[0]) ? (arguments[0]) : null;	
		var event_filter = this.event_filter(link);

		// If there's no filter, just do nothing
		if (!event_filter) {
			return false;
		}		

		// Update the filter notification. Also check if this is a valid filter
		var filter_link = $$('body')[0].down('a.'+event_filter);
		if (filter_link) {
			var filter_text = (filter_link.title) ? filter_link.title : filter_link.innerHTML;
			$('filter_notification').down('.filter').update(filter_text);
			if (!$('filter_notification').visible()) { Effect.BlindDown('filter_notification'); }
		} else {
			return false;
		}

		// Update the location bar with the new filter
		location.hash = event_filter;
		
		// Hide and show all the event divs based on the filter		
		this.events.each(function(event){
			if (event.hasClassName(event_filter)) {								
				event.show(); 
			} else {
				event.hide();
				//if (event.visible()) { Effect.BlindUp(event); }
			}
		});
		
		// Set the filter link to "active" and unset all others
		this.filters.each(function(a){
			a.removeClassName('active-filter');
			if (a.hasClassName(event_filter)) {
				a.addClassName('active-filter');
			}
		});	
	},
	
	// Pass link to filter by, else it will use the location hash
	unfilter_events: function() {
		
		//$('filter_notification').hide();
		Effect.SlideUp('filter_notification');
		
		// Hide and show all the event divs based on the filter
		this.events.invoke('show');
		this.filters.invoke('removeClassName','active-filter');
	},		

	
	// Returns the filter-class from a passed link, or the location
	event_filter: function() {
		var link = (arguments[0]) ? (arguments[0]) : null;		
		
		// If a link was provided, get the filter-class from that
		if (link) {			
			
			// Get everything inbetween /by- and # 
			// ie: "http://cs.calgarystampede.com/upcoming/by-day/2008-07-03#top" becomes "day/2008-07-03"
			var useful_part = link.href.split('/by-')[1].split('#')[0];
			
			// Pull type and value from link (day, 2008-07-03)
			var type = useful_part.split('/')[0];
			var value = useful_part.split('/')[1];
			
			// Return in the format of the class names (ie: day-2008-07-03)		
			return type+'-'+value;
			
		// If not, get the location's filter-class
		} else {
			
			// This is already in the right format, just needs to strip the # off
			var type_and_value = location.hash.split('#')[1];
			return (type_and_value) ? type_and_value : null;
		}		
	}	

});





var InputDefaultValue = Class.create({	
	
	initialize: function(field){
		// Ensure container exists
		if (!$(field)) { return false; }

		this.field = $(field);
		this.defaultValue = $F(this.field);
	
		// Clear field on click
		Event.observe(this.field, "click", function(){
			if ($F(this.field)==this.defaultValue) { 
				$(this.field).clear(); 
			}
			$(this.field).activate();
		}.bind(this));
	
		// Restore field's default text when empty
		Event.observe(this.field, "blur", function(){
			if (!$(this.field).present()) { 
				$(this.field).setValue(this.defaultValue); 
			}
		}.bind(this));
	}
});

		
document.observe("dom:loaded", function() {
	
	// Slideshow of attractions on the upcoming homepage
	new FeaturedAttractions({ 
		slides: '#featured_attractions ul.slides li', 
		thumbs: '#featured_attractions ul.thumbs li'
	});	
	
	// If on page /upcoming/user, mark all events as subscribed. 
	// This will happen anyway when EventSubscription is called, but this should get them sooner.
	if ($('page330')) {
	  $$('#col-two .upcoming-event').invoke('addClassName','subscribed-event');	  
	}
	
	// Discover the available filters, remove the unused, and allow events to filtered by them
	new EventFilter({ 
		events: '#col-two > div', 
		filters: '#filter_calendar a, #filter_interest a, #filter_venue a'
	});

  // Classify
	new EventSubscription({	  
	  events: '#col-two .upcoming-event',
	  login: '#logged_in',
	  notice: '#login_notice'
	});
	
	new InputDefaultValue('event-search');	

});

// Global Window Onload
Event.observe(window, 'load', function() {		
	//
});