var list = (function() {

  function New(opt) {
    this.folders = new Array;
    for (var i = 0; i < opt.folders.length; i++) {
      this.folders.push(new folder(opt.folders[i], this));
    }
    this.actionPanel = new actionPanel(opt.actionPanel, this);
  }

  function actionPanel(data, obj) {
    this.dom = data.dom;
    for (var i in data.property) {
      this[i] = data.property[i];
    }
    if (this.box)
      this.box.checked = false;
    for (var i in data.action) {
      $(data.action[i].dom).bind(data.action[i].type || 'click', {
        list:obj,
        panel:this
      }, this[i]);
    }
    $(this.dom).hide();
  }

  actionPanel.prototype.removeCheckedItems = function(evt) {
    var requiest = new Object;
    for (var i = 0; i < evt.data.list.folders.length; i++) {
      var folder = evt.data.list.folders[i];
      for (var s = 0; s < folder.selectItems.length; s++) {
        var item = folder.selectItems[s];
        if (!requiest[item.box.name || 'id']){
          requiest[item.box.name || 'id'] = new Array;
        }
        requiest[item.box.name || 'id'].push(item.box.value);
        for (var l = 0; l < folder.items.length; l++) {
          if (folder.items[l].dom === item.dom) {
            folder.items.splice(l, 1);
            break;
          }
        }
        $(item.dom).remove();
      }
      if (!folder.items.length) {
        folder.slide({
          data:{
            folder:folder
          }
        });
        if (folder.empty) {
          $(folder.empty).slideDown(400);
        }
      }
      if ((folder.removeEmpty && !folder.items.length) || (folder.box && folder.box.checked)) {
        if (folder.box) {
          if (!requiest[folder.box.name || 'id'])
            requiest[folder.box.name || 'id'] = new Array;
          requiest[folder.box.name || 'id'].push(folder.box.value);
        }
        folder.updateCounter();
        $(folder.dom).remove();
        evt.data.list.folders.splice(i, 1);
        i -= 1;
      } else {
        folder.selectItems = new Array;
        folder.updateCounter();
      }
    }
    $.post(evt.data.panel.url, requiest, function(data) {
      if (data.reload === true) {
        window.location.reload();
      }
    }, 'json');
    evt.data.list.actionPanel.slide(evt.data.list);
    if (!evt.data.list.folders.length && evt.data.panel.empty) {
      $(evt.data.panel.empty).slideDown(400);
    } else if (evt.data.panel.empty && $(evt.data.panel.empty.style).is(':hidden')) {
      $(evt.data.panel.empty).slideUp(400);
    }
  };

  actionPanel.prototype.checkAllFolders = function(evt) {
    for (var i = 0; i < evt.data.list.folders.length; i++) {
      var folder = evt.data.list.folders[i];
      if (folder.box) {
        folder.box.checked = this.checked;
        $(folder.box).trigger('click');
        folder.box.checked = this.checked;
      } else {
        evt.data.folder = folder;
        folder.check.call(this, evt);
      }
    }
  };

  actionPanel.prototype.slide = function(list) {
    var foldersCheck = new Array;
    for (var i = 0; i < list.folders.length; i++) {
      if (list.folders[i].box) {
        if (list.folders[i].box.checked)
          foldersCheck.push(true);
      }
      else if (list.folders[i].items.length && list.folders[i].items.length == list.folders[i].selectItems.length) {
        foldersCheck.push(true);
      }
    }

    for (var i = 0; i < list.folders.length; i++) {
      if (foldersCheck.length || list.folders[i].selectItems.length) {
        if ($(this.dom).is(':hidden'))
          $(this.dom).slideDown(400);
        if (foldersCheck.length == list.folders.length && this.box)
          this.box.checked = true;
        return;
      }
    }
    if (this.box)
      this.box.checked = false;

    $(this.dom).slideUp(400);
  };

  function folder(data, obj) {
    this.dom = data.dom;
    this.selectItems = new Array;
    for (var i in data.property) {
      this[i] = data.property[i];
    }
    if (this.box)
      this.box.checked = false;
    this.removeEmpty = data.removeEmpty;
    for (var i in data.action) {
      $(data.action[i].dom).bind(data.action[i].eventType || 'click', {
        list:obj,
        folder:this
      }, this[i]);
    }
    this.items = new Array;
    for (var i = 0; i < data.items.length; i++) {
      this.items.push(new item(data.items[i], this, obj));
    }
  }

  folder.prototype.check = function(evt) {
    for (var i = 0; i < evt.data.folder.items.length; i++) {
      if (evt.data.folder.items[i].box.checked != this.checked && !$(evt.data.folder.items[i].dom).is(':hidden')) {
        evt.data.folder.items[i].box.checked = this.checked;
        evt.data.folder.items[i].check.call(evt.data.folder.items[i].box, {
          data:{
            folder:evt.data.folder,
            list:evt.data.list,
            item:evt.data.folder.items[i]
          }
        });
      }
    }
    evt.data.list.actionPanel.slide(evt.data.list);
    evt.stopPropagation();
  };

  folder.prototype.updateCounter = function(evt) {
    if (this.counter) {
      this.counter.firstChild.nodeValue = this.items.length;
    }
  };

  folder.prototype.rename = function(evt) {
    var folderName = $('span:first', $(this).next()).text();
    var newFolderText = document.createElement('input');
    newFolderText.type = 'text';
    newFolderText.className = 'text';
    newFolderText.value = folderName;
    $(newFolderText).bind('blur', evt.data, function(evt) {
      if (!this.value.length)this.value = folderName;
      var newName = document.createElement('span');
      newName.appendChild(document.createTextNode(this.value));

      //$(newName).bind('click', evt.data, evt.data.folder.rename);

      if (folderName != this.value) {
        $.get(evt.data.folder.url + $('input:last', this.parentNode.parentNode).val(), {
          name:this.value
        });
      }
      $(this).replaceWith(newName);
    }).bind('keypress', function(evt) {
      if (evt.keyCode == 13) {
        this.blur();
      } else if (evt.keyCode == 27) {
        this.value = '';
        this.blur();
      }
    });
    $('span:first', $(this).next()).replaceWith(newFolderText);
    newFolderText.focus();
    newFolderText.select();
    return false;
  };

  folder.prototype.slide = function(evt) {
    var listItems = $('ul:first', this.dom || this.parentNode);
    if (listItems.is(':hidden') && ((this.items) ? this.items.length : evt.data.folder.items.length)) {
      listItems.slideDown(400, function() {
        var btns = $('i', $(this).prev());
        if (btns[0]) {
          btns[0].className = btns[0].className.replace('close', 'open');
        }
        if (btns[1]) {
          btns[1].className = btns[1].className.replace('arr_down', 'arr_up');
        }
      });
    } else {
      listItems.slideUp(400, function() {
        var btns = $('i', $(this).prev());
        if (btns[0]) {
          btns[0].className = btns[0].className.replace('open', 'close');
        }
        if (btns[1]) {
          btns[1].className = btns[1].className.replace('arr_up', 'arr_down');
        }
      });
    }
  };

  function item(data, folder, list) {
    this.dom = data.dom;
    for (var i in data.property) {
      this[i] = data.property[i];
    }
    if (this.box)
      this.box.checked = false;
    for (var i in data.action) {
      $(data.action[i].dom).bind(data.action[i].eventType || 'click', {
        data:data.action[i].data,
        folder:folder,
        list:list,
        item:this
      }, this[i]);
    }
  }

  item.prototype.slideContent = function(evt) {
    var arr = this, content = evt.data.item.content;
    if ($(content).is(':hidden')) {
      $(content).slideDown(400, function() {
        arr.className = arr.className.replace('arr_down', 'arr_up');
      });
    } else {
      $(content).slideUp(400, function() {
        arr.className = arr.className.replace('arr_up', 'arr_down');
      });
    }
  };

  item.prototype.check = function(evt) {
    if(evt.data.item.setActive){
      $(evt.data.item.dom).toggleClass('active', this.checked);
    }

    if (this.checked) {
      evt.data.folder.selectItems.push(evt.data.item);
    } else {
      if (evt.data.folder.box) {
        evt.data.folder.box.checked = false;
      }

      for (var i = 0; i < evt.data.folder.selectItems.length; i++) {
        if (evt.data.item.dom === evt.data.folder.selectItems[i].dom) {
          evt.data.folder.selectItems.splice(i, 1);
          break;
        }
      }
    }
    evt.data.list.actionPanel.slide(evt.data.list);
  };

  item.prototype.active = function(evt) {
    $(this).addClass('active');
  };
  item.prototype.deactive = function(evt) {
    $(this).removeClass('active');
  };
  $(document).ready(function() {
    $('.ui-panel').each(function() {
      var getAction = function(obj, opt, ele, attr) {
        $('*[' + attr + ']', ele).each(function() {
          eval('var data = {' + $(this).attr(attr) + '}');
          for (var i in data) {
            if (typeof(obj.prototype[i]) == 'function') {
              opt[i] = {
                dom:(opt[i] && opt[i].dom) ? opt[i].dom.add(this) : $(this),
                eventType:data[i]
              }
            }
          }
        });
        if ($(ele).attr(attr)) {
          eval('var data = {' + $(ele).attr(attr) + '}');
          for (var i in data) {
            if (typeof(obj.prototype[i]) == 'function') {
              opt[i] = {
                dom:(opt[i] && opt[i].dom) ? opt[i].dom.add(ele) : $(ele),
                eventType:data[i]
              }
            }
          }
        }
      };
      var getProperty = function(opt, ele, attr) {
        $('*[' + attr + ']', ele).each(function() {
          eval('var data = {' + $(this).attr(attr) + '}');
          for (var i in data) {
            opt[i] = data[i];
          }
        });
        if ($(ele).attr(attr)) {
          eval('var data = {' + $(ele).attr(attr) + '}');
          for (var i in data) {
            opt[i] = data[i];
          }
        }
      };
      var options = {
        folders:new Array,
        actionPanel:{
          dom:this,
          action:new Object,
          property:new Object
        }
      };
      getAction(actionPanel, options.actionPanel.action, this, 'ui-panel-act');
      getProperty(options.actionPanel.property, this, 'ui-panel-prop');
      $('.ui-folder, .ui-folder-removeEmpty').each(function() {
        var folderOption = {
          dom:this,
          slide:true,
          property:new Object,
          items:new Array,
          action:new Object,
          removeEmpty:this.className.search('ui-folder-removeEmpty') != -1
        };
        getAction(folder, folderOption.action, this, 'ui-folder-act');
        getProperty(folderOption.property, this, 'ui-folder-prop');
        $('.ui-item', this).each(function() {
          var itemOption = {
            dom:this,
            action:new Object,
            property:new Object
          };
          getAction(item, itemOption.action, this, 'ui-item-act');
          getProperty(itemOption.property, this, 'ui-item-prop');
          folderOption.items.push(itemOption);
        });
        options.folders.push(folderOption);
      });
      new list(options);
    });
  });
  return New;
})();
