|  | <template>
  <div class="explore-layout">
    <div class="explore-log">
      <div class="explore-log-filler"></div>
    </div>
    <div class="explore-worldinfo">
      <p class="worldinfo-date">{{ world.time.format("MMMM Do Y") }}</p>
      <p class="worldinfo-date">{{ world.time.format("hh:mm:ss a") }}</p>
    </div>
    <div class="explore-statblock">
      <Statblock :subject="world.player" :initiative="0" />
      <button @click="$emit('profile')">Show profile</button>
    </div>
    <div class="explore-containers">
      <transition-group name="container">
        <ContainerView v-show="container.contents.concat(container.digested).length > 0" :container="container" v-for="(container, index) in world.player.containers" :key="'explore-container-' + index" />
      </transition-group>
    </div>
    <div class="explore-info">
      <h2 class="location-name">{{ location.name.capital }}</h2>
      <p class="location-desc">{{ location.desc }}</p>
    </div>
    <div class="explore-nav">
      <NavButton @click.native="writeLog(location.connections[direction].travel(world, world.player))" v-for="direction in Object.keys(location.connections)" :key="direction" :style="navBtnCss(direction)" :location="location" :direction="direction" />
    </div>
    <div class="explore-choices">
      <ChoiceButton @click.native="writeLog(choice.execute(world, world.player))" v-for="(choice, index) in location.choices.filter(choice => choice.visible(world))" :key="'choice' + index" :choice="choice" :world="world" />
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { Direction, World, Place } from '@/game/world'
import NavButton from './NavButton.vue'
import ChoiceButton from './ChoiceButton.vue'
import Statblock from './Statblock.vue'
import ContainerView from './ContainerView.vue'
import { LogEntry } from '@/game/interface'
@Component({
  components: {
    NavButton, ChoiceButton, Statblock, ContainerView
  },
  data () {
    return {
      directions: Direction
    }
  }
})
export default class Explore extends Vue {
  get location () {
    return this.world.player.location
  }
  set location (loc: Place) {
    this.world.player.location = loc
  }
  @Prop({ type: World })
  world!: World
  navBtnCss (dir: string) {
    return {
      '--nav-direction': dir
    }
  }
  writeLog (entry: LogEntry) {
    const log = this.$el.querySelector(".explore-log")
    if (log !== null) {
      const rendered = entry.render()
      if (rendered.length > 0) {
        const holder = document.createElement("div")
        holder.classList.add("explore-log-entry")
        entry.render().forEach(element => {
          holder.appendChild(element)
        })
        holder.classList.add("explore-entry")
        const hline = document.createElement("div")
        hline.classList.add("explore-log-separator")
        log.appendChild(hline)
        log.appendChild(holder)
        log.scrollTo({ top: log.scrollHeight, left: 0, behavior: "smooth" })
      }
    }
  }
}
</script>
<style scoped>
.explore-layout {
  flex: 10;
  position: relative;
  display: grid;
  grid-template-areas: "info log log statblock"
                       "info log log containers"
                       "worldinfo log log containers"
                       "nav nav choices containers  ";
  grid-template-rows: fit-content(50%) 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  width: 100%;
  height: 100%;
  max-width: 1500px;
  margin: auto;
  overflow: hidden;
}
.explore-containers {
  grid-area: containers;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  overflow-x: hidden;
}
.explore-containers > .vore-container {
  flex-basis: 25%;
  max-height: 125px;
}
.explore-log {
  grid-area: log;
  background: #222;
  overflow-y: scroll;
  padding: 8pt;
}
.explore-log-filler {
  height: 100%;
}
.explore-worldinfo {
  grid-area: worldinfo;
  background: #111;
  padding: 8px;
}
.worldinfo-date,
.worldinfo-time {
  font-size: 1.25rem;
}
.explore-statblock {
  grid-area: statblock;
}
.explore-info {
  grid-area: info;
  background: #333;
  display: flex;
  flex-direction: column;
  flex-wrap: none;
  justify-content: start;
  align-items: center;
  padding: 8px;
}
.location-name {
  font-size: 2rem;
  margin: 8pt;
}
.location-desc {
  font-size: 1.5rem;
  color: #ccc;
}
.explore-nav {
  padding: 8px;
  position: relative;
  grid-area: nav;
  background: #444;
  display: grid;
  justify-content: center;
  align-content: center;
  grid-template-areas: "Northwest North  Northeast"
                       "West      Center East     "
                       "Southwest South  Southeast";
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr 1fr;
  width: calc(100% - 16px);
  height: calc(100% - 16px);
  justify-self: end;
}
.explore-choices {
  padding: 8px;
  grid-area: choices;
  background: #555;
  display: flex;
  flex-direction: column;
  overflow-y: scroll;
}
.container-enter {
  opacity: 0;
}
.container-enter-active {
  transition: opacity 2s;
}
.container-move {
  transition: transform 1s;
}
.container-leave-active {
  transition: opacity 5s;
  opacity: 0;
}
</style>
<style>
.explore-log-entry {
  animation: explore-entry-fade 1s;
}
@keyframes explore-entry-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1
  }
}
.explore-log-separator {
  animation: explore-log-keyframes 0.5s;
  height: 4px;
  margin: 16pt auto 16pt;
  background: linear-gradient(90deg, transparent, #444 10%, #444 90%, transparent 100%);
}
@keyframes explore-log-keyframes {
  from {
    width: 0%;
  }
  to {
    width: 100%;
  }
}
.explore-log > div:last-child {
  margin-bottom: 8pt;
}
</style>
 |