text: /**
   * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
   *
   * @author David Sehnal <david.sehnal@gmail.com>
   */
  import { StructureElement } from '../../../structure';
  import { Segmentation } from '../../../../../mol-data/int';
  import { UUID } from '../../../../../mol-util';
  export var IndexedCustomProperty;
  (function (IndexedCustomProperty) {
      function getCifDataSource(structure, prop, cache) {
          if (!prop)
              return { rowCount: 0 };
          if (cache && cache[prop.id])
              return cache[prop.id];
          var data = prop.getElements(structure);
          var ret = { data: data, rowCount: data.elements.length };
          if (cache)
              cache[prop.id] = ret;
          return ret;
      }
      IndexedCustomProperty.getCifDataSource = getCifDataSource;
      function fromAtomMap(map) {
          return new ElementMappedCustomProperty(map);
      }
      IndexedCustomProperty.fromAtomMap = fromAtomMap;
      function fromAtomArray(array) {
          // TODO: create "array based custom property" as optimization
          return new ElementMappedCustomProperty(arrayToMap(array));
      }
      IndexedCustomProperty.fromAtomArray = fromAtomArray;
      var getResidueSegments = function (model) { return model.atomicHierarchy.residueAtomSegments; };
      function fromResidueMap(map) {
          return new SegmentedMappedIndexedCustomProperty('residue', map, getResidueSegments, 0 /* Atomic */);
      }
      IndexedCustomProperty.fromResidueMap = fromResidueMap;
      function fromResidueArray(array) {
          // TODO: create "array based custom property" as optimization
          return new SegmentedMappedIndexedCustomProperty('residue', arrayToMap(array), getResidueSegments, 0 /* Atomic */);
      }
      IndexedCustomProperty.fromResidueArray = fromResidueArray;
      var getChainSegments = function (model) { return model.atomicHierarchy.chainAtomSegments; };
      function fromChainMap(map) {
          return new SegmentedMappedIndexedCustomProperty('chain', map, getChainSegments, 0 /* Atomic */);
      }
      IndexedCustomProperty.fromChainMap = fromChainMap;
      function fromChainArray(array) {
          // TODO: create "array based custom property" as optimization
          return new SegmentedMappedIndexedCustomProperty('chain', arrayToMap(array), getChainSegments, 0 /* Atomic */);
      }
      IndexedCustomProperty.fromChainArray = fromChainArray;
      function fromEntityMap(map) {
          return new EntityMappedCustomProperty(map);
      }
      IndexedCustomProperty.fromEntityMap = fromEntityMap;
  })(IndexedCustomProperty || (IndexedCustomProperty = {}));
  function arrayToMap(array) {
      var ret = new Map();
      for (var i = 0, _i = array.length; i < _i; i++)
          ret.set(i, array[i]);
      return ret;
  }
  var SegmentedMappedIndexedCustomProperty = /** @class */ (function () {
      function SegmentedMappedIndexedCustomProperty(level, map, segmentGetter, kind) {
          this.level = level;
          this.map = map;
          this.segmentGetter = segmentGetter;
          this.id = UUID.create22();
          this.kind = kind;
      }
      SegmentedMappedIndexedCustomProperty.prototype.has = function (idx) { return this.map.has(idx); };
      SegmentedMappedIndexedCustomProperty.prototype.get = function (idx) { return this.map.get(idx); };
      SegmentedMappedIndexedCustomProperty.prototype.getStructureElements = function (structure) {
          var models = structure.models;
          if (models.length !== 1)
              throw new Error("Only works on structures with a single model.");
          var seenIndices = new Set();
          var unitGroups = structure.unitSymmetryGroups;
          var loci = [];
          var segments = this.segmentGetter(models[0]);
          for (var _a = 0, unitGroups_1 = unitGroups; _a < unitGroups_1.length; _a++) {
              var unitGroup = unitGroups_1[_a];
              var unit = unitGroup.units[0];
              if (unit.kind !== this.kind) {
                  continue;
              }
              var chains = Segmentation.transientSegments(segments, unit.elements);
              while (chains.hasNext) {
                  var seg = chains.move();
                  if (!this.has(seg.index) || seenIndices.has(seg.index))
                      continue;
                  seenIndices.add(seg.index);
                  loci[loci.length] = StructureElement.Location.create(structure, unit, unit.elements[seg.start]);
              }
          }
          loci.sort(function (x, y) { return x.element - y.element; });
          return loci;
      };
      SegmentedMappedIndexedCustomProperty.prototype.getElements = function (structure) {
          var _this = this;
          var index = this.segmentGetter(structure.model).index;
          var elements = this.getStructureElements(structure);
          return { elements: elements, property: function (i) { return _this.get(index[elements[i].element]); } };
      };
      return SegmentedMappedIndexedCustomProperty;
  }());
  var ElementMappedCustomProperty = /** @class */ (function () {
      function ElementMappedCustomProperty(map) {
          this.map = map;
          this.id = UUID.create22();
          this.level = 'atom';
          this.kind = 0 /* Atomic */;
      }
      ElementMappedCustomProperty.prototype.has = function (idx) { return this.map.has(idx); };
      ElementMappedCustomProperty.prototype.get = function (idx) { return this.map.get(idx); };
      ElementMappedCustomProperty.prototype.getStructureElements = function (structure) {
          var models = structure.models;
          if (models.length !== 1)
              throw new Error("Only works on structures with a single model.");
          var seenIndices = new Set();
          var unitGroups = structure.unitSymmetryGroups;
          var loci = [];
          for (var _a = 0, unitGroups_2 = unitGroups; _a < unitGroups_2.length; _a++) {
              var unitGroup = unitGroups_2[_a];
              var unit = unitGroup.units[0];
              if (unit.kind !== this.kind) {
                  continue;
              }
              var elements = unit.elements;
              for (var i = 0, _i = elements.length; i < _i; i++) {
                  var e = elements[i];
                  if (!this.has(e) || seenIndices.has(e))
                      continue;
                  seenIndices.add(elements[i]);
                  loci[loci.length] = StructureElement.Location.create(structure, unit, e);
              }
          }
          loci.sort(function (x, y) { return x.element - y.element; });
          return loci;
      };
      ElementMappedCustomProperty.prototype.getElements = function (structure) {
          var _this = this;
          var elements = this.getStructureElements(structure);
          return { elements: elements, property: function (i) { return _this.get(elements[i].element); } };
      };
      return ElementMappedCustomProperty;
  }());
  var EntityMappedCustomProperty = /** @class */ (function () {
      function EntityMappedCustomProperty(map) {
          this.map = map;
          this.id = UUID.create22();
          this.level = 'entity';
          this.kind = 0 /* Atomic */;
      }
      EntityMappedCustomProperty.prototype.has = function (idx) { return this.map.has(idx); };
      EntityMappedCustomProperty.prototype.get = function (idx) { return this.map.get(idx); };
      EntityMappedCustomProperty.prototype.getStructureElements = function (structure) {
          var models = structure.models;
          if (models.length !== 1)
              throw new Error("Only works on structures with a single model.");
          var index = models[0].atomicHierarchy.index;
          var seenIndices = new Set();
          var unitGroups = structure.unitSymmetryGroups;
          var loci = [];
          var segments = models[0].atomicHierarchy.chainAtomSegments;
          for (var _a = 0, unitGroups_3 = unitGroups; _a < unitGroups_3.length; _a++) {
              var unitGroup = unitGroups_3[_a];
              var unit = unitGroup.units[0];
              if (unit.kind !== this.kind) {
                  continue;
              }
              var chains = Segmentation.transientSegments(segments, unit.elements);
              while (chains.hasNext) {
                  var seg = chains.move();
                  var eI = index.getEntityFromChain(seg.index);
                  if (!this.has(eI) || seenIndices.has(eI))
                      continue;
                  seenIndices.add(eI);
                  loci[loci.length] = StructureElement.Location.create(structure, unit, unit.elements[seg.start]);
              }
          }
          loci.sort(function (x, y) { return x.element - y.element; });
          return loci;
      };
      EntityMappedCustomProperty.prototype.getElements = function (structure) {
          var _this = this;
          var elements = this.getStructureElements(structure);
          var chainIndex = structure.model.atomicHierarchy.chainAtomSegments.index;
          var index = structure.model.atomicHierarchy.index;
          return { elements: elements, property: function (i) { return _this.get(index.getEntityFromChain(chainIndex[elements[i].element])); } };
      };
      return EntityMappedCustomProperty;
  }());
  //# sourceMappingURL=indexed.js.map