/* accordions.js
 * January 12, 2010 Jon Suderman
 * Pass css selector which points to accordions
 * var a = new Accordions('#content .accordion')
 *--------------------------------------------------------------------------*/
var Accordions = Class.create({
  accordions          : new Hash(),
  accordions_controls : new Hash(),
  accordions_container: null,
  skipped             : new Hash(),
  skipped_counter     : 0,
  duration            : 0.5,
  
  initialize: function(){
    $A(arguments).each(function(accordions_selector){
      this.accordion_assets = $$(accordions_selector)
      
      // Ensure the selector is valid
      if (this.accordion_assets.length < 1) { return false }

      // Get the container
      this.accordions_container = this.accordion_assets.first().up()  
      this.accordions_container.setStyle({visibility:'hidden'})
      
      this.namespace = this.accordions_container.identify()
      this.accordion_classname = 'accordion'
        
      this.skipped_template =   '<div id="#{skipped_id}" class="#{skipped_classname}_skipped">#{controls}'+
                                  '<div id="#{skipped_id}_content"></div>'+
                                '</div>'        
                                
      this.accordion_template = '<div id="#{accordion_id}" class="#{accordion_classname}">'+
                                  '<h2 class="#{accordion_classname}_head">#{controls}'+
                                    '<a class="toggle" href="##{accordion_id}">'+
                                      '<span class="title">#{accordion_title}</span>'+
                                      '<span class="view">+ View Details</span>'+
                                      '<span class="clear"></span>'+                                      
                                    '</a>'+
                                  '</h2>'+
                                  '<div class="#{accordion_classname}_body">'+
                                    '<div id="#{accordion_id}_content" class="#{accordion_classname}_content"></div>'+
                                  '</div>'+
                                '</div>'
      // Make it so
      this.parse_accordions()
      this.build_accordions()
      this.observe_accordions()      
      this.accordions_container.setStyle({visibility:'visible'})
      
    }.bind(this))
  },

  // Look for accordions inside the container and group them together
  parse_accordions: function() {

    // Mark all accordions
    this.accordion_assets.invoke('addClassName', this.namespace + '_accordion_asset')

    // Set default name for hash
    var skipped_accordion = 'skipped ' + this.skipped_counter
    this.skipped.set(skipped_accordion, true)
    this.accordions.set(skipped_accordion, []);

    // Set the current accordion as the default name
    current_accordion = skipped_accordion;

    // Each accordion contains everything up to the next accordion or end of container
    this.accordions_container.childElements().each(function(asset){ 

      // This asset is an accordion asset
      if (asset.hasClassName(this.namespace + '_accordion_asset')) {

        if (asset.hasClassName('stop')){
          this.skipped_counter++
          skipped_accordion = 'skipped ' + this.skipped_counter
          this.skipped.set(skipped_accordion, true)
          
          current_accordion = skipped_accordion
          
        } else {

          // Start a new section named after this accordion asset
          current_accordion = asset.down('span.title').innerHTML.strip();        
          
        }
        
        this.accordions.set(current_accordion,[]);

        // Save surf-to-edit controls if they are there
        var controls = asset.down('.pagecontent > div:first-child')
        if (controls){
          this.accordions_controls.set(current_accordion, '<div class="controls">' + controls.innerHTML + '</div>')
        }

      // This asset is any other kind
      } else {

        // Get the contents of this section and add the new contents to it
        this.accordions.get(current_accordion).push(asset.remove())
      }
    }.bind(this));
  },


  // Clear the container, print the accordion links, reprint all the content inside wrapping div's id'ed as accordions
  build_accordions: function() {

    // Clear out container 
    this.accordions_container.update('');

    // Loop through each key or accordion section
    this.accordions.keys().each(function(accordion_name) {

      // Get a half-decent id to use
      var accordion_id = accordion_name.toLowerCase()
      accordion_id = accordion_id.replace(/&amp;/g,'and');        // replace & with and
      accordion_id = accordion_id.replace(/ /g,'-');              // replace space with -
      accordion_id = accordion_id.replace(/\//g,'-');             // replace / with -
      accordion_id = accordion_id.replace(/\-\-/g,'-');           // reduce double - to single -
      accordion_id = accordion_id.replace(/[^A-Za-z0-9\-]/g,'');  // strip all non alpha, - characters 
    
      // Build accordion_id 
      var accordion_id = this.namespace + '_' + this.accordion_classname + '_' + accordion_id 
      
      // Add each accordion
      if (this.skipped.get(accordion_name)==true) {
        
        this.accordions_container.insert(this.skipped_template.interpolate({ 
          skipped_id: accordion_id,
          skipped_classname: this.accordion_classname,
          controls: (this.accordions_controls.get(accordion_name) || '')
        }))        
        
      } else {

        // Create the new accordion and add to the container
        this.accordions_container.insert(this.accordion_template.interpolate({ 
          accordion_id: accordion_id, 
          accordion_classname: this.accordion_classname,
          accordion_title: accordion_name,
          controls: (this.accordions_controls.get(accordion_name) || '')
        }))
      }
      
      // Load this section with all assets that belong to it
      this.accordions.get(accordion_name).each(function(asset){ 
        if ($(accordion_id + '_content')){ $(accordion_id + '_content').insert(asset) }
      }.bind(this))

    }.bind(this));
  },


  observe_accordions: function(){

    var all_accordions = $(this.accordions_container).select('.' + this.accordion_classname)
    all_accordions.each(function(accordion){
      // // Find current section
      // if ((!this.current_accordion) && (accordion.hasClassName('active'))) {
      //   this.open(accordion);
      //   this.current_accordion = accordion;      
      // }
      accordion.down('h2.' + this.accordion_classname + '_head a.toggle').observe('click', this.activate.bind(this, accordion), false)
      accordion.down('div.' + this.accordion_classname + '_body').hide()
    }.bind(this))

  },

  close : function(accordion) {
    if (!accordion) { return; }
    
    // Remove the old section's active class
    accordion.removeClassName('active');
    accordion.addClassName('animating');
    accordion.down('.view').update('+ View Details');
    
    // Animate up, and remove the open class when done
    new Effect.BlindUp( accordion.down('div.' + this.accordion_classname + '_body'), { 
      duration: this.duration,
      afterFinish: function() {
        accordion.removeClassName('open');
        accordion.removeClassName('animating');
        this.animating=false;        
      }.bind(this)
    });    
  },
  
  open : function(accordion) {    
    if (!accordion) { return; }  
    
    // Add the active class to the new panel (make it red)
    accordion.addClassName('active');
    accordion.addClassName('animating');              
        
    // Animate down, and add the open class when done
    new Effect.BlindDown( accordion.down('div.' + this.accordion_classname + '_body'), {   
      duration: this.duration,
      afterFinish: function(){
        accordion.addClassName('open');
        accordion.removeClassName('animating');        
        accordion.down('.view').update('- Hide Details');
        this.animating = false;        
      }.bind(this)
    });    
  },
  
  activate : function(accordion, event) {  
      
    var old_accordion = this.current_accordion;    

    // Do nothing if already animating or the current panel was clicked
    if (this.animating) { return false; }

    // Set flag
    this.animating = true;

    if (accordion.hasClassName('open')){
      this.close(accordion);
    } else {
      this.open(accordion);
    }

    // Update the current panel
    this.current_accordion = accordion;
    
    // Update the URL for any bookmarking
    location.hash = accordion.id.split(this.accordion_classname + '_').pop();
    
    // Don't the browser scroll up or down to the id
    if (event) { event.stop() }  
  }

});



