/* -----------------------------------------------------------------------------
* g-countryselector.js
* Copyright 2010 wollzelle GmbH (http://wollzelle.com). All rights reserved.
* ------------------------------------------------------------------------------ */
(function(){
  var $ = document.id;
  
  /**
   * class GUCCI.CountrySelector < Class
   * 
   * Implements country selector overlay methods and properties
   * 
   **/
  GUCCI.CountrySelector = new Class({
  
    Implements: [Events, Options],
  
    options: {
      className: 'selector',
      maxRows: 27,
      choicesWidth: 600
    },
  
    initialize: function(element, options){
      this.origSelect = $(element);
      this.setOptions(options);
      this.opts = this.getOptionsGrouped();
      this.optsEls = this.getOptions();
      this.optsValues = this.optsEls.map(function(opt){ return opt.get('value') });
      this.defaultValue = this.optsValues[0];
      
      var self = this;
    
      this.fakeSelect = new Element('div', {
        'class': this.options.className + '_select', 
        'id': element.name+'_select'
      }).injectAfter(this.origSelect);
      
      this.container = new Element('div', {
        'class': 'b-overlay', 'id': element.name+'_choices',
        'id': 'country_choices'
      }).injectAfter(this.fakeSelect);
      var closeLink = new Element('a', { 'href': '#', 'class': 'js-close', 'rel': 'overlay:close' }).set('text', 'Close').inject(this.container)
      var ul = new Element('ul', { 'class': 'optgroups' }).inject(this.container);
    
      this.build(this.opts);
      this.origSelect.setStyle('display', 'none'); // Hide original select element
      this.setValue(this.defaultValue);
    
      this.container.addEvents({
        'click:relay(a.link-optgroup)': function(e){
          e.preventDefault();
        
          var prevGroup = this.getParent('ul').getElement('.optgroup.active .choices_options_wrapper');
          var newGroup =  this.getParent('li').getElement('.choices_options_wrapper');
        
          if($defined(prevGroup)) 
            prevGroup.morph({
              'left': -self.options.choicesWidth
            });
        
          newGroup.setStyles({
            'left': -self.options.choicesWidth
          }).morph({
            'left': 0
          });
          
          var activeLi = this.getParent('ul').getElement('li.active')
          if($defined(activeLi)) activeLi.removeClass('active');
        
          this.getParent().addClass('active');
        }
      });
    },
  
    getOptions: function(){
      return this.origSelect.getElements('option');
    },
  
    getOptionsGrouped: function(){
      return this.origSelect.getElements('optgroup').map(function(optgroup){
        var cList = [];
        cList = optgroup.getElements('option').map(function(option){
          return {
            'text': option.get('text'),
            'value': option.get('value')
          };
        });
      
        return {
          'label': optgroup.get('label'),
          'options': cList
        };
      });
    },
  
    build: function(data){
      data.each(function(optgroup){
        var col = 0,
            colWrapperEl,
            optGroupEl = this.createOptgroup(optgroup),
            wrapperEl = optGroupEl.getElement('.choices_options_wrapper');
            
        optGroupEl.inject(this.container.getElement('ul'));
        
        optgroup.options.each(function(option, idx){  
          // Create new column
          if(idx % this.options.maxRows == 0) {
            col++;
            colWrapperEl = new Element('div', { 'class': 'choices_options_col' });
            colWrapperEl.inject(wrapperEl);
          }
          this.createOption(option).inject(colWrapperEl);
        }, this);
      }, this);
    
      return this;
    },
  
    open: function(){
      this.fakeSelect.addClass('active')
      if(Browser.Engine.trident) this.container.setStyles({'visibility': 'visible', 'display': 'block'});
      this.container.addClass('b-overlay-active');
      return this;
    },
  
    close: function(){
      this.fakeSelect.removeClass('active');
      if(Browser.Engine.trident) this.container.setStyles({'visibility': 'visible', 'display': 'none'});
      this.container.removeClass('b-overlay-active');
      return this;
    },
  
    createOptgroup: function(data){
      var li = new Element('li', { 'class': 'optgroup' });
      new Element('a', { 'href': '#', 'class': 'link-optgroup', 'title': data.label}).set('text', data.label).inject(li);
      new Element('div', { 'class': 'choices_options_wrapper' }).set('morph', {
        duration: 1000,
        transition: 'cubic:in:out',
        link: 'cancel'
      }).inject(new Element('div', { 'class': 'choices_options' }).inject(li));
      
      return li;
    },
  
    createOption: function(data){
      return new Element('a', { 'class': 'option', 'href': data.value }).set('text', data.text).addEvent('click', function(event){
        event.preventDefault();
        this.setValue(data.text);
        this.close();
        var idx = this.optsValues.indexOf(data.value);
        this.origSelect.options[idx].selected = 'selected';
    		this.origSelect.fireEvent('change');
      }.bindWithEvent(this));
    },
  
    activateByIdx: function(idx){
      var option = this.origSelect.options[idx];
    
      // Set fake select element content
      this.setValue(option.get('text'));
    
      var prevGroup = this.container.getElement('.active .choices_options_wrapper');
      if($defined(prevGroup)) prevGroup.setStyle('left', -this.options.choicesWidth); // Deactivate prev optgroup if any was active
    
      this.container.getElements('.active').removeClass('active');
      // Activate option
      this.container.getElement('.choices_options_wrapper a.option[href="'+option.get('value')+'"]').addClass('active');
      
      // Activate options group
      this.container.getElement('.choices_options_wrapper a.active').getParent('.optgroup').addClass('active').getElement('.choices_options_wrapper').setStyle('left', 0);
    
      // Set real option to selected
      option.set('selected', 'selected');
      return option;
    },
    
    activateByValue: function(value){
      var l = this.origSelect.options.length;
      for(var i = 0; i < l; i++) {
        var opt = this.origSelect.options[i];
        // if(opt.selected) opt.selected = false; // Deselect active item
              
        if(opt.value === value) // Select new item
          this.activateByIdx(i);
      }
    },
  
    setValue: function(value){
      this.fakeSelect.set('html', '<a href="#country_choices" rel="overlay:open">' + value + '</a>');
      return this;
    }
  });
})();
