<template>
  <div>
    <div class="gallery-thumbs__spacer"></div>
    <ul ref="galleryThumbsList"
        class="gallery-thumbs__list list-shadow">
      <li v-for="(gallery, galleryIndex) in galleries"
          :key="galleryIndex"
          :class="{ 'is-active': activeRow === galleryIndex }"
          class="gallery-thumbs__row-container">
        <ul ref="galleryThumbsRows"
            class="gallery-thumbs__row"
            :style="{ 'transform': 'translate3d(' + thumbRowOffsets[galleryIndex] + 'px, 0, 0)' }">
          <li class="featured-image-spacer mobile-only"
              :style="{ 'height': featuredHeight }">
            <ThumbNav class="featured-nav mobile-only"
                      direction="right"
                      @navClick="handleNavClick(galleryIndex, 'right')" />
          </li>
          <li v-for="(image, imageIndex) in gallery.images"
              :ref="galleryIndex == 0 && imageIndex == 0 ? 'thumbContainer' : null"
              class="thumb-container thumb-overlay selected-indicator"
              :class="{ 'is-active': imageIndex === activeIndex }"
              :style="{ 'background-image': 'url(' + image.thumbUrl + ')' }"
              :key="galleryIndex + '.' + imageIndex + '.' + image.url"
              @click="$emit('thumbClick', galleryIndex, imageIndex)">
            <ThumbNav class="thumb-nav thumb-nav--left mobile-only"
                      direction="left"
                      @navClick="handleNavClick(galleryIndex, 'left')" />
            <ThumbNav v-if="imageIndex < gallery.images.length - 1"
                      class="thumb-nav mobile-only"
                      direction="right"
                      @navClick="handleNavClick(galleryIndex, 'right')" />
          </li>
        </ul>
      </li>
      <ThumbNav class="thumb-nav thumb-nav--left mobile-hide shadow-deco"
                :class="{ 'is-active': isLeftDesktopNavActive }"
                direction="left"
                @navClick="handleNavClickDesktop(activeRow, 'left')"/>
      <ThumbNav class="thumb-nav thumb-nav--right mobile-hide shadow-deco"
                :class="{ 'is-active': isRightDesktopNavActive }"
                direction="right"
                @navClick="handleNavClickDesktop(activeRow, 'right')"/>
    </ul>
  </div>
</template>

<script>
import ThumbNav from '@/components/ThumbNav'

