import { __require as requireCollection } from "./collection.mjs";
var refs;
var hasRequiredRefs;
function requireRefs() {
  if (hasRequiredRefs) return refs;
  hasRequiredRefs = 1;
  var Collection = requireCollection();
  function hasOwnProperty(e, property) {
    return Object.prototype.hasOwnProperty.call(e, property.name || property);
  }
  function defineCollectionProperty(ref, property, target) {
    var collection = Collection.extend(target[property.name] || [], ref, property, target);
    Object.defineProperty(target, property.name, {
      enumerable: property.enumerable,
      value: collection
    });
    if (collection.length) {
      collection.forEach(function(o) {
        ref.set(o, property.inverse, target);
      });
    }
  }
  function defineProperty(ref, property, target) {
    var inverseProperty = property.inverse;
    var _value = target[property.name];
    Object.defineProperty(target, property.name, {
      configurable: property.configurable,
      enumerable: property.enumerable,
      get: function() {
        return _value;
      },
      set: function(value) {
        if (value === _value) {
          return;
        }
        var old = _value;
        _value = null;
        if (old) {
          ref.unset(old, inverseProperty, target);
        }
        _value = value;
        ref.set(_value, inverseProperty, target);
      }
    });
  }
  function Refs(a, b) {
    if (!(this instanceof Refs)) {
      return new Refs(a, b);
    }
    a.inverse = b;
    b.inverse = a;
    this.props = {};
    this.props[a.name] = a;
    this.props[b.name] = b;
  }
  Refs.prototype.bind = function(target, property) {
    if (typeof property === "string") {
      if (!this.props[property]) {
        throw new Error("no property <" + property + "> in ref");
      }
      property = this.props[property];
    }
    if (property.collection) {
      defineCollectionProperty(this, property, target);
    } else {
      defineProperty(this, property, target);
    }
  };
  Refs.prototype.ensureRefsCollection = function(target, property) {
    var collection = target[property.name];
    if (!Collection.isExtended(collection)) {
      defineCollectionProperty(this, property, target);
    }
    return collection;
  };
  Refs.prototype.ensureBound = function(target, property) {
    if (!hasOwnProperty(target, property)) {
      this.bind(target, property);
    }
  };
  Refs.prototype.unset = function(target, property, value) {
    if (target) {
      this.ensureBound(target, property);
      if (property.collection) {
        this.ensureRefsCollection(target, property).remove(value);
      } else {
        target[property.name] = void 0;
      }
    }
  };
  Refs.prototype.set = function(target, property, value) {
    if (target) {
      this.ensureBound(target, property);
      if (property.collection) {
        this.ensureRefsCollection(target, property).add(value);
      } else {
        target[property.name] = value;
      }
    }
  };
  refs = Refs;
  return refs;
}
export {
  requireRefs as __require
};
