<template>
  <v-card flat>
    <v-card-text>
      <v-form>
        <v-text-field
          label="Path"
          v-model="value.path"
        >
          <dougal-file-browser-dialog
            slot="append"
            v-model="value.path"
            :root="rootPath"
          ></dougal-file-browser-dialog>
        </v-text-field>

        <v-select
          label="Preplot class"
          :items="fileClasses"
          v-model="fileClass"
        ></v-select>

        <v-select
          label="File format"
          :items="preplotFileTypes"
          v-model="fileType"
          :append-outer-icon="fileClass == 'saillines' && fileType == 'x-sl+csv' ? 'mdi-help-circle-outline' : ''"
        >
          <template v-slot:append-outer="" v-if="fileClass == 'saillines' && fileType == 'x-sl+csv'">
            <v-menu :close-on-content-click="false" v-model="tooltip">
              <template v-slot:activator="{ on, attrs }">
                <v-btn icon v-bind="attrs" title="Information on sailline CSV files" @click="tooltip = !tooltip"><v-icon>mdi-help-circle-outline</v-icon></v-btn>
              </template>

              <v-card>
                <v-card-title>Saillines CSV format</v-card-title>
                <v-card-text>
                  <p>
                    The input CSV should have the following comma-separated fields:
                      <dl>
                        <dt><code>sail_line</code></dt> <dd>The vessel line number</dd>
                        <dt><code>incr</code></dt> <dd><em>1</em> if this line is to be shot in the incrementing shot points direction, <em>0</em> or blank otherwise</dd>
                        <dt><code>ntba</code></dt> <dd><em>1</em> if this line is not to be acquired</dd>
                        <dt><code>remarks</code></dt> <dd>Any comments pertinent to the line. Supports <a target="_blank" href="https://commonmark.org/help/">Markdown</a>.</dd>
                        <dt><code>meta.colour</code></dt> <dd>An <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value">HTML colour</a>. Changes the background colour of the line in Dougal's ‘Lines’ tab.</dd>
                        <dt><code>source_line</code></dt> <dd>The source line number. This column should be repeated once per gun array.</dd>
                      </dl>
                    </p>
                    <p>See an <a target="_blank" href="https://gitlab.com/-/snippets/4873650">example file</a> (<a title="Direct download" href="https://gitlab.com/-/snippets/4873650/raw/main/preplots-saillines-example.csv?inline=false"><v-icon dense small>mdi-paperclip</v-icon></a>)</p>
                </v-card-text>
              </v-card>
            </v-menu>
          </template>
        </v-select>

        <v-text-field v-if="value.class == 'S'"
          class="mb-3"
          label="Sailline offset"
          prefix="±"
          type="number"
          hint="The value to add/substract to source lines to get to the corresponding sailline"
          v-model.number="value.saillineOffset"
        >
        </v-text-field>

        <v-expansion-panels v-if="isFixedWidthFormat"
          :value="head.length ? 0 : null"
        >
          <v-expansion-panel>
            <v-expansion-panel-header>Column settings</v-expansion-panel-header>
            <v-expansion-panel-content>
              <div class="mb-3" style="max-width:fit-content;">
                <v-select v-if="head"
                  label="Sample text size"
                  hint="Choose how much of the file to display"
                  :items="sampleSizeItems"
                  v-model="sampleSize"
                ></v-select>
              </div>

              <v-text-field
                label="Skip lines"
                hint="This lets you to skip file headers if present"
                type="number"
                min="0"
                v-model.number="firstRow"
              ></v-text-field>

              <dougal-fixed-string-decoder
                :text="rows"
                :fields="fields"
                :multiline="true"
                :numbered-lines="firstRow"
                max-height="300px"
                :editable-field-list="false"
              ></dougal-fixed-string-decoder>
            </v-expansion-panel-content>
          </v-expansion-panel>
        </v-expansion-panels>

        <v-expansion-panels v-else-if="isDelimitedFormat"
          :value="head.length ? 0 : null"
        >
          <v-expansion-panel>
            <v-expansion-panel-header>Column settings</v-expansion-panel-header>
            <v-expansion-panel-content>

              <v-container>
                <v-row>
                  <v-col cols="6">
                    <div class="mb-3" style="max-width:fit-content;">
                      <v-select v-if="head"
                        label="Sample text size"
                        hint="Choose how much of the file to display"
                        :items="sampleSizeItems"
                        v-model="sampleSize"
                      ></v-select>
                    </div>
                  </v-col>
                </v-row>
                <v-row>
                  <v-col cols="12">

                    <dougal-delimited-string-decoder
                      title="Fields"
                      :text="rows"
                      :fields.sync="fields"
                      :header-row.sync="headerRow"
                      :numbered-lines.sync="firstRow"
                      :editable-field-list="false"
                      :delimiter.sync="delimiter"
                    ></dougal-delimited-string-decoder>

                  </v-col>
                </v-row>

              </v-container>
            </v-expansion-panel-content>
          </v-expansion-panel>
        </v-expansion-panels>
        <v-expansion-panels v-else-if="fileClass == 'saillines'"
          :value="head.length ? 0 : null"
        >
          <v-expansion-panel>
            <v-expansion-panel-header>Column settings</v-expansion-panel-header>
            <v-expansion-panel-content>

              <v-container>
                <v-row>
                  <v-col cols="6">
                    <div class="mb-3" style="max-width:fit-content;">
                      <v-select v-if="head"
                        label="Sample text size"
                        hint="Choose how much of the file to display"
                        :items="sampleSizeItems"
                        v-model="sampleSize"
                      ></v-select>
                    </div>
                  </v-col>
                </v-row>
                <v-row>
                  <v-col cols="12">

                    <dougal-saillines-string-decoder
                      subtitle="Sailline data"
                      :text="head"
                    ></dougal-saillines-string-decoder>

                  </v-col>
                </v-row>

              </v-container>
            </v-expansion-panel-content>
          </v-expansion-panel>
        </v-expansion-panels>
      </v-form>
    </v-card-text>
  </v-card>
