<template>
  <v-tour
    name="exampleMode"
    :steps="steps"
    :callbacks="callbacks"
    :options="{
      highlight: true,
      enabledNavigationKeys: {
        ESCAPE: false,
        ARROW_RIGHT: true,
        ARROW_LEFT: false,
      },
      labels: {
        buttonPrevious: 'Fast-forward to results',
        buttonSkip: 'End example',
        buttonNext: 'Next',
        buttonStop: 'Next',
      },
    }"
  >
  </v-tour>
</template>

<script>
import { mapGetters, mapMutations } from "vuex";
import _ from "lodash";
class Act {
  constructor({ id, content, before, params, target }) {
    this.id = id;
    this.content = content;
    this.before = before;
    this.params = _.merge({ enableScrolling: false }, params);
    this._target = target;
  }

  get elem() {
    return document.querySelector(this.target);
  }

  input(text) {
    this.elem.value = text;
    this.elem.dispatchEvent(new CustomEvent("input", { bubbles: true }));
    this.elem.dispatchEvent(new Event("input", { bubbles: true }));
  }

  get target() {
    return this._target ?? `[example-act='${this.id}']`;
  }
}

function wait() {
  return new Promise((resolve) => {
    requestAnimationFrame(resolve);
  });
}

function checkElement(selector) {
  if (document.querySelector(selector) === null) {
    return wait().then(() => checkElement(selector));
  } else {
    return Promise.resolve(true);
  }
}

