<template>
  <DialogBase
    ref="dialogWindow"
    :title="album_title"
    @canceled="closed"
    @opened="opened"
    :showFooter="false"
    :disableXscroll="true"
    :disableYscroll="true"
  >
    <div id="albumViewer">
      <div id="header" class="flex-column">
        <div id="background" :style="coverBackground" />

        <div id="albumList" class="flex-row z1" @scroll="loadingAlbums()">
          <div class="dummyAlbum" />
          <div id="loadPrevAlbums" />

          <AlbumItem
            v-for="album in albums"
            :key="album._id"
            :item="album"
            class="ma"
            :class="{ focus: album._id == selectedAlbum._id }"
            :id="album._id"
            @touchend="albumAutoSelect"
            @click="selectAlbum(album)"
            @dblclick="dblclick"
          />

          <div id="loadNextAlbums" />
          <div class="dummyAlbum" />
        </div>
        <awesome-icon
          icon="star"
          size="2x"
          class="favourite ma4"
          :class="{ active: isFavourite }"
          @click="toggleFavourite"
        />
        <div id="stats" class="flex-row grow z1 pa4-bottom">
          <DropDown v-if="$store.getters['user/isAdministrator']">
            <button class="flat pa8-left pa8-right" :title="visibility_text">
              <awesome-icon :icon="visibility_icon" />
            </button>
            <template v-slot:dropdown-content>
              <div>
                <button
                  v-for="(item, i) in $store.state.system.lists.visibility"
                  :key="i"
                  @click="setVisibility(item)"
                >
                  <awesome-icon :icon="getVisibilityIcon(item)" />{{
                    getVisibilityText(item)
                  }}
                </button>
              </div>
            </template>
          </DropDown>

          <span class="grow center" @click="scrollIntoCenter(selectedAlbum)">
            <b>{{ album_title }}</b> by
            <b @click="gotoArtist" class="pointer">{{
              selectedAlbum.artist_name
            }}</b>
            <br />
            <span v-if="album_year">
              from year <b>{{ album_year }}</b> </span
            ><br />
            <b>{{ album_tracks.length }}</b> Tracks with a duration of
            <b>{{ album_duration }}</b>
          </span>

          <DropDown v-if="$store.getters['user/isAdministrator']">
            <button class="flat pa8-left pa8-right">
              <awesome-icon icon="ellipsis-v" />
            </button>
            <template v-slot:dropdown-content>
              <div>
                <button @click="uploadNewCover">
                  <awesome-icon icon="image" />Set new Cover...
                </button>
                <button @click="resetCover">
                  <awesome-icon icon="eraser" />Reset Cover
                </button>
                <hr />
                <button @click="mergeAlbum">
                  <awesome-icon icon="compress-alt" />Merge Albums...
                </button>
              </div>
            </template>
          </DropDown>
        </div>
      </div>

      <ul id="trackList" class="tracks">
        <li v-for="track in selectedAlbum.tracks" :key="track._id">
          <TrackItem :track="track" :showCover="false" />
        </li>
      </ul>
    </div>
    <AlbumMerge ref="mergeDialog" />
  </DialogBase>
</template>

<script>
import AlbumMerge from "./AlbumMerge.vue";
import TrackItem from "../Track";
import { mapGetters } from "vuex";

