text: /**
   * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
   *
   * @author Michal Malý <michal.maly@ibt.cas.cz>
   * @author Jiří Černý <jiri.cerny@ibt.cas.cz>
   */
  import { __assign } from "tslib";
  import { ConfalPyramids, ConfalPyramidsProvider } from './property';
  import { ConfalPyramidsUtil } from './util';
  import { ConfalPyramidsTypes as CPT } from './types';
  import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
  import { MeshBuilder } from '../../../mol-geo/geometry/mesh/mesh-builder';
  import { PrimitiveBuilder } from '../../../mol-geo/primitive/primitive';
  import { LocationIterator } from '../../../mol-geo/util/location-iterator';
  import { Mat4, Vec3 } from '../../../mol-math/linear-algebra';
  import { EmptyLoci } from '../../../mol-model/loci';
  import { StructureProperties, Unit } from '../../../mol-model/structure';
  import { Representation } from '../../../mol-repr/representation';
  import { StructureRepresentationProvider, StructureRepresentationStateBuilder, UnitsRepresentation } from '../../../mol-repr/structure/representation';
  import { UnitsMeshParams, UnitsMeshVisual } from '../../../mol-repr/structure/units-visual';
  import { getAltResidueLociFromId } from '../../../mol-repr/structure/visual/util/common';
  import { ParamDefinition as PD } from '../../../mol-util/param-definition';
  import { NullLocation } from '../../../mol-model/location';
  var t = Mat4.identity();
  var w = Vec3.zero();
  var mp = Vec3.zero();
  function calcMidpoint(mp, v, w) {
      Vec3.sub(mp, v, w);
      Vec3.scale(mp, mp, 0.5);
      Vec3.add(mp, mp, w);
  }
  function shiftVertex(vec, ref, scale) {
      Vec3.sub(w, vec, ref);
      Vec3.scale(w, w, scale);
      Vec3.add(vec, vec, w);
  }
  var ConfalPyramidsMeshParams = __assign({}, UnitsMeshParams);
  function createConfalPyramidsIterator(structureGroup) {
      var structure = structureGroup.structure, group = structureGroup.group;
      var instanceCount = group.units.length;
      var prop = ConfalPyramidsProvider.get(structure.model).value;
      if (prop === undefined || prop.data === undefined) {
          return LocationIterator(0, 1, 1, function () { return NullLocation; });
      }
      var locations = prop.data.locations;
      var getLocation = function (groupIndex, instanceIndex) {
          if (locations.length <= groupIndex)
              return NullLocation;
          return locations[groupIndex];
      };
      return LocationIterator(locations.length, instanceCount, 1, getLocation);
  }
  function createConfalPyramidsMesh(ctx, unit, structure, theme, props, mesh) {
      if (!Unit.isAtomic(unit))
          return Mesh.createEmpty(mesh);
      var prop = ConfalPyramidsProvider.get(structure.model).value;
      if (prop === undefined || prop.data === undefined)
          return Mesh.createEmpty(mesh);
      var pyramids = prop.data.pyramids;
      if (pyramids.length === 0)
          return Mesh.createEmpty(mesh);
      var mb = MeshBuilder.createState(512, 512, mesh);
      var handler = function (pyramid, first, second, firsLocIndex, secondLocIndex) {
          if (firsLocIndex === -1 || secondLocIndex === -1)
              throw new Error('Invalid location index');
          var scale = (pyramid.confal_score - 20.0) / 100.0;
          var O3 = first.O3.pos;
          var OP1 = second.OP1.pos;
          var OP2 = second.OP2.pos;
          var O5 = second.O5.pos;
          var P = second.P.pos;
          shiftVertex(O3, P, scale);
          shiftVertex(OP1, P, scale);
          shiftVertex(OP2, P, scale);
          shiftVertex(O5, P, scale);
          calcMidpoint(mp, O3, O5);
          mb.currentGroup = firsLocIndex;
          var pb = PrimitiveBuilder(3);
          /* Upper part (for first residue in step) */
          pb.add(O3, OP1, OP2);
          pb.add(O3, mp, OP1);
          pb.add(O3, OP2, mp);
          MeshBuilder.addPrimitive(mb, t, pb.getPrimitive());
          /* Lower part (for second residue in step */
          mb.currentGroup = secondLocIndex;
          pb = PrimitiveBuilder(3);
          pb.add(mp, O5, OP1);
          pb.add(mp, OP2, O5);
          pb.add(O5, OP2, OP1);
          MeshBuilder.addPrimitive(mb, t, pb.getPrimitive());
      };
      var walker = new ConfalPyramidsUtil.UnitWalker(structure, unit, handler);
      walker.walk();
      return MeshBuilder.getMesh(mb);
  }
  function getConfalPyramidLoci(pickingId, structureGroup, id) {
      var groupId = pickingId.groupId, objectId = pickingId.objectId, instanceId = pickingId.instanceId;
      if (objectId !== id)
          return EmptyLoci;
      var structure = structureGroup.structure;
      var unit = structureGroup.group.units[instanceId];
      if (!Unit.isAtomic(unit))
          return EmptyLoci;
      var prop = ConfalPyramidsProvider.get(structure.model).value;
      if (prop === undefined || prop.data === undefined)
          return EmptyLoci;
      var locations = prop.data.locations;
      if (locations.length <= groupId)
          return EmptyLoci;
      var altId = StructureProperties.atom.label_alt_id(CPT.toElementLocation(locations[groupId]));
      var rI = unit.residueIndex[locations[groupId].element.element];
      return getAltResidueLociFromId(structure, unit, rI, altId);
  }
  function eachConfalPyramid(loci, structureGroup, apply) {
      return false; // TODO: Implement me
  }
  function ConfalPyramidsVisual(materialId) {
      return UnitsMeshVisual({
          defaultProps: PD.getDefaultValues(ConfalPyramidsMeshParams),
          createGeometry: createConfalPyramidsMesh,
          createLocationIterator: createConfalPyramidsIterator,
          getLoci: getConfalPyramidLoci,
          eachLocation: eachConfalPyramid,
          setUpdateState: function (state, newProps, currentProps) {
          }
      }, materialId);
  }
  var ConfalPyramidsVisuals = {
      'confal-pyramids-symbol': function (ctx, getParams) { return UnitsRepresentation('Confal Pyramids Symbol Mesh', ctx, getParams, ConfalPyramidsVisual); },
  };
  export var ConfalPyramidsParams = __assign({}, UnitsMeshParams);
  export function getConfalPyramidsParams(ctx, structure) {
      return PD.clone(ConfalPyramidsParams);
  }
  export function ConfalPyramidsRepresentation(ctx, getParams) {
      var repr = Representation.createMulti('Confal Pyramids', ctx, getParams, StructureRepresentationStateBuilder, ConfalPyramidsVisuals);
      return repr;
  }
  export var ConfalPyramidsRepresentationProvider = StructureRepresentationProvider({
      name: 'confal-pyramids',
      label: 'Confal Pyramids',
      description: 'Displays schematic depiction of conformer classes and confal values',
      factory: ConfalPyramidsRepresentation,
      getParams: getConfalPyramidsParams,
      defaultValues: PD.getDefaultValues(ConfalPyramidsParams),
      defaultColorTheme: { name: 'confal-pyramids' },
      defaultSizeTheme: { name: 'uniform' },
      isApplicable: function (structure) { return structure.models.some(function (m) { return ConfalPyramids.isApplicable(m); }); },
      ensureCustomProperties: {
          attach: function (ctx, structure) { return ConfalPyramidsProvider.attach(ctx, structure.model, void 0, true); },
          detach: function (data) { return ConfalPyramidsProvider.ref(data.model, false); },
      }
  });
  //# sourceMappingURL=representation.js.map