/***********************************************/
/* by Delyan Haralanov
/***********************************************/

var MooSlide = new Class({
  
  Implements: [Events, Options],
  
  options: {
    //onChange: $empty,
    
    tabs: [],
    next: [],
    previous: [],
    selected: 'selected',
    padding: 0,
    width: 0,
    useAnchors: true,
    wrap: true,
    animation: {
      duration: 500
    }
    
  },
  
  initialize: function(element, options){
    this.setOptions(options);
		this.element = $(element);
		this.document = this.element.getDocument();
		
		this.options.width = this.options.width ? this.options.width : this.element.getSize().x;
		this.options.padding = this.options.padding ? this.options.padding : this.element.getStyle('padding-left').toInt();
		
		this.element.setStyles({'overflow':'hidden', 'width':this.options.width, 'position':'relative'});
		
		this.animation = new Fx.Scroll(this.element, this.options.animation);
		
		this.tabs = new Array();
		
		this.panels = this.element.getChildren();
		if(this.panels.length == 0) return;
		this.panels.each(function(panel, index) {
		  // If Ajax show loading
		  var first = panel.getFirst();
		  if($type(first) == 'element' && first.get('tag') == 'a' && first.get('rel') == 'section'){
		    panel.store('request_url', first.get('href'));
		    panel.empty().grab(new Element('span', {'class':'loading', 'html':'Loading...'}));
		  }
		  
		  // Initiate the tabs Array for this panel
		  this.tabs[index] = new Array();
		  
		  // Set panel's default style
			panel.setStyles({
			  'display' : 'block',
			  'overflow': 'hidden',
			  'float': 'left',
			  'padding-left': this.options.padding + 'px',
			  'padding-right': this.options.padding + 'px',
			  'margin': '0',
			  'width': (this.options.width - 2 * this.options.padding) + 'px',
			  'height': panel.getSize().y ? '100%' : '1px',
			  'position': 'relative'
		  });
		},this);
		
		// Create wraper
		this.wrapper = new Element('div', {id:'slide-wrapper', styles:{width: (this.options.width * this.panels.length) + 'px', overflow:'hidden'}});
		this.wrapper.adopt(this.panels);
		this.element.adopt(this.wrapper);
		
		// Assign previous and next links
	  this.assignToPrevious(this.options.previous);
	  this.assignToNext(this.options.next);
	  
	  // Assign tab links
	  $splat(this.options.tabs).each(function(selector){
	    $$(selector).each(function(tab, index){
	      this.assignTo(tab, index);
	    }, this);
	  }, this);
		  
		// Init tab location
		if(this.options.useAnchors && location.hash && location.hash.slice(1).toInt() < this.panels.length){
		  this.current = location.hash.slice(1).toInt() - 1;
		  // Executes only once but still ugly... will be modified
		  new Fx.Scroll(this.element, {duration:0}).toElement(this.panels[this.current]);
		}else{
		  this.current = 0;
		}
		this.__select(this.current);

  },
  
  __select: function(panelNum){
    // Remove select class
    this.tabs[this.current].each(function(tab, index){
      tab.removeClass(this.options.selected);
    }, this);
    
    // Add select class
    this.tabs[panelNum].each(function(tab, index){
      tab.addClass(this.options.selected);
    }, this);
		
		// Load if Ajax
		var panel = this.panels[panelNum];
		var request_url = panel.retrieve('request_url');
		if($type(request_url) == 'string'){
		  panel.set('load', {
		    method: 'get',
		    autoCancel: true,
		    onComplete: function(panel){
		      // Loaded once for all
		      panel.store('request_url', null);
		      // Assign previous and next links in the loaded content
		      this.assignToNext(this.options.next, panel);
		      this.assignToPrevious(this.options.previous, panel);
		    }.bind(this, panel)
		  });
		  
		  // Delay the load function (otherwise breaks the animation when updates the element)
		  var load = function(){
		    this.load(request_url);
		  };
		  
		  load.delay(this.options.animation.duration, panel);
		}
  },
  
  __assign: function(parent){
    
  },
  
  goTo: function(event, panelNum){    
    if($type(event) == 'event') event.preventDefault(); else event = false;

    if(panelNum == this.current) return;
    
    var panel = this.panels[panelNum];
    
    this.fireEvent('onChange', [event, panel]);
    
    this.__select(panelNum);
    
    this.current = panelNum;
    if(this.options.useAnchors) location.hash = panelNum + 1;
    
    // Trigger the animation
    this.animation.cancel();
		this.animation.toElement(panel);
  },
  
  goToNext: function(event){
    if(this.current == this.panels.length - 1) this.goTo(event, (this.options.wrap ? 0 : this.current)); else this.goTo(event, this.current + 1);
  },
  
  goToPrevious: function(event){
    if(this.current == 0) this.goTo(event, (this.options.wrap ? this.panels.length - 1 : this.current)); else this.goTo(event, this.current - 1);
  },
  
  assignTo: function(tab, panelNum, parent){
    this.tabs[panelNum].include(  $(tab).setProperty('href', '#' + (panelNum + 1)).addEvent('click', this.goTo.bindWithEvent(this, panelNum)) );
  },
  
  assignToNext: function(selectors, parent){
    parent = $type(parent) == 'element' ? parent : this.document;
    $splat(selectors).each(function(selector){
      parent.getElements(selector).each(function(link, index){
        link.setProperty('href', '#').addEvent('click', this.goToNext.bindWithEvent(this));
      }, this);
    }, this);
  },
  
  assignToPrevious: function(selectors, parent){
    parent = $type(parent) == 'element' ? parent : this.document;
    $splat(selectors).each(function(selector){
      parent.getElements(selector).each(function(link, index){
        link.setProperty('href', '#').addEvent('click', this.goToPrevious.bindWithEvent(this));
      }, this);
    }, this);
  }
  
});
