'use strict';

exports.__esModule = true;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var TreeStore = function () {
  function TreeStore(options) {
    _classCallCheck(this, TreeStore);

    this.key = options.key;
    this.label = options.label || 'label';
    this.children = options.children || 'children';
    this.isLeaf = options.isLeaf || 'isLeaf';
    this.disabled = options.disabled;
    this.hideCheckbox = options.hideCheckbox;
    this.initData(options.data);
  }

  TreeStore.prototype.initData = function initData(data, lazy) {
    this.cache = Object.create(null);
    this.cacheIdMap = Object.create(null);
    this.data = [];
    this._traverse(data, lazy, true);
  };

  TreeStore.prototype._traverse = function _traverse(data, lazy, isRoot, parent) {
    var _this = this;

    var children = this.children;

    if (data && data.length > 0) {
      data.forEach(function (item) {
        var node = new Item(item, _this);
        node.parent = parent;
        if (isRoot) {
          _this.data.push(node);
        } else {
          parent.children.push(node);
        }
        _this._registerNode(node);
        var childList = typeof children === 'function' ? children(item) : item[children];
        if (!lazy && childList) {
          node.children = [];
          _this._traverse(childList, false, false, node);
        }
      });
    }
  };

  TreeStore.prototype._registerNode = function _registerNode(node) {
    if (!this.cache[node.key]) {
      this.cache[node.key] = [];
    }
    this.cache[node.key].push(node);
    this.cacheIdMap[node.id] = node;
  };

  TreeStore.prototype.registerNode = function registerNode(data) {
    var node = new Item(data, this);
    this._registerNode(node);
    return node;
  };

  TreeStore.prototype.getNodeById = function getNodeById(id) {
    return this.cacheIdMap[id];
  };

  TreeStore.prototype.getNodes = function getNodes(data) {
    var node = new Item(data, this);
    return this.getNodesByKey(node.key);
  };

  TreeStore.prototype.getNodesByKey = function getNodesByKey(key) {
    if (!key) return [];
    if (!this.cache[key]) {
      this.cache[key] = [];
    }
    return this.cache[key];
  };

  TreeStore.prototype.createKeyToItem = function createKeyToItem(arr) {
    var map = {};
    arr.forEach(function (item) {
      map[item.id] = item;
    });
    return map;
  };

  TreeStore.prototype.uniqNodes = function uniqNodes(nodes) {
    var result = [];
    var map = {};
    nodes.forEach(function (item) {
      if (!map[item.id]) {
        map[item.id] = item;
        result.push(item);
      }
    });
    return result;
  };

  TreeStore.prototype.difference = function difference(prevArr, currentArr) {
    var results = [];
    var uniqCurrArr = this.uniqNodes(currentArr);
    var newKeyToItem = this.createKeyToItem(uniqCurrArr);
    this.uniqNodes(prevArr).forEach(function (item) {
      if (!newKeyToItem[item.id]) {
        results.push(item);
      }
    });
    return results;
  };

  return TreeStore;
}();

exports.default = TreeStore;


var idSeed = 0;

var Item = exports.Item = function () {
  function Item(data, _ref) {
    var key = _ref.key,
        label = _ref.label,
        disabled = _ref.disabled,
        isLeaf = _ref.isLeaf,
        hideCheckbox = _ref.hideCheckbox;

    _classCallCheck(this, Item);

    this.id = 'tree-node-' + idSeed++;
    this.label = typeof label === 'function' ? label(data) : data[label] || data['label'];
    this.data = data;
    this.key = data[key] || this.id;
    this.isLeaf = typeof isLeaf === 'function' ? isLeaf(data) : data[isLeaf];
    if (!this.isLeaf) {
      this.children = [];
    }
    this.disabled = typeof disabled === 'function' ? disabled(data) : data['disabled'] || false;
    this.hideCheckbox = data[hideCheckbox] || false;
    this.parent = null;
  }

  Item.prototype.getData = function getData() {
    return this.data;
  };

  Item.prototype.traverseSub = function traverseSub(cb) {
    cb(this);
    if (Array.isArray(this.children) && this.children.length > 0) {
      this.children.forEach(function (item) {
        return item.traverseSub(cb);
      });
    }
  };

  Item.prototype.traverseParent = function traverseParent(cb) {
    var parent = this.parent;
    while (parent && parent instanceof Item) {
      cb(parent);
      parent = parent.parent;
    }
  };

  return Item;
}();