</template>

<script>
import DougalFileBrowserDialog from '@/components/file-browser/file-browser-dialog'
import DougalFixedStringDecoder from '@/components/decoder/fixed-string-decoder'
import DougalDelimitedStringDecoder from '@/components/decoder/delimited-string-decoder';
import DougalSaillinesStringDecoder from '@/components/decoder/saillines-string-decoder';

import { mapActions, mapGetters } from 'vuex'

export default {
  name: "DougalProjectSettingsPreplotsPreplot",

  components: {
    DougalFileBrowserDialog,
    DougalFixedStringDecoder,
    DougalDelimitedStringDecoder,
    DougalSaillinesStringDecoder
  },

  props: {
    value: Object,
    rootPath: String
  },

  data () {
    return {
      fileClasses: [
        { text: "Source points", value: "S" },
        { text: "Vessel points", value: "V" },
        { text: "Sail lines", value: "saillines" }
      ],

      preplotFileTypeList: {
        "S": [
          { header: "Fixed width" },
          { text: "SPS v1", value: "sps1", fixedWidth: true },
          { text: "SPS v2.1", value: "sps2.1", fixedWidth: true },
          { text: "P1/90", value: "p190", fixedWidth: true },
          { text: "Other fixed width", value: "fixed-width", fixedWidth: true },
          { header: "Delimited values" },
          { text: "P1/11", value: "p111", delimited: true },
          { text: "CSV", value: "csv", delimited: true },
        ],
        "V": [
          { header: "Fixed width" },
          { text: "SPS v1", value: "sps1", fixedWidth: true },
          { text: "SPS v2.1", value: "sps2.1", fixedWidth: true },
          { text: "P1/90", value: "p190", fixedWidth: true },
          { text: "Other fixed width", value: "fixed-width", fixedWidth: true },
          { header: "Delimited values" },
          { text: "P1/11", value: "p111", delimited: true },
          { text: "CSV", value: "csv", delimited: true },
        ],
        "saillines": [
          { text: "Sail lines CSV", value: "x-sl+csv" }
        ]
      },

      head: "",
      sampleSize: 8192, //1024;
      sampleSizeItems: [
        { text: "512 bytes", value: 512 },
        { text: "1 kiB", value: 1024 },
        { text: "2 kiB", value: 1024*2 },
        { text: "4 kiB", value: 1024*4 },
        { text: "8 kiB", value: 1024*8 },
        { text: "16 kiB", value: 1024*16 },
        { text: "32 kiB", value: 1024*32 },
      ],
      tooltip: false,
    };
  },

  computed: {

    preplotFileTypes () {
      return this.preplotFileTypeList[this.fileClass] ?? [];
    },

    isFixedWidthFormat () {
      return this.preplotFileTypes.find(i => i.value == this.fileType)?.fixedWidth;
    },

    isDelimitedFormat () {
      return this.preplotFileTypes.find(i => i.value == this.fileType)?.delimited;
    },

    rows () {
      if (this.head) {
        if (this.firstRow) {
          return this.head.split("\n").slice(this.firstRow).join("\n");
        }
        return this.head;
      }
      return "";
    },

    fields: {
      get () {
        return (this.value?.fields && Object.keys(this.value.fields).length)
          ? this.value.fields
          : {
            line_name: {
              type: "int"
            },
            point_number: {
              type: "int"
            },
            easting: {
              type: "float"
            },
            northing: {
              type: "float"
            }
          };
      },

      set (v) {
        // console.log("set fields", v);
        this.$emit("input", {
          ...this.value,
          fields: {...v}
        });
      }
    },

    fileClass: {
      get () {
        return this.value?.class;
      },

      set (v) {
        this.$emit("input", {
          ...this.value,
          class: v
        });
      }
    },

    fileType: {
      get () {
        return this.value?.type;
      },

      set (v) {
        this.$emit("input", {
          ...this.value,
          type: v
        });
      }
    },

    firstRow: {
      get () {
        return this.value?.firstRow ?? 0;
      },

      set (v) {
        this.$emit("input", {
          ...this.value,
          firstRow: v
        });
      }
    },

    headerRow: {
      get () {
        return this.value?.headerRow ?? false;
      },

      set (v) {
        this.$emit("input", {
          ...this.value,
          headerRow: v
        });
      }
    },

    delimiter: {
      get () {
        return this.value?.delimiter;
      },

      set (v) {
        this.$emit("input", {
          ...this.value,
          delimiter: v
        });
      }
    }

  },

  watch: {

    async "value.path" (cur, prev) {
      if (cur != prev) {
        this.head = await this.getHead();
      }
    },

    async sampleSize (cur, prev) {
      if (cur && cur != prev) {
        this.head = await this.getHead();
      }
    },

    fileClass (cur, prev) {
      if (cur != prev && cur == "saillines") {
        this.fileType = "x-sl+csv"
      }
    },

    fileType (cur, prev) {
      switch (cur) {
        case prev:
          return;
        case "sps1":
          this.fields = {
            line_name: {
              offset: 1,
              length: 16,
              type: "int"
            },
            point_number: {
              offset: 17,
              length: 8,
              type: "int"
            },
            easting: {
              offset: 46,
              length: 9,
              type: "float"
            },
            northing: {
              offset: 55,
              length: 10,
              type: "float"
            }
          };
          break;
        case "sps2.1":
          this.fields = {
            line_name: {
              offset: 1,
              length: 7,
              type: "int" // SPS v2.1 has this as float but Dougal doesn't support that
            },
            point_number: {
              offset: 11,
              length: 7,
              type: "int" // Ditto
            },
            easting: {
              offset: 46,
              length: 9,
              type: "float"
            },
            northing: {
              offset: 55,
              length: 10,
              type: "float"
            }
          };
          break;
        case "p190":
          this.fields = {
            line_name: {
              offset: 1,
              length: 12,
              type: "int"
            },
            point_number: {
              offset: 19,
              length: 6,
              type: "int"
            },
            easting: {
              offset: 46,
              length: 9,
              type: "float"
            },
            northing: {
              offset: 55,
              length: 9,
              type: "float"
            }
          };
          break;
        case "fixed-width":
          this.fields = {
            line_name: {
              offset: 1,
              length: 4,
              type: "int"
            },
            point_number: {
              offset: 11,
              length: 4,
              type: "int"
            },
            easting: {
              offset: 44,
              length: 8,
              type: "float"
            },
            northing: {
              offset: 53,
              length: 9,
              type: "float"
            }
          };
        case "csv":
          this.fields = {
            line_name: {
              column: 0,
              type: "int"
            },
            point_number: {
              column: 1,
              type: "int"
            },
            easting: {
              column: 2,
              type: "float"
            },
            northing: {
              column: 3,
              type: "float"
            }
          };
          break
        case "x-sl+csv":
          this.fields = null;
          break;
      }
    }

  },

  methods: {

    async getHead () {
      if (this.value?.path) {
        const url = `/files/${this.value.path}`;
        const init = {
          headers: {
            "Range": `bytes=0-${this.sampleSize}`
          }
        };
        const opts = {format: "text"};
        const head = await this.api([url, init, null, opts]);
        return typeof head === "string"
          ? head?.substring(0, head.lastIndexOf("\n")) || ""
          : this.head ?? "";
      }
      return "";
    },

    ...mapActions(["api"])
  },

  created () {
    this.$nextTick(async () => {
      this.head = await this.getHead();
    });
  }

}

</script>
