<template>
  <div class='guacamoleClient' :class="[viewState, clientState, {'hide-overflow': options.autoScale, 'no-control': !control} ]" ref="main">

    <div class="guac_client__header guac_client-slot">
      <slot name="header"/>
    </div>

    <div class='flex-expand display-wrapper' ref="displayWrapper">

      <img class='static-image' :src="staticImage.src" v-show="staticImage.src && !isConnected" >
      <div class="static-overlay" v-show="!isConnected"/>

      <div v-show='isConnected'
           id='display'
           @click='hideNav'
           ref="display"
      />

      <guac-options-drawer
        :options="options"
        :viewState="viewState"
        :client="client"
        :resolution="resolution"
        :control="control"
        @setClipboard="setClipboard"
        @disconnect="disconnect"
        @connect="connect"
        @exitFullscreen="exitFullscreen"
        @resolutionChange="resolutionChange"
        v-if="!hideOptions"
      />

      <transition name="'fade'">
        <div class="guac_client-status guac-center" v-show="!isConnected">
          <guac-notification :status="options.clientState" :options="options" :message="message ">
            <slot name="status" slot="statusOverride" />
          </guac-notification>
        </div>
      </transition>


    </div>

    <div class="guac_client__footer guac_client-slot">
      <slot v-show='!isFullscreen' name="footer"/>
    </div>

  </div>
</template>

<script>

  //Mixins
  import GuacDisplay from './components/GuacDisplay'
  import GuacConnection from './components/GuacConnection'
  import GuacState from './components/GuacState'
  import GuacInput from './components/GuacInput'
  import GuacErrors from './components/GuacErrors'
  import fscreen from 'fscreen'

  //Components
  import GuacOptionsDrawer from './components/GuacOptionsDrawer'
  import GuacNotification from './components/GuacNotification'

  import Guacamole from 'guacamole-common-js'
  export default {
    components: {GuacOptionsDrawer, GuacNotification},
    props: { connectionID:     { default: null },
             control:          { default: true },
             webSocketTunnel:  { default: null },
             httpTunnel:       { default: null },
             defaultView:      { default: 'thumbnail' },
             resolution:       { default: '1920x1080' },
             hideOptions:      { default: false }
    },

    name: 'GuacamoleClient',

    mixins: [ GuacDisplay, GuacConnection, GuacState, GuacInput ],

    beforeDestroy: function(){
      try{ this.tunnel.disconnect() }catch(err){ }
      try{ this.client.disconnect() }catch(err){ }

      this.tunnel = this.display = this.client = this.keyboard = this.error = null;
      this.staticImage = this.options = this.errors = null;
    },

    data () {
      return {
        errors: GuacErrors.ERRORS,
        options: {
          showOptionsDrawer: false,
          showConnectionStatus: true,
          autoScale: true,
          scale: 1,
          tunnelState: 'Not Connected',
          clientState: 'Not Connected'
        },
        tunnel: null,
        staticImage: {
          src: null,
          width: null,
          height: null
        },
        client: null,
        display: null,
        keyboard: null,
        mouse: null,
        error: null,
        viewState: this.defaultView,
        updateActivity: _.throttle(this.emitActivityUpdate, 5000),
      }
    },
    methods: {

      updateStaticImage () {
        if (!this.$refs.display || !this.display || !this.isConnected) return;
        this.staticImage.src = this.display.flatten().toDataURL('image/png')
      },

      fullscreen() {
        fscreen.addEventListener('fullscreenchange', this.fullScreedExited, false)
        fscreen.requestFullscreen(this.$refs.displayWrapper)
        setTimeout(this.adjustScale, 1000)
        // this.$nextTick(this.adjustScale)

      },

      fullScreedExited(){
        if (!fscreen.fullscreenElement) {
          fscreen.removeEventListener('fullscreenchange', this.fullScreedExited, false)
          this.viewState = 'full'
        }
      },

      emitActivityUpdate(){
        this.$emit('activity', Date.now())
      },

      resolutionChange(data){
        this.$emit('resolutionChange', data)
      },

      exitFullscreen(){
        fscreen.exitFullscreen();
        this.viewState = 'full';
      },

      hideNav () {
        this.options.showOptionsDrawer = false
        this.$refs.display.focus()
      },

      setViewState(state) {
        this.viewState = state
        if (this.viewState == 'fullscreen'){
          this.fullscreen()
        }
      }
    },
    computed: {
      isFullscreen () {
        return this.viewState == 'fullscreen'
      },
      isConnected () {
        return this.connectionID && this.status == 'Connected'
      },

      enlargedView () {
        if (!this.isConnected) return false
        if (this.viewState == 'thumbnail') return false
        return true
      },

      clientState () {
        return this.options.clientState.toLowerCase()
      },

      message () {
        if (this.error) {
          // Get Error message
          let message = this.error.message ? this.error.message : 'Connection has been disconnected'
          console.log('Guacamole Error: ' + this.error.message)

          // If reconnection is recommended, emit event to reconnect
          if (this.error.reconnect){
            this.disconnect()
            this.$emit('reconnect')
            console.log('Guacamole Error: ' + this.error.message)
            return
          }

          return message
        }
        return 'Waiting for Guacamole Connection'
      }
    },
    watch: {
      'viewState': function (newState) {
        this.$nextTick( () => {
          this.adjustScale()
          this.$emit('viewStateChanged', newState)
        })
        let interval = setInterval(this.adjustScale, 500)
        setTimeout(() => {
          clearInterval(interval)
        }, 10000)
      },
      'options.showOptionsDrawer': function (showOptionsDrawer) {
        if (!this.keyboard) return;

        if (!showOptionsDrawer) {
          this.keyboard.onkeydown = (keysym) => this.client.sendKeyEvent(1, keysym)
          this.keyboard.onkeyup = (keysym) => this.client.sendKeyEvent(0, keysym)
        } else {
          this.keyboard.onkeydown = null
          this.keyboard.onkeyup = null
        }
      }
    },
    mounted() {
      this.disconnect()
      this.connect()
      setInterval(this.updateStaticImage, 5000)
    }
  }
