/**
 * Pageload
 */ 
window.addEvent('domready', function() {
  new Tabmenu('tabbed-menu', 'tabbed-menu-slider');
  
  var slideShow = new ASNSlideShow('.slide', {timeout:15000, duration:1000, playPauseBtn:$$('img#control-pause')});
  slideShow.start();
  
  SlideControls.init($$('#controls-help img'), slideShow); // Set slideshow controls
  
  $('slideshow-controls').setStyle('display', 'block');
  var controlPanel = $('slideshow-controls').effect('opacity', {duration:500, wait:false}).set(0);
  //new Fx.Slide('slideshow-controls', {duration:500});
//  $('slideshow-controls').setStyle('display', 'block');
  
  $('slideshow').addEvents({
    'mouseenter': function(){
      controlPanel.start(1);
    },
    'mouseleave': function(){
      controlPanel.start(0);
    }
  });
});



/**
 * Inline object
 */
var SlideControls = {
  init: function(controlHelpElem, slideShow){
    $$('#control-prev', '#control-next').addEvents({ // PREVIOUS & NEXT BUTTONS
      'mouseover': function(){
        (this.getProperty('id') == 'control-prev')? controlHelpElem.addClass('help-prev'): controlHelpElem.addClass('help-next');
        controlHelpElem.setStyle('display', 'block');
        controlHelpElem.getPrevious().setStyle('display', 'none');
      },
      'mouseout': function(){
        controlHelpElem.getPrevious().setStyle('display', 'block');
        controlHelpElem.setStyle('display', 'none');
        (this.getProperty('id') == 'control-prev')? controlHelpElem.removeClass('help-prev'): controlHelpElem.removeClass('help-next');
      },
      'click': function(){
        (this.getProperty('id') == 'control-prev')? slideShow.showPrevious(): slideShow.showNext();
      }
    });
    
    $('control-pause').addEvents({ // PAUSE / RESUME BUTTON
      'mouseover': function(){
        (slideShow.isActive())? controlHelpElem.addClass('help-pause'): controlHelpElem.addClass('help-resume');
        controlHelpElem.setStyle('display', 'block');
        controlHelpElem.getPrevious().setStyle('display', 'none');
      },
      'mouseout': function(){
        controlHelpElem.getPrevious().setStyle('display', 'block');
        controlHelpElem.setStyle('display', 'none');
        controlHelpElem.removeClass('help-pause');
        controlHelpElem.removeClass('help-resume');
      },
      'click': function(){
        (slideShow.isActive())? slideShow.stop(): slideShow.start();
      }
    });
  }
} // End inline SlideControls object



/***** Class declarations *****/

/**
 * Slideshow class
 * 
 * First active slide can be set using active-slide css class in html. This is
 * in turn overwritten if the startIndex is set in object initiation.
 * 
 * See option block below for possible options
 * 
 * NOTE: Since we're using a png in the header, it's not possible to fade in IE6
 */
