'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

exports['default'] = dom;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

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

var _virtualDomH = require('virtual-dom/h');

var _virtualDomH2 = _interopRequireDefault(_virtualDomH);

var _refsStack = require('./refs-stack');

var _refsStack2 = _interopRequireDefault(_refsStack);

function dom(tag, properties) {
  for (var _len = arguments.length, children = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
    children[_key - 2] = arguments[_key];
  }

  if (typeof tag === 'function') {
    return new ComponentWidget(tag, properties, children);
  } else {
    if (properties && properties.ref) {
      properties.ref = new RefHook(properties.ref);
    }
    return (0, _virtualDomH2['default'])(tag, properties, children);
  }
}

var ComponentWidget = (function () {
  function ComponentWidget(constructor, properties, children) {
    _classCallCheck(this, ComponentWidget);

    this.type = 'Widget';
    this.constructor = constructor;
    this.properties = properties;
    this.children = children;

    if (this.properties && this.properties.key) {
      this.key = this.properties.key;
    }
  }

  _createClass(ComponentWidget, [{
    key: 'init',
    value: function init() {
      this.component = new this.constructor(this.properties, this.children);
      if (this.properties && this.properties.ref && _refsStack2['default'].length > 0) {
        _refsStack2['default'][_refsStack2['default'].length - 1][this.properties.ref] = this.component;
      }
      return this.component.element;
    }
  }, {
    key: 'update',
    value: function update(oldWidget, oldElement) {
      var oldRef = undefined,
          newRef = undefined;

      if (oldWidget.properties && oldWidget.properties.ref) {
        oldRef = oldWidget.properties.ref;
      }

      if (this.properties && this.properties.ref) {
        newRef = this.properties.ref;
      }

      if (this.constructor === oldWidget.constructor && typeof oldWidget.component.update === 'function') {
        if (newRef !== oldRef && _refsStack2['default'].length > 0) {
          delete _refsStack2['default'][_refsStack2['default'].length - 1][oldRef];
          _refsStack2['default'][_refsStack2['default'].length - 1][newRef] = oldWidget.component;
        }

        oldWidget.component.update(this.properties, this.children);
      } else {
        if (_refsStack2['default'].length > 0) {
          if (newRef !== oldRef) {
            delete _refsStack2['default'][_refsStack2['default'].length - 1][oldRef];
          }
          if (newRef) {
            _refsStack2['default'][_refsStack2['default'].length - 1][newRef] = this.component;
          }
        }

        var newElement = this.init();
        oldElement.parentNode.replaceChild(newElement, oldElement);
      }
    }
  }]);

  return ComponentWidget;
})();

var RefHook = (function () {
  function RefHook(refName) {
    _classCallCheck(this, RefHook);

    this.refName = refName;
  }

  _createClass(RefHook, [{
    key: 'hook',
    value: function hook(node) {
      if (_refsStack2['default'].length > 0) {
        _refsStack2['default'][_refsStack2['default'].length - 1][this.refName] = node;
      }
    }
  }, {
    key: 'unhook',
    value: function unhook(node) {
      if (_refsStack2['default'].length > 0) {
        delete _refsStack2['default'][_refsStack2['default'].length - 1][this.refName];
      }
    }
  }]);

  return RefHook;
})();

module.exports = exports['default'];