/* tabs.js
 * September 8, 2010 Jon Suderman
 * Pass css selector which points to tabs
 * eg: <div id="main">...<h2 class="tab">One</h2>...<h2 class="tab">Two</h2>...</div>
 * var t = new Tabs('#main_wide .tab')
 *--------------------------------------------------------------------------*/
var Tabs = Class.create({
  sections            : {},
  sections_container  : null,
  tabs_container_id   : null,
  tabs_container      : null,
  preface_id          : null,
  preface             : null,

  initialize: function(){
    $A(arguments).each(function(tabs_selector){
      this.tabs = $$(tabs_selector)

      // Ensure the selector is valid
      if (this.tabs.length < 1) { return false }

      // Get the container
      this.sections = new Hash()
      this.sections_container = this.tabs.first().up()
      this.sections_container.setStyle({visibility:'hidden'})

      this.namespace = this.sections_container.identify()
      this.section_classname = 'tab_section'

      this.tabs_container_name = 'tabs_container'
      this.preface_name = 'preface'

      this.preface_template = '<div id="#{preface_id}"></div>'
      this.section_template = '<div id="#{section_id}" class="#{section_classname}"></div>'
      this.tabs_container_template = '<ul id="#{tabs_container_id}" class="tabs_container"></ul>'
      this.tab_template = '<li><a href="##{tab_id}" rel="#{tab_id}"><span>#{tab_name}</span></a></li>'

      // Make it so
      this.parse_tabs()
      this.build_tabs()
      this.observe_tabs()
      this.sections_container.setStyle({visibility:'visible'})

    }.bind(this))
  },

  // Look for span.tab's inside the container and group them together
  parse_tabs: function() {

    // Mark all tabs
    this.tabs.invoke('addClassName', this.namespace + '_tab')

    // Set default name for hash
    this.sections.set(this.preface_name,[]);

    // Set the current tab as the default name
    current_tab = this.preface_name;

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

      // This asset is a tab asset
      if (asset.hasClassName(this.namespace + '_tab')) {

        // Start a new section named after this tab asset
        current_tab = "tab_"+asset.innerHTML.strip();
        this.sections.set(current_tab,[]);

      // This asset is any other kind
      } else {

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


  // Clear the container, print the tab links, reprint all the content inside wrapping div's id'ed as tabs
  build_tabs: function() {

    this.preface_id = this.namespace + '_' + this.section_classname + '_' + this.preface_name
    this.tabs_container_id = this.namespace + '_' + this.tabs_container_name

    // Clear out container leaving the preface and the tabs ul
    this.sections_container.update(
      this.preface_template.interpolate({ preface_id: this.preface_id }) +
      this.tabs_container_template.interpolate({ tabs_container_id: this.tabs_container_id })
    );

    // Now that the UL finally exists, create a shortcut to it
    this.preface = $(this.preface_id)
    this.tabs_container = $(this.tabs_container_id)


    // Loop through each key or tab section
    this.sections.keys().each(function(tab_name) {

      // Get a half-decent id to use
      var tab_id = tab_name.toLowerCase()
      tab_id = tab_id.replace(/tab_/g,'');           // remove string prefix
      tab_id = tab_id.replace(/&amp;/g,'and');       // replace & with and
      tab_id = tab_id.replace(/ /g,'-');             // replace space with -
      tab_id = tab_id.replace(/\//g,'-');            // replace / with -
      tab_id = tab_id.replace(/\-\-/g,'-');          // reduce double - to single -
      tab_id = tab_id.replace(/[^A-Za-z0-9\-]/g,''); // strip all non alpha, - characters

      // Build section_id based off tab_id
      var section_id = this.namespace + '_' + this.section_classname + '_' + tab_id

      // Add each tab (except for the default, which is really everything before the first real tab)
      if (tab_name!=this.preface_name) {
        this.tabs_container.insert( this.tab_template.interpolate({ tab_id:tab_id, tab_name:tab_name.replace('tab_','')}) )

        // Create the new tab section and add to the container
        this.sections_container.insert(this.section_template.interpolate({
          section_id: section_id,
          section_classname: this.section_classname
        }))
      }

      // Load this section with all assets that belong to it
      this.sections.get(tab_name).each(function(asset){
        $(section_id).insert(asset)
      }.bind(this))

    }.bind(this));

    // The "preface" tab isn't really a tab, so just remove the classname.
    this.preface.removeClassName(this.section_classname);
  },


  observe_tabs: function(){

    // Set click events for each tab
    this.tabs_container.select('a').each(function(a) {
      a.observe('click', this.active_tab.bind(this,a));
    }.bind(this));

    // Activate the tab that's in the hash
    if (location.hash != '') {
      this.tabs_container.select('a[href$="'+ location.hash +'"]').each(this.active_tab.bind(this));
    }

    // If no tab is active, select the first one
    if (this.tabs_container.select('a.active').length<1) {
      if (first_tab = this.tabs_container.down('a')) {
        this.active_tab(first_tab);
      }
    }
  },


  active_tab: function(a,event){

    // Hide all sections and unclass all tabs from being active
    this.sections_container.select('.' + this.section_classname).invoke("hide");
    this.tabs_container.select('a').invoke('removeClassName','active')

    // Show the section and set the clicked tab as active
    $(this.namespace + '_' + this.section_classname + '_' + a.rel).show();
    $(a).addClassName('active');
    
    // Show the relevant map if there is a map on the page
    try {
      var mapURL = $(this.namespace + '_' + this.section_classname + '_' + a.rel)
          .select("div[class='map']")[0].readAttribute('data-source');
      if (mapURL) {
        var mapChildNodes = $("map_container").descendants();
        mapChildNodes[0].writeAttribute('src', mapURL);
        mapChildNodes[3].writeAttribute('href', mapURL);
        console.log(mapURL);
      }
    }catch(e){}    

    // Update the URL for any bookmarking
    location.hash = a.rel;

    // Don't the let browser scroll up or down to the id
    if (event) { event.stop() }
  }

});