var ASNSlideShow = new Class({
  slides     : [],
  slideTimer : null,
  currentSlideIndex : null,
  slideFx    : [],
  fadeFx     : [],
  isAnimating: false,
  browserIsIE6: false,
  
  options : {
    timeout    : 5000, // time to wait untill next slide
    duration   : 1000, // duration of the switching slides effect
    autoPlay   : false, // start playing as soon as slides have been initialised
    autoContinue : false, // start playing again after previous or next have been clicked (even if it was set to pause before)
    playPauseBtn : null, // if set, this class will change the playPauseBtn image
    playPauseImg : { play:'images/icons/ctrl-play.gif', pause:'images/icons/ctrl-pause.gif' } // the image names, used if playPauseBtn is set
  },
  
  initialize: function(slides, options){
    if( window.ie6 ) this.browserIsIE6 = true;
    
    $$(slides).each(function(slide, i){ // put slides in object array
      this.slides[i] = slide; // add slide to object array
      
      // effects init
      this.slideFx.include(new Fx.Slide(slide.getFirst().getFirst(), {duration:(this.options.duration / 2), mode:'horizontal'}).hide()); // add image slider for this slide
      if(! this.browserIsIE6 ) this.fadeFx.include(new Fx.Style(slide, 'opacity', {duration:this.options.duration}).set(0)); // add fade effect to whole slide
      
      if( slide.hasClass('active-slide') ){
        this.currentSlideIndex = i; // set startIndex to active-slide
        slide.removeClass('active-slide'); // make dynamic display block
        slide.setStyle('display', 'block');
      }
      
      if( this.browserIsIE6 ){
        var txtArea = slide.getChildren()[1];
        txtArea.getChildren().each(function(el){
          if( el.getTag() == 'a' ){
            txtArea.setStyle('cursor', 'pointer');
            txtArea.addEvents({
              'mouseover': function(){
                el.setStyle('textDecoration', 'underline');
              },
              'mouseout': function(){
                el.setStyle('textDecoration', 'none');
              },
              'click': function(){
                window.location = el.getProperty('href');
              }
            });
            return true; // exit loop
          }
        });
        
        
      }
    }.bind(this));
    
    this.setOptions(options); // customise options
    
    if( this.currentSlideIndex == null ){ // this means active-slide is not set. this should never happen, otherwise non-JS users won't see a thing
      this.currentSlideIndex = 0;
      this.slides[this.currentSlideIndex].setStyle('display', 'block');
    }
    
    // Set startvalues for effects
    this.slideFx[this.currentSlideIndex].show();
    if(! this.browserIsIE6 ) this.fadeFx[this.currentSlideIndex].set(1);
    
    if( this.options.autoPlay ) this.start();
  },
  
  /**
   * Start the slideshow
   * Starts at startIndex, or resumes at current slide if paused
   */
  start: function(){
    if( this.options.playPauseBtn ) this.options.playPauseBtn.setProperty('src', this.options.playPauseImg.pause);
    this.slideTimer = (function(){ this.showNext(true); }).delay(this.options.timeout, this);
  },
  
  /**
   * Stops the slideshow and changes playPauseBtn if set
   */
  stop: function(internal){
    if( !internal ) this.options.playPauseBtn.setProperty('src', this.options.playPauseImg.play);
    this.slideTimer = $clear(this.slideTimer);
  },
  
  /**
   * Show next slide in row
   */
  showNext: function(internal){
    if (this.slideTimer) this.stop(internal);
    
    if( $chk(this.currentSlideIndex) && this.currentSlideIndex < this.slides.length - 1 ){
      this._doSlide(this.currentSlideIndex + 1); // show next slide
    }else
    if( $chk(this.currentSlideIndex) ){
      this._doSlide(0); // wrap on last slide
    }
    
    if( internal || this.options.autoContinue ) this._preStart(); // cycle
  },
  
  /**
   * Show previous slide
   */
  showPrevious: function(){
    if( this.slideTimer ) this.stop();
    
    if( this.currentSlideIndex ){
      this._doSlide(this.currentSlideIndex - 1);
    }
    else {
      this._doSlide(this.slides.length - 1);
    }
    
    if( this.options.autoContinue ) this._preStart(); // cycle
  },
  
  /**
   * Returns true if the slideshow is active
   */
  isActive: function(){
    if( this.slideTimer )
      return true;
    else
      return false;
  },
  
  /**
   * Prestart provides extra wait time for the slide effects to take place
   */
  _preStart: function(){
    this.slideTimer = this.start.delay(this.options.duration, this);
  },
  
  /**
   * Handles the actual change of slides
   */
  _doSlide: function(newSlideIndex){
    if(! $chk(this.currentSlideIndex) ) return false; // No slides have been set
    if( this.isAnimating == true ) return false; // If user presses next or previous button to quickly
    this.isAnimating = true;
    
    var oldSlideIndex = this.currentSlideIndex;
    var oldSlide = this.slides[oldSlideIndex];
    var newSlide = this.slides[newSlideIndex];
    
    // effects
    if(! this.browserIsIE6 ){
      this.slideFx[oldSlideIndex].slideOut();
      this.fadeFx[oldSlideIndex].start(0).chain(function(){
        oldSlide.setStyle('display', 'none');
      });
    }
    else {
      oldSlide.setStyle('zIndex', 3);
      newSlide.setStyle('zindex', 2);
      this.slideFx[oldSlideIndex].slideOut();
      (function(){ oldSlide.setStyles({
          display : 'none',
          zIndex  : 1
         });
       }.delay(this.options.duration/2 - this.options.duration/10));
    }
    newSlide.setStyle('display', 'block');
    this.slideFx[this.slides.indexOf(newSlide)].show();
    if(! this.browserIsIE6 ) this.fadeFx[this.slides.indexOf(newSlide)].start(1);
    
    this.isAnimating = false;
    this.currentSlideIndex = newSlideIndex;
  }
});
ASNSlideShow.implement(new Options, new Events); // End ASNSlideShow.class



/**
 * Tabmenu class for MooTools
 * 
 * Handles the whole tab menu functionality
 * @param {string} tabContainer id of the <div> containing the tabs.
 * @param {string} menuPanel id of the element that contains the menu. Slide effect will be applied to this.
 */
