/* Button object */

(function($) {

  var buttons = new Array();

  this.b_button_OPTIONS = {
    selfInit: false,
    defaultName: "button",
    className: "b-button",
    formClass: "b-button_form",
    template:
      '<div class="b-button" bindEvents="mousedown,mouseup,mouseover,mouseout">' +
        '<table><tr><td>' +
          '<div class="b-button-bg">' +
            '<i class="l g-png"></i><i class="r g-png"></i>' +
          '</div>' +
          '<div class="b-button-text" attachData="value">' +
            '<i class="b-button-icon g-png"></i>' +
          '</div>' +
        '</td></tr></table>' +
      '</div>'
  };

  this.b_button_IDs = 0;

  if(b_button_OPTIONS.selfInit){
    //Self-init:
    $(document).ready(function(){
      GLOBAL.reInit(function(){
        b_button_init();
      })
    })
  }

  // Force init:
  this.b_button_init = function(str){
    if(str){
      var obj = document.getElementById(str);
      if(obj){
        var jobj = $(obj);
        if(jobj.find(".b-button_form").length)
          new b_button_group(obj);
        else
          new b_button(obj);
      } 
    } else {

      $("*[buttonType=group]").each(function(){
        new b_button_group(this);
      })
      $("button[buttonType]").each(function(){
        new b_button(this);
      })

    }
  }

  
  this.b_button = function(){
    return this.init.apply(this, arguments);
  }

  b_button.prototype = {
    init: function(obj, options){
      this.options = $.extend(b_button_OPTIONS, options ? options : {});

      this.domNode = $(obj);
      
      var b = this.isExist();
      if(b){ return b; }

      this.is = {
        prevent: true,
        stateBubble: true,
        template: false
      };

      if(this.domNode.find("." + this.options.className).length)
        this.is.template = true;
        
      this.old = {} // save here old states if it changes

      this.o = {
        type: this.domNode.attr("buttonType"),
        confirm: this.domNode.attr("confirm")
      };

      this.checked = false;
      this.name = this.domNode.attr("name") ? this.domNode.attr("name") : this.options.defaultName + b_button_IDs++;

      // events for append
      this.e = {
        list: ["mousedown", "mouseup", "mouseover", "mouseout"],
        onstatechange: this.domNode.attr("onstatechange") ? this.domNode.attr("onstatechange") : function(){}
      };
      

      if(!this.is.template){

        this.value = this.domNode.html();
        
        // data for append
        this.d = {
          value: this.value
        }

        var checkedLabel = this.domNode.attr("checkedLabel");
        if(checkedLabel && checkedLabel.length){
          this.d.value = '' +
            '<span class="off">' + this.value + '</span>' +
            '<span class="on">' + checkedLabel + '</span>'
        }

        this.domNode
          .removeAttr("buttonType")
          .addClass(this.options.formClass)
          .html(this.parse(this.options.template)) // parse nodes and append events and data

      } else {
        this.parse(this.domNode);
      }
      
      this.bindEvents();
        
      if(this.domNode.get(0).disabled) // define disabled state
        this.setClass(this.domNode, "disabled") 

      var checked = this.domNode.attr("checked");
      if(checked && (checked == 'true' || checked == 'checked') && this.o.type != "simple"){ // define checked state
        this.is.stateBubble = false;
        this.state("checked", true, true)
      }
      
      this.postCreate();

      obj.buttonHandler = this;
      buttons.push(this);
    },
    
    isExist: function(){
      for (var i=0; i < buttons.length; i++) {
        if(buttons[i].domNode.get(0) == this.domNode.get(0))
          return buttons[i];
      };
      return false;
    },
    
    postCreate: function(){

      var _on = this.domNode.find(".on");
      var _off = this.domNode.find(".off");
      var w = {
        on: _on.css({ display: "inline-block" }).width()+1,
        off: _off.css({ display: "inline-block" }).width()+1
      }
      _on.removeAttr("style");
      _off.removeAttr("style");

      if(w.on >= w.off){
        _on.css({ width: w.on });
        _off.css({ width: w.on });
      } else {
        _on.css({ width: w.off });
        _off.css({ width: w.off });
      }

    },
    
    bindEvents: function(){
      var $this = this;

      for (var i=0; i < this.e.list.length; i++) {
        var _event = this.e.list[i];
        if(this[_event]){
          
          (function(_event){
            $this.domNode.bind(_event, function(){
              $this[_event].apply($this, $this.e[_event] ? [$this.e[_event]] : null)
            });

            if(_event == 'mouseup')
              $(document).bind(_event, function(){
                $this[_event].apply($this, $this.e[_event] ? [$this.e[_event]] : null)
              })

          })(_event)

        }
      };

    },
    
    mousedown: function(node){
      var node = node ? node : this.domNode;

      switch(this.o.type){
        case 'trigger':
          if(this.checked){
            this.is.prevent = false;
          } else {
            this.state("checked", true);
            this.is.prevent = true;
          }
          break;

        case 'switcher':
          if(!this.checked)
            this.state("checked", true);
          
          break;

        case 'simple':
        default:
          this.is.prevent = false;
          this.setClass(node, "down");
          break;
      }

    },

    mouseup: function(node){
      var node = node ? node : this.domNode;

      if(!this.is.prevent){
        switch(this.o.type){
          case 'trigger':
            if(this.checked) this.state("checked", false);
            break;

          case 'trigger':
            
            break;

          case 'simple':
          default:
            this.setClass(node, "down", false);
            break
        }
      }

    },

    mouseover: function(node){
      var node = node ? node : this.domNode;
      this.setClass(node, "hover");
    },

    mouseout: function(node){
      var node = node ? node : this.domNode;
      this.setClass(node, "hover", false);
    },
    
    onstatechange: function(){
    },
    
    _onstatechange: function(){
      this.onstatechange.apply(this);
      if($.isFunction(this.e.onstatechange))
        this.e.onstatechange.apply(this)
      else
        eval(this.e.onstatechange)
    },
    
    parse: function(tpl){

      function bind( dom ){
        dom.filter("[bindEvents]").add(dom.find("*[bindEvents]")).each(function(){
          var node = $(this);
          jQuery.each(node.attr("bindEvents").split(/ *, */), function(){
            var _event = this.toString();
            $this.e[_event] = node;
          });
          node.removeAttr("bindEvents");
        })
      }
      
      function append( dom ){
        dom.filter("[attachData]").add(dom.find("*[attachData]")).each(function(){
          var node = $(this);
          jQuery.each(node.attr("attachData").split(/ *, */), function(){
            var _type = this.toString();
            node.append($this.d[_type]);
            $this.o[_type] = node;
          });
          $(this).removeAttr("attachData");
        })
      }

      var $this = this;

      switch(typeof tpl){

        case 'string':
          var tpl = $(tpl);
          bind(tpl);
          append(tpl);
          break;
          
        case 'object':
          bind(tpl);
          break;
      }

      return tpl;
    },
    
    setClass: function(node, sClass, b){
      if(b === false) node.removeClass(this.options.className + "_" + sClass);
      else node.addClass(this.options.className + "_" + sClass);
    },
    
    state: function(name, value, force){
      this.is.prevent = true;

      switch(name){
        case 'checked':
          if(force || !this.o.confirm || (this.o.confirm && confirm(this.o.confirm))){
            this.old[name] = this[name];
            this[name] = value;

            if(this.old[name] != this[name] && this.is.stateBubble)
              this._onstatechange()
            if(!this.is.stateBubble)
              this.is.stateBubble = true;

            if(!value)
              this.setClass(this.e.mouseup, "down", false);
            else
              this.setClass(this.e.mouseup, "down");
          }
          break;

        case 'disabled':

          this.old[name] = this[name];
          this[name] = value;

          if(value){
            this.setClass(this.domNode, name)
            this.domNode.attr(name, true)
          } else {
            this.setClass(this.domNode, name, false)
            this.domNode.removeAttr(name)
          }

          break;
      }
    }
    
    
  }

  function b_button_group(){
  	return this.init.apply(this, arguments);
  }

  b_button_group.prototype = {
    init: function(obj){
      var $this = this;
      
      this.domNode = $(obj);
      this.is = {
        template: false
      }

      if(this.domNode.find("."+ b_button_OPTIONS.className +"_left, ."+ b_button_OPTIONS.className +"_center, ."+ b_button_OPTIONS.className +"_right").length)
        this.is.template = true;

      this.e = {
        onstatechange: this.domNode.attr("onstatechange") ? this.domNode.attr("onstatechange") : function(){}
      };

      this.buttons = new Array();

      if(!this.is.template){
        var buttons = this.domNode.addClass(b_button_OPTIONS.className + "_group").find("button[buttonType]");
        
        buttons.each(function(i){
          var button = new b_button(this);
          var sClass = "center";
          if(i == 0) sClass = "left";
          if(i == buttons.length - 1) sClass = "right";

          if(buttons.length != 1)
            button.domNode.wrap($("<div>").addClass(b_button_OPTIONS.className + "_" + sClass))

          $this.buttons.push(button);
        })

      } else {
        this.domNode.find("."+ b_button_OPTIONS.className +"_form").each(function(){
          $this.buttons.push(this.buttonHandler);
        })
      }


      
      if(this.buttons.length != 1)
        this.bindEvents();
    },
    
    bindEvents: function(){
      $this = this;
      $.each(this.buttons, function(){
        this.onstatechange = function(){
          $this.onclick(this)
        };
      })
    },
    
    onclick: function(obj){
      var $this = this;

      state = {};
      state[obj.name] = true;
      state.new_state = obj.name;

      $.each(this.buttons, function(){
        if(this != obj){
          this.is.stateBubble = false;
          this.state("checked", false);
          if(this.old.checked == true && this.checked == false) {
            state[this.name] = false;
            state.old_state = this.name;
          }
        }
      })
      obj.is.prevent = true;
      

      if($.isFunction(this.e.onstatechange))
        this.e.onstatechange.apply(this)
      else
        (function(state){
          eval($this.e.onstatechange)
        }).call(obj, state)
      
    }
    
  };

})(jQuery);

/* Button object (end) */

