<template>
  <v-card>
    <v-card-title v-text="title"></v-card-title>
    <v-card-subtitle v-text="subtitle"></v-card-subtitle>
    <v-card-text>
      <v-tabs v-model="tab">
        <v-tab tab-value="paths">Paths</v-tab>
        <v-tab tab-value="globs">Globs</v-tab>
        <v-tab tab-value="pattern" v-if="pattern">Pattern</v-tab>
        <v-tab tab-value="lineNameInfo" v-if="lineNameInfo">Line info</v-tab>
      </v-tabs>

      <v-tabs-items v-model="tab">

        <v-tab-item value="paths">
          <v-card flat>
            <v-card-subtitle>
              A list of directories which are searched for matching files.
            </v-card-subtitle>
            <v-card-text>
              <slot name="paths"></slot>
              <v-form>
                <v-text-field v-for="(item, index) in paths" :key="index"
                  v-model="paths[index]"
                >
                  <dougal-file-browser-dialog
                    slot="append"
                    v-model="paths[index]"
                    :root="rootPath"
                    :mimetypes="[ 'inode/directory' ]"
                    title="Select a directory"
                  ></dougal-file-browser-dialog>
                  <v-btn slot="append-outer"
                    fab
                    x-small text
                    dark
                    color="red"
                    title="Remove"
                    @click="() => paths.splice(index, 1)"
                  >
                    <v-icon>mdi-minus</v-icon>
                  </v-btn>
                </v-text-field>
                <v-btn
                  class="mx-2"
                  fab dark
                  x-small text
                  color="primary"
                  title="Add path"
                  @click="() => paths.push('')"
                >
                  <v-icon dark>mdi-plus</v-icon>
                </v-btn>
              </v-form>
            </v-card-text>
          </v-card>
        </v-tab-item>

        <v-tab-item value="globs">
          <v-card flat>
            <v-card-subtitle>
              A list of <a href="https://en.wikipedia.org/wiki/Glob_(programming)" target="_blank">glob patterns</a> expanding to match the files of interest. Note that Linux is case-sensitive.
            </v-card-subtitle>
            <v-card-text>
              <slot name="globs"></slot>
              <v-form>
                <v-text-field v-for="(item, index) in globs" :key="index"
                  v-model="globs[index]"
                >
                  <v-btn slot="append-outer"
                    fab
                    x-small text
                    dark
                    color="red"
                    title="Remove"
                    @click="() => globs.splice(index, 1)"
                  >
                    <v-icon>mdi-minus</v-icon>
                  </v-btn>
                </v-text-field>
                <v-btn
                  class="mx-2"
                  fab dark
                  x-small text
                  color="primary"
                  title="Add glob pattern"
                  @click="() => globs.push('')"
                >
                  <v-icon dark>mdi-plus</v-icon>
                </v-btn>
              </v-form>
            </v-card-text>
          </v-card>
        </v-tab-item>

        <v-tab-item value="pattern" v-if="pattern">
          <v-card flat>
            <v-card-subtitle>
              Regular expression that describes the file format definition. Used to capture information such as line and sequence number, etc.
              <b v-if="lineNameInfo">Note: Use the <a @click.stop="tab=3">line info</a> tab preferentially.</b>
            </v-card-subtitle>
            <v-card-text>
              <slot name="pattern"></slot>
              <v-form>
                <v-text-field
                  class="mb-5"
                  label="Regular expression"
                  v-model="pattern.regex"
                  persistent-hint
                  hint="Regular expression"
                >
                </v-text-field>

                <fieldset class="pa-3 mb-5">
                  <legend>Captures</legend>

                  <v-text-field v-for="(item, index) in pattern.captures" :key="index"
                    v-model="pattern.captures[index]"
                  >
                    <v-btn slot="append-outer"
                      fab
                      x-small text
                      dark
                      color="red"
                      title="Remove"
                      @click="() => pattern.captures.splice(index, 1)"
                    >
                      <v-icon>mdi-minus</v-icon>
                    </v-btn>
                  </v-text-field>
                  <v-btn
                    class="mx-2"
                    fab dark
                    x-small text
                    color="primary"
                    title="Add capture"
                    @click="() => pattern.captures.push('')"
                  >
                    <v-icon dark>mdi-plus</v-icon>
                  </v-btn>
                </fieldset>

                <v-text-field
                  class="mb-5"
                  label="Flags"
                  v-model="pattern.flags"
                  persistent-hint
                  hint="Regular expression modifier flags"
                >
                </v-text-field>
              </v-form>
            </v-card-text>
          </v-card>
        </v-tab-item>

        <v-tab-item value="lineNameInfo">
          <v-card flat>
            <v-card-subtitle>
              Line information that will be extracted from file names
            </v-card-subtitle>
            <v-card-text>
              <slot name="line-info"></slot>
              <v-form>
                <v-text-field
                  label="Example file name"
                  hint="Enter the name of a representative file to make it easier to visualise your configuration"
                  persistent-hint
                  v-model="lineNameInfo_.example"
                ></v-text-field>

                <dougal-fixed-string-decoder
                  :multiline="true"
                  :text="lineNameInfo_.example"
                  :fixed.sync="lineNameInfo_.fixed"
                  :fields.sync="lineNameInfo_.fields"
                ></dougal-fixed-string-decoder>

              </v-form>
            </v-card-text>
          </v-card>
        </v-tab-item>

      </v-tabs-items>
    </v-card-text>
    <v-card-actions>
      <!--
      <v-btn
        color="primary"
        :disabled="!isValid"
        @click="save"
      >Save</v-btn>
      <v-spacer></v-spacer>
      <v-btn
        color="warning"
        @click="reset"
      >Reset</v-btn>
      -->
        <v-btn
          v-if="tab=='lineNameInfo'"
          :disabled="!validLineNameInfo"
          @click="copyLineNameInfo"
          title="Copy this definition into the clipboard. It can then be pasted into other sections or configurations."
        >
          <v-icon left>mdi-content-copy</v-icon>
          Copy
        </v-btn>
        <v-btn
          v-if="tab=='lineNameInfo'"
          @click="pasteLineNameInfo"
          title="Paste a line info definition copied from elsewhere"
        >
          <v-icon left>mdi-content-paste</v-icon>
          Paste
        </v-btn>
      <v-spacer></v-spacer>
      <v-btn
        color="secondary"
        @click="back"
      >Back</v-btn>
    </v-card-actions>
  </v-card>
