<template>
  <div class="nglviewer">
    <div id="solution-stage"></div>
  </div>
</template>

<script>
import { Stage, ColormakerRegistry } from "ngl";
import { mapActions, mapGetters, mapMutations } from "vuex";
import { color } from "d3";

function secondaryStructureToNglUint(secondary_structure) {
  return secondary_structure.toLowerCase().charCodeAt(0);
}

export default {
  data() {
    return {
      protein: null,
      stage: null,
      structure: null,
    };
  },

  computed: {
    ...mapGetters(["getSolution", "getSolutionMeta"]),
  },
  methods: {
    ...mapMutations(["setPreview"]),
    updateSecondaryStrcutures() {
      if (this.structure?.structure?.residueStore?.sstruc != null) {
        let sstructs = this.structure.structure.residueStore.sstruc;
        for (let acid of this.getSolution.acids) {
          sstructs[acid.index] = secondaryStructureToNglUint(
            acid.simple_coils_secondary_structure
          );
        }
      }
    },
    loadPdb(protein, metaInformation) {
      this.protein = protein;
      this.stage
        .loadFile(new Blob([protein.pdb], { type: "text/plain" }), {
          ext: "pdb",
        })
        .then((structure) => {
          this.structure = structure;
          this.updateSecondaryStrcutures();

          let solutionSchemeID = ColormakerRegistry.addScheme(function () {
            this.atomColor = function (atom) {
              let resColor = color(
                metaInformation.sequencePreview[atom.residueIndex] == "I"
                  ? "#179BAC"
                  : "#AC2817"
              );
              let resColorHexed = parseInt(resColor.formatHex().slice(1), 16);
              return resColorHexed;
            };
          });
          structure.setSelection(`:${protein.chain}/0`);
          structure.addRepresentation("cartoon", {
            color: solutionSchemeID,
          });

          this.structure.autoView(500);
        });
    },
    _hover(hoverProxy) {
      if (hoverProxy && (hoverProxy.atom || hoverProxy.bond)) {
        let atom = hoverProxy.atom || hoverProxy.closestBondAtom;

        let acid = this.protein.getAcid(atom.resno);
        if (acid != null) {
          this.setPreview({
            description: {
              Acid: acid.acid_name,
              "PDB n.": acid.pdb_number,
              Index: acid.index,
              DSSP: acid.secondary_structure,
            },
          });
        }
      } else {
        this.setPreview(null);
      }
    },
  },
  mounted: function () {
    this.$nextTick().then(() => {
      this.stage = new Stage("solution-stage", {
        backgroundColor: "white",
        tooltip: false,
      });
      //   this.stage.signals.clicked.add(viewPanel._click);
      this.stage.signals.hovered.add(this._hover);
    });
  },
  watch: {
    getSolution(newValue) {
      this.stage.removeAllComponents();
      this.loadPdb(this.getSolution, this.getSolutionMeta);
    },
  },
};
</script>

<style scoped>
#solution-stage {
  width: 450px;
  height: 400px;
  touch-action: none;
  border-radius: 10px;
}
</style>