/*
---

name: FunkyNavigation

description: Funky FX for navigation

authors: Rolf Langenhuijzen

license: MIT-style license.

requires: [Core, PowerTools!/Class.Binds, More/Fx.Elements]

provides: FunkyNavigation

...
*/

var FunkyNavigation = new Class({

	Implements: [Class.Binds, Events, Options],

	options: {
    containerId: 'container',
    containerFocusOpacity: 1,
    containerNoFocusOpacity: 1,
		activeLIIdentifier: '.li-active',
		activeAIdentifier: '.li-a-active',
		inactiveLIIdentifier: '.li-inactive',
		inactiveAIdentifier: '.li-a-inactive',
		activeLink: ''
	},

	initialize: function(options){
		this.setOptions(options);
    this.container = document.id(this.options.containerId);
    this.container.store('linkClicked', false);
		this.container.store('activeLink', '');
    this.buttonsDimmed = false;
    this.buttons = this.container.getElements('li');
	  this.buttons.each(function(btn){
      this.prepare(btn).attach(btn);
    }.bind(this));
		if (this.options.activeLink != '') this.initialState();
	},

  prepare: function(btn){
    var a = btn.getElement('a');
    btn.set({
      /*opacity: this.options.containerFocusOpacity,*/
      morph: {
        duration: Browser.ie ? 100 : 200,
        transition: Browser.ie ? 'sine:in' : 'cubic:out'
      }
    }).store('href', a.get('href'));
    a.set({
      title: '',
      morph: {
        duration: 100,
        transition: Browser.ie ? 'sine:in' : 'cubic:out'
      }
    });
    return this;
  },

  attach: function(element, attach){
    attach = attach != null ? attach : true;
    var method = attach ? 'addEvents' : 'removeEvents';
    element[method]({
      click: this.bound('handleClick').pass(element),
      mouseenter: this.bound('open').pass(element),
      mouseleave: this.bound('close').pass(element),
      close: this.bound('close'),
      closeFast: this.bound('closeFast').pass(element),
      open: this.bound('open')
    });
    return this;
  },

  detach: function(element){
    this.attach(element, false);
  },

  handleClick: function(btn){
    btn.store('active', true);
    var otherBtns = this.buttons.filter(function(element){
      if (element != btn) return true;
    });
    otherBtns.each(function(otherBtn){
      otherBtn.store('active', false).fireEvent('close', otherBtn);
    });
    this.container.store('linkClicked', true);
		var href = btn.retrieve('href');
		this.container.store('activeLink', href);
		this.fireEvent('linkClicked', href);
  },

  open: function(btn){
		btn.morph(this.options.activeLIIdentifier);
    btn.getElement('a').morph(this.options.activeAIdentifier);
    return this;
  },

  close: function(btn){
    if (!btn.retrieve('active')){
      btn.morph(this.options.inactiveLIIdentifier);
      btn.getElement('a').morph(this.options.inactiveAIdentifier);
    }
    return this;
  },

  closeFast: function(btn){
    if (!btn.retrieve('active')) {
      new Fx.Morph(btn).set(this.options.inactiveLIIdentifier);
			new Fx.Morph(btn.getElement('a')).set(this.options.inactiveAIdentifier);
    }
    return this;
  },

	initialState: function(){
		this.buttons.each(function(btn){
			if (btn.retrieve('href') == this.options.activeLink){
				btn.removeClass(this.options.activeLIIdentifier.substr(1, this.options.activeLIIdentifier.length));
				btn.getElement('a').removeClass(this.options.activeAIdentifier.substr(1, this.options.activeAIdentifier.length));
				new Fx.Morph(btn).set(this.options.activeLIIdentifier);
				new Fx.Morph(btn.getElement('a')).set(this.options.activeAIdentifier);
				btn.store('active', true);
				this.container.store('linkClicked', true);
				this.container.store('activeLink', this.options.activeLink);
			}
		}.bind(this));
		return this;
	},

	dim: function(state){
		if (state == null) state = true;
    this.buttonsDimmed = state;
    var activeBtns = this.buttons.filter(function(element){
      if (element.retrieve('active')) return true;
    });
    var otherBtns = this.buttons.filter(function(element){
      if (!activeBtns.contains(element)) return true;
    });
    if (!state){
      otherBtns.store('dimmed', false).removeClass('dim'); //.set('opacity', this.options.containerFocusOpacity);
    } else {
      otherBtns.store('dimmed', true).addClass('dim');
			/*
			//requires FX.Elements
      var obj = {};
  		otherBtns.each(function(otherBtn, i){
  			obj[i] = {
  			  'opacity': this.options.containerNoFocusOpacity
  			};
  		}.bind(this));
      new Fx.Elements(otherBtns, {
        link: 'cancel',
        duration: 600,
        transition: 'pow:in:out'
      }).start(obj);
			*/
    }
  },

	setActiveByLink: function(link){
		if (link == this.container.retrieve('activeLink')) return false;
    //Find correct button
    var btn = this.buttons.filter(function(element){
      if (element.retrieve('href') == link) return true;
    });
		if (btn.length === 0) return false;
		btn = btn[0]; //The filtered array should contain 1 match at position 0
		//Proceed with correct button
    btn.store('active', true);
		btn.removeClass('dim');
		//Get all other buttons that are currently marked as active (usually just 1)
    var otherBtns = this.buttons.filter(function(element){
      if (element != btn && element.retrieve('active')) return true;
    });
    otherBtns.each(function(otherBtn) {
      otherBtn.store('active', false);
      if (this.buttonsDimmed){
        otherBtn.fireEvent('closeFast', otherBtn);
				if (!otherBtn.hasClass('dim')) otherBtn.addClass('dim');
        //otherBtn.set('opacity', this.options.containerNoFocusOpacity)
      } else {
        otherBtn.fireEvent('close', otherBtn);
      }
    }.bind(this));
    btn.fireEvent('open', btn); //Style the new/active button
    this.container.store('linkClicked', true);
	}
});