export default {
  data() {
    return {
      move: 152,
      albums: [],
      scrollTimer: 0,
      loadingPrev: false,
      loadingNext: false,
      elements: {},
    };
  },
  mounted() {
    if (window.innerWidth <= 480 || window.innerHeight <= 480) {
      this.move = 120;
    }
  },
  methods: {
    albumAutoSelect() {
      this.albums.forEach((album) => {
        let center_client = document.documentElement.clientWidth / 2;
        let e = document.getElementById(album._id);
        let r = e.getBoundingClientRect();
        let center_element = center_client - r.left - r.width / 2;
        if (center_element < this.move / 2 && center_element > -this.move / 2) {
          if (album._id == this.selectedAlbum._id) {
            this.scrollIntoCenter(album, "smooth");
          } else {
            this.selectAlbum(album);
          }
        }
      });
    },
    readElements() {
      if (document.getElementById("header") == undefined) {
        return false;
      }
      this.elements.prev = document
        .getElementById("loadPrevAlbums")
        .getBoundingClientRect();

      this.elements.next = document
        .getElementById("loadNextAlbums")
        .getBoundingClientRect();

      this.elements.header = document
        .getElementById("header")
        .getBoundingClientRect();

      this.elements.albums = document.getElementById("albumList");

      return true;
    },
    dblclick() {
      this.$store.commit("tracks/resetSelectedTrack");
      this.$store.commit("radios/resetSelectedRadio");
      this.$store.dispatch("tracks/playContainer", this.selectedAlbum);
    },
    gotoArtist() {
      let artist = this.$store.getters["artists/collection"].find(
        (f) => f._id == this.selectedAlbum.artist_id
      );
      if (artist) {
        this.$store.dispatch("artists/selectArtist", artist);
      } else {
        this.$store
          .dispatch("artists/loadArtist", this.selectedAlbum.artist_id)
          .then((artist) => {
            this.$store.dispatch("artists/selectArtist", artist);
          });
      }
    },
    gotoNextAlbum() {
      let i = this.albums.indexOf(this.selectedAlbum);
      if (i < this.albums.length - 1) {
        this.selectAlbum(this.albums[++i]);
      }
    },
    gotoPrevAlbum() {
      let i = this.albums.indexOf(this.selectedAlbum);
      if (i > 0) {
        this.selectAlbum(this.albums[--i]);
      }
    },
    gotoTrack() {
      if (this.$route.query.play) {
        let track = this.selectedAlbum.tracks.find(
          (f) => f._id == this.$route.query.play
        );
        if (track) {
          this.$store.dispatch("tracks/play", track);
        }
      }
    },
    closed() {
      if (
        (window.history.state.back &&
          window.history.state.back.indexOf("?") == -1) ||
        window.history.state.back.startsWith("/search")
      ) {
        this.$router.back();
      } else {
        this.$store.dispatch("albums/resetSelectedAlbum");
      }
      this.albums = [];
    },
    keydownListener(e) {
      if (e.key == "ArrowLeft") {
        e.preventDefault();
        this.elements.albums.scrollLeft -= 0;
        this.gotoPrevAlbum();
      }
      if (e.key == "ArrowRight") {
        e.preventDefault();
        this.elements.albums.scrollLeft += 0;
        this.gotoNextAlbum();
      }
    },
    loadingAlbums() {
      clearTimeout(this.scrollTimer);
      if (!this.readElements()) {
        return;
      }

      let posPrev = this.elements.prev.left - this.elements.header.left;
      let posNext = this.elements.header.right - this.elements.next.right;

      if (posPrev >= -this.move && !this.loadingPrev) {
        this.loadingPrev = true;
        this.$store
          .dispatch("albums/getPrevTo", this.albums[0])
          .then((album) => {
            if (album) {
              this.albums.unshift(album);
              this.elements.albums.scrollLeft += this.move;
            }
            this.loadingPrev = false;
          });
      } else if (posPrev < -this.move * 3 && !this.loadingPrev) {
        this.loadingPrev = true;
        this.elements.albums.scrollLeft -= this.move;
        this.albums.shift();
        this.loadingPrev = false;
      }

      if (posNext >= -this.move && !this.loadingNext) {
        this.loadingNext = true;
        this.$store
          .dispatch("albums/getNextTo", this.albums[this.albums.length - 1])
          .then((album) => {
            if (album) {
              this.albums.push(album);
            }
            this.loadingNext = false;
          });
      } else if (posNext < -this.move * 3 && !this.loadingNext) {
        this.loadingNext = true;
        this.albums.pop();
        this.loadingNext = false;
      }
    },
    mergeAlbum() {
      this.$refs.mergeDialog.open(this.selectedAlbum);
    },
    opened() {
      this.$nextTick(() => {
        this.scrollIntoCenter(this.selectedAlbum);
      });
    },
    setVisibility(visibility) {
      this.selectedAlbum.visibility = visibility;
      this.$store.dispatch("albums/updateAlbum", this.selectedAlbum);
    },
    toggleFavourite() {
      this.$store.dispatch("user/toggleFavourite", {
        itemId: this.selectedAlbum._id,
        type: "album",
      });
    },
    uploadNewCover() {
      this.$store.dispatch("albums/uploadNewCover", this.selectedAlbum);
    },
    resetCover() {
      this.$store.dispatch("albums/resetCover", this.selectedAlbum);
    },
    getVisibilityIcon(visibility) {
      return visibility == "global"
        ? "globe"
        : visibility == "instance"
        ? "server"
        : visibility == "hidden"
        ? "eye-slash"
        : "user";
    },
    getVisibilityText(visibility) {
      return visibility == "global"
        ? "Global"
        : visibility == "instance"
        ? "On this server"
        : visibility == "hidden"
        ? "Hide this Album"
        : "Only for me";
    },
    scrollIntoCenter(album, behavior = "auto") {
      let e = document.getElementById(album._id);
      if (e) {
        e.scrollIntoView({ behavior: behavior, inline: "center" });
      }
    },
    selectAlbum(album) {
      this.$store.dispatch("albums/selectAlbum", album);
      this.scrollIntoCenter(album);
    },
  },
  computed: {
    ...mapGetters({
      prevAlbum: ["albums/prevAlbum"],
      nextAlbum: ["albums/nextAlbum"],
      selectedAlbum: ["albums/selectedAlbum"],
      selectedTrack: ["tracks/selectedTrack"],
      favourites: ["user/favourites"],
    }),
    album_title() {
      return this.selectedAlbum.title;
    },
    album_year() {
      return this.selectedAlbum.year;
    },
    album_tracks() {
      return this.selectedAlbum.tracks || [];
    },
    album_duration() {
      if (!this.selectedAlbum.tracks) {
        return 0;
      }
      let duration = 0;
      let hours = 0;
      let minutes = 0;
      let seconds = 0;

      this.selectedAlbum.tracks.forEach((track) => {
        duration += track.duration;
      });

      if (duration >= 3600) {
        hours = parseInt(duration / 3600);
        duration -= hours * 3600;
      }

      minutes = parseInt(duration / 60);
      seconds = parseInt(duration - minutes * 60);
      return (
        (hours > 0 ? hours + ":" : "") +
        (minutes < 10 ? "0" : "") +
        minutes +
        ":" +
        (seconds < 10 ? "0" : "") +
        seconds
      );
    },

    coverBackground() {
      return "background-image: url('" + this.cover + "')";
    },
    cover() {
      return (
        this.selectedAlbum.covers.cover256 || "/static/icons/dummy/album.svg"
      );
    },

    visibility_icon() {
      return this.selectedAlbum.visibility == "global"
        ? "globe"
        : this.selectedAlbum.visibility == "instance"
        ? "server"
        : this.selectedAlbum.visibility == "hidden"
        ? "eye-slash"
        : "user";
    },
    visibility_text() {
      return this.selectedAlbum.visibility == "global"
        ? "Visible for the whole world"
        : this.selectedAlbum.visibility == "instance"
        ? "Visible on this instance"
        : this.selectedAlbum.visibility == "hidden"
        ? "Hidden for all users"
        : "Visible only for me";
    },
    isFavourite() {
      return (
        this.favourites.find((f) => f.itemId == this.selectedAlbum._id) !=
        undefined
      );
    },
  },
  watch: {
    selectedAlbum(newVal) {
      if (newVal._id) {
        if (this.albums.length == 0) {
          this.albums.push(newVal);
        }
        if (!this.$refs.dialogWindow.visible) {
          this.$refs.dialogWindow.open();
          window.addEventListener("keydown", this.keydownListener);
        }
        this.gotoTrack();
      } else {
        if (this.$refs.dialogWindow.visible) {
          this.$refs.dialogWindow.close();
        }
        window.removeEventListener("keydown", this.keydownListener);
      }
    },
  },
  components: {
    AlbumMerge,
    TrackItem,
  },
};
</script>

<style scoped>
#albumViewer {
  display: flex;
  flex-direction: column;
  height: 100%;
}
#albumList {
  overflow-x: overlay;
  max-width: 100%;
  align-self: center;
}
#albumList::-webkit-scrollbar {
  display: none;
}
#header {
  position: relative;
  min-width: 280px;
  width: 456px;
  background: black;
}
#header img {
  align-self: center;
}
#navigation {
  width: 456px;
  overflow: auto;
}
#stats {
  z-index: 2;
  color: var(--white);
  text-shadow: 0 1px 2px black;
  line-height: 1.4;
  background-color: #ffffff40;
  border-top: 1px solid #ffffff20;
  border-bottom: 1px solid #00000020;
}
#trackList {
  height: 360px;
  width: 456px;
  background-color: var(--white);
  z-index: 1;
}
.album {
  transition: transform 0.25s;
}
.album.focus {
  transform: scale(1.1);
}
.dummyAlbum {
  min-width: 160px;
}
@media (max-width: 480px), (max-height: 480px) {
  #header {
    width: 100%;
  }
  #trackList {
    height: initial;
    width: 100%;
  }
  .dummyAlbum {
    min-width: 128px;
  }
}
</style>