var Tabmenu = new Class({
  // fixed parameters
  activeTab       : null,
  menuPanelOpen   : false,
  mouseOverPanel  : false,  
  tabResetTimer   : {},
  panelCloseTimer : null,
  tabLeftOffset   : 0,
  isIE6           : false,
  
  initialize: function(tabContainer, menuPanel, options){
    if( window.ie6 ) this.isIE6 = true;
    
    // create tab and menuPanel objects
    this.tabCollection = $$('#'+ tabContainer +' ul li');
    this.menuPanel = $(menuPanel);
    
    // set custom options
    this.options = $extend({
      tabContentPrefix : 'tab_',
      activeTabClass   : 'active',
      slideDuration    : 800, // duration of slide effect
      slideInTimeout   : 500, // time until panel closes on mouseout
      slideTransition  : Fx.Transitions.Sine.easeOut
    }, options || {});
    
    // instantiate the slider
    this.panelSlider = new Fx.Slide(this.menuPanel, {
      duration   : this.options.slideDuration,
      transition : this.options.slideTransition,
      wait       : false
    });
    this.menuPanel.setStyle('display', 'block');
    this.panelSlider.hide();
    
    // set eventlisteners on tabs
    this.tabCollection.each(function(tab) {
      tab.addEvent('mouseenter', function(){
        this.checkTimers(tab);
        this.resetOtherTabs(tab);
        this.activateTab(tab);
        if(! this.menuPanelOpen ) this.openMenuPanel();
      }.bind(this));
      
      tab.addEvent('mouseleave', function(){
        (function(){ // nested function required for delay
          if( this.activeTab != tab ){
            this.deactivateTab(tab);
          }
          else {
            if(! this.mouseOverPanel ){
              this.closeMenuPanel(tab);
            }
          }
        }.bind(this)).delay(5); // delay is needed, or panel might close prematurely
      }.bind(this));
      
      // Align content divs with tabs
      if( tab.getPrevious() ){
        if( this.isIE6 )
          this.tabLeftOffset += (tab.getPrevious().getCoordinates().width / 2);
        else
          this.tabLeftOffset += tab.getPrevious().getCoordinates().width;
        
        $(this.options.tabContentPrefix + tab.getProperty('title')).setStyle('margin-left', this.tabLeftOffset);
      }
    }.bind(this));
    
    // set eventlisteners on menu panel
    this.menuPanel.addEvent('mouseover', function(){
      if( this.menuPanelOpen ){
        this.checkTimers();
        this.mouseOverPanel = true;
      }
    }.bind(this));
    
    this.menuPanel.addEvent('mouseout', function(){
      if( this.menuPanelOpen ){
        this.mouseOverPanel = false;
        this.panelCloseTimer = (function(){this.closeMenuPanel(this.activeTab)}).delay(this.options.slideInTimeout, this);
      }
    }.bind(this));
  }, // End initialize
  
  activateTab: function(tab){
    this.activeTab = tab;
    tab.addClass(this.options.activeTabClass);
    tab.getFirst().addClass(this.options.activeTabClass);
    
    $(this.options.tabContentPrefix + tab.getProperty('title')).setStyle('display', 'block');
  },
  
  deactivateTab: function(tab){
    if( this.activeTab == tab ){
      this.activeTab = null; // only reset if theres no new active tab
    }
    tab.removeClass(this.options.activeTabClass);
    tab.getFirst().removeClass(this.options.activeTabClass);
    
    $(this.options.tabContentPrefix + tab.getProperty('title')).setStyle('display', 'none');
  },
  
  /**
   * If the mouse went from panel to a non-active tab, the previous active
   * tab should be deactivated.
   * @param {Object} newTab The tab that triggers the mouseover
   */
  resetOtherTabs: function(newTab){
    if( this.activeTab && this.activeTab != newTab ){
      this.deactivateTab(this.activeTab);
    }
  },
  
  openMenuPanel: function(){
    this.menuPanelOpen = true;
    this.panelSlider.slideIn();
  },
  
  closeMenuPanel: function(resetTab){
    if( this.mouseOverPanel ) this.mouseOverPanel = false;
    
    this.menuPanelOpen = false;
    this.panelSlider.slideOut();
    
    this.tabResetTimer = {
      tab  : resetTab,
      timer: (function(){this.deactivateTab(resetTab)}).delay(this.options.slideDuration, this)
    };
  },
  
  checkTimers: function(tab){
    if( this.panelCloseTimer  ){ // if slider is is set to close
      $clear(this.panelCloseTimer);
    }
    
    if( this.tabResetTimer.timer && tab ){ // if slider is still closing
      if( this.tabResetTimer.tab == tab ){
        this.clearTabResetTimer(false);
      }
      else {
        this.clearTabResetTimer(true);
      }
    }
  },
  
  clearTabResetTimer: function(resetTab){
    if( resetTab ){
      this.deactivateTab(this.tabResetTimer.tab);
    }
    $clear(this.tabResetTimer.timer);
    this.tabResetTimer = {};
  }
}); // End Tabmenu.class