export default {
  data() {
    return {
      steps: [
        new Act({
          id: "scaffold-source", // We're using document.querySelector() under the hood
          content: `Download the scaffold protein PDB from RCSB.org`,
        }),
        new Act({
          id: "scaffold-download-pdb",
          content: "Type in the PDB ID (6G75)",
        }),
        new Act({
          id: "scaffold-download-chain",
          content: "and the chain (A)",
        }),
        new Act({
          id: "scaffold-download-confirm",
          content: "Click to proceed",
        }),
        new Act({
          id: "scaffold-protein-adjustment",
          content:
            "The DSSP assignment in residues 150 - 155 (a small 3:10 helix) is not the one desired and it can be modified to coil. Select the residues",
          before: () => {
            document
              .querySelector("[example-act='scaffold-download-confirm']")
              ?.click();
            return checkElement("[example-act='scaffold-protein-adjustment']");
          },
          params: {
            placement: "top",
          },
        }),
        new Act({
          id: "make-coil-button",
          content: "and set them to coil",
          before: () => {
            document
              .querySelector("[example-act='scaffold-protein-adjustment']")
              .dispatchEvent(new CustomEvent("change", { bubbles: true }));
          },
        }),
        new Act({
          id: "3d",
          content: "The scaffold protein can be inspected here",
        }),
        new Act({
          id: "pipeline-viz",
          content:
            "The progress in the loop grafting pipeline can be monitored here",
        }),
        new Act({
          id: "insert-source",
          content: "Load the insert protein",
        }),
        new Act({
          id: "insert-download-pdb",
          content: "Type in the PDB ID (2PSF)",
        }),
        new Act({
          id: "insert-download-chain",
          content: "and the chain (B)",
        }),
        new Act({
          id: "insert-download-confirm",
          content: "Click to proceed",
        }),
        new Act({
          id: "loop-exploration-open",
          content:
            "The first step (Protein upload) is now completed. To continue with the second one (Loop exploration), click on the header to unfold the step interface.",
          before: () => {
            document
              .querySelector("[example-act='insert-download-confirm']")
              ?.click();
            return checkElement("[example-act='loop-exploration-open']");
          },
        }),
        new Act({
          id: "scaffold-download-loops",
          content:
            "Click here to calculate the scaffold protein loops and their geometries.",
        }),
        new Act({
          id: "scaffold-loop-rep",
          content:
            "An overview of all the loops on the scaffold protein can be seen here.",
          before: () => {
            document
              .querySelector("[example-act='scaffold-download-loops']")
              ?.click();
            return checkElement(
              "[example-act='scaffold-loop-rep'] > .loop-row"
            );
          },
        }),
        new Act({
          id: "insert-download-loops",
          content:
            "Click here to calculate the insert protein loops and their geometries.",
        }),
        new Act({
          id: "view-interesting-loops",
          content:
            "The attributes of the scaffold loops and their selection status for grafting can be seen here at each step.",
        }),
        new Act({
          id: "select-scaffold-loop",
          content:
            "Loops can be inspected up closer. Click on the loop that was initially modified (different secondary structure assignment) to obtain a detailed view of it.",
          target: "#le-6g75_A_13",
        }),
        new Act({
          id: "select-insert-loop",
          content:
            "Loops from the insert protein can also be inspected this way. Selecting loops from both scaffold and insert allows for direct comparison of those loops.",
          target: "#le-2psf_B_11",
        }),
        new Act({
          id: "loop-comparison-1",
          content:
            "The extent of the loops, their secondary structure assignment and numerical values for geometry can be observed here;",
        }),
        new Act({
          id: "loop-comparison-2",
          content:
            "and a graphical representation of their geometries here, providing an easy way of comparison.",
        }),
        new Act({
          id: "flexibility-open",
          content:
            "To continue with the third step (Flexibility evaluation), click on the header to unfold the step interface.",
        }),
        new Act({
          id: "flexibility-select",
          content:
            "Gausian and Anisotropic Network Models can be used in addition to B-factors obtained from the PDB file fro the assessment. Additionally, custom values can also be inputted by clicking on the right side arrow.",
        }),
        new Act({
          id: "flexibility-select-confirm",
          content: "Click to proceed.",
        }),
        new Act({
          id: "flexibility-exploration",
          content:
            "The calculated flexibility for all scaffold loops is shown colour-coded here, being more flexible loops warm-coloured and the less flexible ones shown in cold colours.",
          before: () => {
            document
              .querySelector("[example-act='flexibility-select-confirm']")
              ?.click();
            return checkElement("[example-act='flexibility-exploration']");
          },
        }),
        new Act({
          id: "flexibility-exploration-methods",
          content:
            "The correlation in between the different used methods for flexibility assessment can be seen here.",
        }),
        new Act({
          id: "flexibility-ss",
          content:
            "The flexibility values can also be shown for secondary structure elements or individual residues.",
          params: {
            placement: "top",
          },
        }),
        new Act({
          id: "flexibility-select-loop",
          content:
            "This loop looks interesting, because joins a relatively static region of the protein (left, bluish colour) with a very flexible one (right, bright orange colour). Add it to the list of candidate loops using the + button.",
          target: "#fe-anm-6g75_A_13",
        }),
        new Act({
          id: "view-interesting-loops",
          content:
            "The scaffold list now shows the selected loop as a candidate loop for grafting.",
        }),
        new Act({
          id: "ccors-open",
          content:
            "To continue with the fourth step (Motion-correlation evaluation), click on the header to unfold the step interface.",
        }),
        new Act({
          id: "ccors-exploration",
          content:
            "The motion cross-correlation between the currently selected candidate loops and the remaining ones in the scaffold protein can be seen here.",
          params: {
            placement: "left",
          },
        }),

        new Act({
          id: "ccors-select-loop",
          content:
            "The flexible regions of this loop show a good cross-correlation with the loop already selected. Add it to the candidate list by clicking on the + button.",
          target: "#ce-6g75_A_18",
        }),
        new Act({
          id: "pairing-open",
          content:
            "To continue with the fifth step (Loop pairing), click on the header to unfold the step interface.",
        }),
        new Act({
          id: "pairing-start-13",
          content:
            "Click on the button to pair the scaffold loop 6g75_A_13 with the appropriate insert one.",
          target: "#pair-6g75_A_13 .pair-button",
        }),
        new Act({
          id: "pairing-select-13",
          content:
            "The loop located in the equivalent structural region in the insert protein is selected for grafting.",
          target: "#lp-2psf_B_11",
        }),
        new Act({
          id: "pairing-geometry-13",
          content:
            "The geometrical similarity of the paired loops can be reviewed again in here.",
          target: "#pairing-charts-6g75_A_13",
        }),
        new Act({
          id: "pairing-start-18",
          content:
            "The same process is repeated for all remaining selected loops.",
          target: "#pair-6g75_A_18 .pair-button",
        }),
        new Act({
          id: "pairing-select-18",
          content:
            "The loop located in the equivalent structural region in the insert protein is selected for grafting.",
          target: "#lp-2psf_B_16",
        }),
        new Act({
          id: "grafting-open",
          content:
            "To continue with the sixth step (Loop grafting), click on the header to unfold the step interface.",
        }),
        new Act({
          id: "graft-start",
          content:
            "Submit the selected and paired loops for pregrafting to obtain the grafting sequences.",
        }),
        new Act({
          id: "download-seq",
          content: "You may obtain them as a JSON file here.",
          before: () => {
            document.querySelector("[example-act='graft-start']")?.click();
            return checkElement("[example-act='download-seq']");
          },
        }),
        new Act({
          id: "confirm-licenses",
          content:
            "In addition to the grafted protein sequences, to obtain (minimised) models and their scores the ownership of third party software licenses needs to be stated.",
        }),
        new Act({
          id: "graft-final",
          content: "Click here to start to start the model computation.",
          before: () => {
            let modeller = document.querySelector("#modeller-licence");
            if (modeller.checked == false) {
              modeller.click();
            }
            let rosseta = document.querySelector("#rosseta-licence");
            if (rosseta.checked == false) {
              rosseta.click();
            }
          },
        }),
        new Act({
          id: "grafting-link",
          content:
            "And the process is done! Bookmark this link and visit the page later to see the results. The calculation on this example (which yields over 400 solutions) typically needs less than one hour. Other experiments may take longer.  Due to computational restrictions, the maximum number of solutions is limited to 1000.",
          before: () => {
            document.querySelector("[example-act='graft-final']")?.click();
            return checkElement("[example-act='grafting-link']");
          },
        }),
      ],

      callbacks: {
        onNextStep: this.handleStep,
        onSkip: () => {
          this.$router.push({
            name: "home",
          });
        },
        onPreviousStep: () => {
          this.$router.push({
            name: "results-view",
            params: { jobId: "exemplary-example" },
          });
          this.$tours["exampleMode"].stop();
        },
        onFinish: () => {
          this.$router.push({
            name: "results-check",
            params: { jobId: "exemplary-example" },
          });
        },
      },
    };
  },

  methods: {
    ...mapMutations(["setExampleMode", "setToken"]),
    startExample() {
      this.setExampleMode(true);
      this.$tours["exampleMode"].start();
    },
    handleStep(step) {
      let act = this.steps[step];
      Promise.all(this.getCurrentAwaitables).then(() => {
        switch (act.id) {
          case "scaffold-source":
            act.elem?.click();
            break;
          case "scaffold-download-pdb":
            act.input("6g75");
            break;
          case "scaffold-download-chain":
            act.input("A");
            break;
          case "make-coil-button":
            act.elem?.click();
            break;
          case "insert-source":
            act.elem?.click();
            break;
          case "insert-download-pdb":
            act.input("2psf");
            break;
          case "insert-download-chain":
            act.input("B");
            break;
          case "loop-exploration-open":
            act.elem?.click();
            break;
          case "scaffold-download-loops":
            act.elem?.click();
            break;
          case "insert-download-loops":
            act.elem?.click();
            break;
          case "select-scaffold-loop":
            act.elem?.click();
            break;
          case "select-insert-loop":
            act.elem?.click();
            break;
          case "flexibility-open":
            act.elem?.click();
            break;
          case "flexibility-select-loop":
            document.querySelector("#fe-anm-6g75_A_13 > .remove")?.click();
            break;
          case "ccors-open":
            act.elem?.click();
            break;
          case "ccors-select-loop":
            document.querySelector("#ce-6g75_A_18 .remove")?.click();
            break;
          case "pairing-open":
            act.elem?.click();
            break;
          case "pairing-start-13":
            document.querySelector("#pair-6g75_A_13 .pair-button")?.click();
            break;
          case "pairing-select-13":
            document.querySelector("#lp-2psf_B_11")?.click();
            break;
          case "pairing-start-18":
            document.querySelector("#pair-6g75_A_18 .pair-button")?.click();
            break;
          case "pairing-select-18":
            document.querySelector("#lp-2psf_B_16")?.click();
            break;
          case "grafting-open":
            act.elem?.click();
            break;
          //stop forgetting the break before default
          default:
            break;
        }
      });
    },
  },
  computed: {
    ...mapGetters(["getCurrentAwaitables"]),
  },

  created() {
    if (this.$route.meta.activateExample) {
      this.setToken("exemplary-example");
    }
  },

  mounted() {
    this.$nextTick().then(() => {
      if (this.$route.meta.activateExample) {
        this.startExample();
      }
    });
  },
  // watch: {
  //   $route: {
  //     handler: function (to) {
  //       if (to.meta.activateExample) {
  //         this.$nextTick().then(() => {});
  //       }
  //     },
  //     immediate: true,
  //   },
  // },
};
</script>

<style>
.v-tour__target--highlighted {
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.3) !important;
}
.v-tour__target--highlighted[example-act="flexibility-select"],
.v-tour__target--highlighted[example-act="view-interesting-loops"],
.v-tour__target--highlighted[example-act="scaffold-loop-rep"],
.v-tour__target--highlighted[example-act="loop-comparison-1"],
.v-tour__target--highlighted[example-act="flexibility-exploration"],
.v-tour__target--highlighted[example-act="scaffold-loop-rep"],
.v-tour__target--highlighted[example-act="scaffold-loop-rep"],
.v-tour__target--highlighted[example-act="scaffold-loop-rep"],
.v-tour__target--highlighted[example-act="scaffold-loop-rep"] {
  pointer-events: none;
}

.v-step {
  background: var(--accent) !important;
}

.v-step__arrow {
  border-color: var(--accent) !important;
}
</style>