</script>

<style scoped>

  .static-image{
    position: absolute;
    height: 100%;
  }


  .static-overlay{
    width: 100%;
    height: 100%;
    position: absolute;
    background-color: #676a6cb5
  }

  .guacamoleClient {
    position: inherit;
    padding: 0px;
    border: 0px;
    display: flex;
    flex-flow: column nowrap;

  }

  .guacamoleClient.thumbnail {
    width: 450px;
    z-index: 7;
    border: 1px solid #e8e8e8;
    border-radius: 5px;
    box-sizing: border-box;
  }

  .guacamoleClient.full {
    position: fixed !important;
    top: 0px !important;
    left: 0px !important;

    height: 100% !important;
    width: 100% !important;
    z-index: 9999;
  }



  .display-wrapper{
    background-color: #3d3d5c;;
    display: flex;
    width: 100%;
    flex-direction: column;
    justify-content: center;
    overflow: hidden;
    z-index: 8;
    position: relative;
  }

  .thumbnail .display-wrapper{
    height: 260px;
    width: 450px;
    pointer-events: none;
    z-index: 7;
  }

  .full .client-slot{
    z-index: 10;
  }


  .flex-expand{
    flex: 1 1 auto;
    align-items: center;
  }

  .flex-fixed{
    flex: 0 0 auto;
  }


  .static-wrapper img{
    margin: auto;
  }
  #display div{
    margin: auto;
  }

  .guacamoleClient.connected #display:hover {
    cursor: none;
  }

  .guacamoleClient.connected.no-control #display:hover {
    cursor: inherit;
  }

  .hide-overflow {
    overflow: hidden;
  }

  .guac_client-slot{
    background-color: white;
  }

  .guac-center{
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
    height: 125px;
    width: 400px;
    background-color: #e8e8e8;
  }

  .fade-enter-active, .fade-leave-active {
    transition: opacity 5s;
  }
  .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
    opacity: 0;
  }

</style>