</template>

<style scoped>
.sample {
  font-family: mono;
  white-space: pre;
}
</style>

<script>
import { deepCompare } from '@/lib/utils';
import DougalFileBrowserDialog from '@/components/file-browser/file-browser-dialog';
import DougalFixedStringDecoder from '@/components/decoder/fixed-string-decoder';
import { mapActions, mapGetters } from 'vuex';

export default {
  name: "DougalProjectSettingsFileMatchingParameters",

  components: {
    DougalFileBrowserDialog,
    DougalFixedStringDecoder
  },

  props: {
    title: String,
    subtitle: String,
    isValid: { type: Boolean, default: true },
    save: Function,

    rootPath: String,
    paths: Array,
    globs: Array,
    lineNameInfo: Object,
    pattern: Object
  },

  data () {
    return {
      tab: null,
      globs_: [],
      paths_: [],
      lineNameInfo_: {},
      pattern_: {
        flags: "i",
        regex: null,
        captures: []
      }
    }
  },

  computed: {
    validLineNameInfo () {
      return typeof this.lineNameInfo == 'object';
    },
  },

  watch: {

    globs () {
      if (!deepCompare(this.globs, this.globs_)) {
        this.globs_ = this.globs;
      }
    },

    paths () {
      if (!deepCompare(this.paths, this.paths_)) {
        this.paths_ = this.paths;
      }
    },

    lineNameInfo () {
      if (!deepCompare(this.lineNameInfo, this.lineNameInfo_)) {
        this.lineNameInfo_ = this.lineNameInfo;
      }
    },

    pattern () {
      if (!deepCompare(this.pattern, this.pattern_)) {
        this.pattern_ = this.pattern;
      }
    }

  },

  methods: {

    async copyLineNameInfo () {
      await navigator.clipboard.writeText(JSON.stringify(this.lineNameInfo, null, 4));
      this.showSnack(["Line name information copied to clipboard", "primary"]);
    },

    async pasteLineNameInfo () {
      const text = await navigator.clipboard.readText();
      try {
        const data = JSON.parse(text);
        if (["fixed", "fields", "example"].every( key => key in data )) {
          this.$emit("update:lineNameInfo", data);
          this.showSnack(["Line name information pasted from clipboard", "primary"]);
        } else {
          this.showSnack(["Clipboard contents are not valid line name information", "error"]);
        }
      } catch (err) {
        if (err instanceof SyntaxError) {
          this.showSnack(["Clipboard contents are not valid line name information", "error"]);
        }
      }
    },

    reset () {
      this.globs_ = this.globs;
      this.paths_ = this.paths;
      this.lineNameInfo_ = this.lineNameInfo;
      this.pattern_ = this.pattern;
    },

    /*
    save () {
      this.$emit('input', this.data);
    },
    */

    back () {
      this.$emit('close');
    },

    ...mapActions(["showSnack"])

  },

  mounted () {
    this.reset();
  }

}
</script>