export default {
  components: {
    ThumbNav
  },
  
  props: {
    galleries: {
      type: Array,
      required: true
    },
    featuredHeight: {
      type: String,
      required: true
    },
    activeRow: {
      type: Number,
      required: true
    },
    // index of image to be highlighted
    activeIndex: {
      type: Number,
      required: false,
      default () {
        return 0
      },
    },
    // scroll this image into view
    showImage: {
      type: Number,
      required: false,
      default () {
        return 0
      },
    },
  },

  data () {
    return {
      thumbRowOffsets: new Array(this.galleries.length),
      isLeftDesktopNavActive: false,
      resizeIsThrottling: false,
      isThumbsScrolling: false,
      touchDownPosition: null
    }
  },

  computed: {
    thumbsVerticalOffset () {
      let rowHeight = this.$refs.thumbContainer ? this.$refs.thumbContainer[0].clientHeight : 0;
      return  rowHeight * this.activeRow
    },
    isRightDesktopNavActive () {
      return this.thumbRowOffsets[this.activeRow] > 0
    }
  },

  watch: {
    activeRow: function(val) {
      this.$nextTick(() => {
        this.updateElements(false)
      })
    },
    showImage () {
      this.scrollToThumb(this.showImage)
    }
  },

  mounted () {
    window.addEventListener('resize', this.handleResize)
    this.$refs.galleryThumbsList.addEventListener('touchstart', this.handleTouch, { passive: true })
    this.$refs.galleryThumbsList.addEventListener('touchend', this.handleTouch, { passive: true })
    this.$refs.galleryThumbsList.addEventListener('wheel', this.handleThumbsScroll, { passive: true })
    // firefox
    this.$refs.galleryThumbsList.addEventListener('mousewheel', this.handleThumbsScroll, { passive: true })
    this.$nextTick(function () {
      this.updateElements()
      this.scrollToThumb(this.activeIndex)
    })
  },

  methods: {
    // TOOD move logic of getting sizes of elements into getter methods
    scrollToThumb (thumbIndex) {
      if (thumbIndex >= this.galleries[this.activeRow].images.length || thumbIndex < 0) { return }
      const containerWidth = this.$refs.galleryThumbsList.clientWidth
      const thumbWidth = this.$refs.thumbContainer[0].clientWidth
      let offset = this.thumbRowOffsets[this.activeRow]
      const thumbPosition = thumbWidth * (this.galleries[this.activeRow].images.length - thumbIndex)
      const rowWidth = this.$refs.galleryThumbsRows[this.activeRow].clientWidth

      if (containerWidth < thumbPosition - offset) {
        this.$set(this.thumbRowOffsets, this.activeRow, thumbPosition - containerWidth + 1)
        this.isLeftDesktopNavActive = containerWidth + offset > rowWidth
      } else if (thumbPosition <= offset) {
        this.$set(this.thumbRowOffsets, this.activeRow, thumbPosition - thumbWidth)
        this.isLeftDesktopNavActive = containerWidth + offset > rowWidth
      }
      

    },
    updateElements (resetOffsets=true) {
      if (resetOffsets) {this.resetOffsets()}
      if (this.$refs.galleryThumbsRows[this.activeRow] && this.$refs.galleryThumbsList) {
        let totalRowWidth = this.$refs.galleryThumbsRows[this.activeRow].clientWidth
        let visibleRowWidth = this.$refs.galleryThumbsList.clientWidth
        this.initLeftNav(totalRowWidth, visibleRowWidth)
        if (visibleRowWidth > totalRowWidth) {
          this.centerThumbs(totalRowWidth, visibleRowWidth)
        }
      }
    },
    initLeftNav (totalRowWidth, visibleRowWidth) {
      let offset = this.thumbRowOffsets[this.activeRow]
      let maxOffset = totalRowWidth - visibleRowWidth
      this.isLeftDesktopNavActive = (totalRowWidth > visibleRowWidth) 
        && (offset < maxOffset)
    },
    resetOffsets() {
      for (let index = 0; index < this.thumbRowOffsets.length; index++) {
        this.$set(this.thumbRowOffsets, index, 0)
      }
    },
    centerThumbs(rowWidth, visibleWidth) {
      let offset = (visibleWidth - rowWidth) / -2
      this.$set(this.thumbRowOffsets, [this.activeRow], offset)
    },
    handleNavClick(source, direction) {
      let offset = this.thumbRowOffsets[source]
      const thumbContainerWidth = this.$refs.thumbContainer[0].clientWidth
      if (direction === 'left') {
        offset += thumbContainerWidth
      } else if (direction === 'right') {
        offset -= thumbContainerWidth
      }
      offset = offset > 0 ? 0 : offset
      this.$set(this.thumbRowOffsets, source, offset)
    },
    handleNavClickDesktop(source, direction) {
      let offset = this.thumbRowOffsets[source]
      let thumbContainerWidth = this.$refs.thumbContainer[0].clientWidth
      let visibleRowWidth = this.$refs.galleryThumbsList.clientWidth
      let totalRowWidth = this.$refs.galleryThumbsRows[source].clientWidth
      let maxOffset = totalRowWidth - visibleRowWidth
      if (direction === 'left') {
        offset += thumbContainerWidth
      } else if (direction === 'right') {
        offset -= thumbContainerWidth
        if (offset != 0) {
          this.isLeftDesktopNavActive = true
        }
      }
      if (offset < 0) {
        offset = 0
      } else if (offset >= maxOffset) {
        offset = maxOffset
        this.isLeftDesktopNavActive = false
      }
      this.$set(this.thumbRowOffsets, source, offset)
    },
    handleResize() {
      if (!this.resizeIsThrottling) {
        this.resizeIsThrottling = true
        this.$nextTick(() => {
          this.updateElements()
          this.resizeIsThrottling = false
        })
      }
    },
    handleThumbsScroll(event) {
      if (event.wheelDeltaX) {
        if (event.wheelDeltaX > 0) {
          this.doThumbScroll('right')
        } else if (event.wheelDeltaX < 0) {
          this.doThumbScroll('left')
        }
      } else if (event.deltaY) {
        if (event.deltaY > 0) {
          this.doThumbScroll('left')
        } else if (event.deltaY < 0) {
          this.doThumbScroll('right')
        }
      }
    },
    handleTouch(event) {
      if (event.type === 'touchstart') {
        this.touchDownPosition = event.changedTouches[0].clientX
      } else if (event.type === 'touchmove') {
        event.preventDefault()
      } else if (event.type === 'touchend') {
        let xPos = event.changedTouches[0].clientX
        let direction = this.touchDownPosition - xPos < 0 ? 'left' : 'right'
        this.doThumbScroll(direction)
      }
    },
    doThumbScroll(direction) {
      if (this.isThumbsScrolling) { return }

      this.isThumbsScrolling = true
      if ((direction === 'left' && this.isLeftDesktopNavActive) || (direction === 'right' && this.isRightDesktopNavActive)) {
        this.handleNavClickDesktop(this.activeRow, direction)
      }
      this.$nextTick(() => {
        this.isThumbsScrolling = false
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.gallery-thumbs__row {
  display: flex;
  flex-direction: row;
  list-style: none;
  padding: 0;
  margin: 0;
}

.thumb-container {
  background-size: cover;
  background-position: center center;
  overflow: hidden;

  padding: 0 2px;
  background-clip: content-box;

  cursor: pointer;
}

@media (max-width: $bp__layout) {
  .gallery-thumbs__spacer {
    display:none;
  }

  .gallery-thumbs__row {
    position: relative;
    transition : transform .5s;
  }

  .featured-image-spacer {
    position: relative;
    height: calc(50vh - #{$site-menu__header-height / 2}) !important; // must override inline style set with prop
    width: 100vw;
    flex: 0 0 100vw;
  }

  .thumb-container {
    position: relative;
    height: calc(50vh - #{$site-menu__header-height / 2});
    width: 100vw;

    background-size: cover;
    background-position: center center;
  }

  .featured-nav {
    z-index: 20;
    position: absolute;
    width: 100%;
    height: 100%;
    right: 0;
    top: 0;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    padding-left: 80%;
    padding-right: 16px;
    padding-bottom: 16px;

    opacity: .3;
  }

  .thumb-nav {
    z-index: 20;
    position: absolute;
    width: 8rem;
    height: 8rem;
    bottom: 1rem;
    right: 8px;
    padding: 0 1rem 0 3rem;

    display: flex;
    align-items: flex-end;

    opacity: .4;

    &--left {
      left: 8px;
      right: auto;
      padding: 0 3rem 0 1rem;
    }
  }

  .mobile-hide {
    display: none;
  }
  
}

@media (min-width: $bp__layout) {
  .mobile-only {
    display: none;
  }

  .mobile-hide {
    display: initial;
  }

  .featured-image-spacer {
    width: 100%;
  }

  .thumb-container {
    position: relative;
    z-index: 1;
    height: $gallery-thumbs-height--compact;
    width: $gallery-thumbs-height--compact * 1.6;
    flex: 0 0 $gallery-thumbs-height--compact * 1.6;
  }

  .gallery__thumbs {
    width: 100%;
  }

  .gallery-thumbs__list {
    position: relative;
    height: $gallery-thumbs-height--compact;
    flex: 0 0 $gallery-thumbs-height--compact;
    bottom: 8px;

    overflow: hidden;

    transition: opacity .3s; // TEMP
  }

  .list-shadow {
    $color: $color__neutral-100;
    box-shadow: 0 -3px 33px -9px $color, 0 0 8px -3px $color;
    background-color: rgba($color, .7);
  }

  .gallery-thumbs__row-container {
    position: absolute;
    width: 100%;
    height: 100%;

    transition: opacity .5s;
    opacity: 0;
    pointer-events: none;

    &.is-active {
      transition: opacity .5s .3s;
      opacity: 1;
      pointer-events: auto;
    }
  }

  .gallery-thumbs__row {
    position: absolute;
    height: 100%;
    top: 0;
    right: 0;

    transition: transform .5s;
  }

  .thumb-nav {
    position: absolute;
    top: 1rem;
    width: $gallery-thumbs-height--compact - 2rem;
    height: $gallery-thumbs-height--compact - 2rem;

    transition: opacity .5s;
    opacity: 0;
    pointer-events: none;

    &.is-active {
      opacity: 1;
      pointer-events: auto;
    }

    &--left {
      left: -.5rem;
    }

    &--right {
      right: -.5rem;
    }
  }
}

@media (min-width: $bp__gallery-compact) {
  .gallery-thumbs__list {
    height: $gallery-thumbs-height;
    flex: 0 0 $gallery-thumbs-height;
  }
  
  .thumb-container {
    height: $gallery-thumbs-height;
    width: $gallery-thumbs-height * 1.6;
    flex: 0 0 $gallery-thumbs-height * 1.6;
  }

  .gallery-thumbs__list {
    height: $gallery-thumbs-height;
    flex: 0 0 $gallery-thumbs-height;
  }

  .thumb-nav {
    width: $gallery-thumbs-height - 2rem;
    height: $gallery-thumbs-height - 2rem;
  }
}
</style>