<template>
  <div class="simeon">
    <div class="simeon-wrapper">
      <div class="overlay">
        <div class="start">
          <div class="score">
            {{score}}
          </div>

          <button :disabled="started" @click="startGame()">
            START
          </button>
        </div>

        <div class="reset">
          <button @click="reset()">
            RESET
          </button>
        </div>
      </div>
      <div class="simeon-game-board">
        <div :key="space"
          @click="checkInput(i)"
          v-for="(space,i) in spaces"
          :class="[space.klass, {fail: fail, success: success}] "
          class="simeon-game-spaces">

          <div class="lite" :class="{blink: blink == i}">
            <div class="key">
              {{space.key}}
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>


const getAudioContext = () => {
  let ctx = null, usingWebAudio = true;

  try {
    // Fix up for prefixing
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    ctx = new AudioContext();

    // context state at this time is `undefined` in iOS8 Safari
    if (usingWebAudio && ctx.state === 'suspended') {
      var resume = function () {
        ctx.resume();

        setTimeout(function () {
          if (ctx.state === 'running') {
            document.body.removeEventListener('touchend', resume, false);
          }
        }, 0);
      };
      document.body.addEventListener('touchend', resume, false);
    }

    return ctx

  } catch (e) {
    usingWebAudio = false;
    alert('Sorry, Web Audio API is not supported in this browser');
    return null;
  }
};

export default {
  name: 'App',
  components: {
  },

  data() {
    return {
      started: false,
      audioContext: null,
      oscMain: null,
      gainMain: null,
      volume: 60,
      count: 4,
      score: 0,
      blink: null,
      check: [],
      pattern: [],
      running: false,
      fail: false,
      success: false,
      playing: false,
      spaces: [
        {
          key: "Q",
          tone: 196.00,
          klass: 'piece-t-l'
        },
        {
          key: "W",
          tone: 220.00,
          klass: 'piece-t-r'
        },
        {
          key: "A",
          tone: 261.63,
          klass: 'piece-b-l'
        },
        {
          key: "S",
          tone: 293.66,
          klass: 'piece-b-r'
        },
      ]
    }
  },

  created() {
    window.addEventListener('keyup', (e) => {
      if (e.key == 'q') {
        this.playOSC(this.spaces[0].tone)
        this.checkInput(0)
      }
    })

    window.addEventListener('keyup', (e) => {
      if (e.key == 'w') {
        this.playOSC(this.spaces[1].tone)
        this.checkInput(1)
      }
    })

    window.addEventListener('keyup', (e) => {
      if (e.key == 'a') {
        this.playOSC(this.spaces[2].tone)
        this.checkInput(2)
      }
    })

    window.addEventListener('keyup', (e) => {
      if (e.key == 's') {
        this.playOSC(this.spaces[3].tone)
        this.checkInput(3)
      }
    })
  },

  methods: {
    playOSC: function (freq = 440.0, type = 'sine') {
      if (this.oscMain != null) {
        console.log("stopping")
        this.oscMain.stop();
        this.oscMain = null;
      }

      this.oscMain = null;
      this.oscMain = this.audioContext.createOscillator();

      this.oscMain.type = type;
      this.oscMain.frequency.value = freq;

      this.gainMain = this.gainMain || this.audioContext.createGain();
      this.gainMain.gain.value = this.volume / 100.0;

      this.oscMain.connect(this.gainMain);
      this.gainMain.connect(this.audioContext.destination);

      this.oscMain.start();
      this.oscMain.stop(this.audioContext.currentTime + 0.2);
    },

    checkInput(i) {
      if(!this.playing) {
        if(this.check.length < this.pattern.length) {
          this.playOSC(this.spaces[i].tone)
          this.check.push(i)
        }

        for(let i = 0; i < this.check.length; i++) {
          if(this.check[i] != this.pattern[i]) {
            this.fail = true
          }
        }

        if(!this.fail && (this.check.length == this.pattern.length)) {
          this.score += 1
          this.check = []
          this.success = true

          setTimeout(()=>{

            setTimeout(()=>{
              this.success = false
              this.fail = false
            },200)

            this.check = []
            this.addToPattern()
            this.playPattern()
          },200)
        }
      }
    },

    startGame() {
      this.started = true
      if(!this.audioContext) {
        this.audioContext = getAudioContext()
      }

      this.playOSC(this.spaces[0].tone)

      this.reset()
    },

    reset() {
      this.fail = false
      this.success = false
      this.pattern = []
      this.check = []
      this.score = 0
      //this.generatePattern()
      this.addToPattern()
      this.playPattern()
    },

    playPattern() {
      this.playing = true
      for(let i = 0; i < this.pattern.length; i++ ) {
        setTimeout(()=> {
          setTimeout(()=> {
            this.blink = this.pattern[i]
            this.playOSC(this.spaces[this.pattern[i]].tone)
          }, 900)

          setTimeout(()=> {
            this.blink = null
            if(i == this.pattern.length - 1) {
              this.playing = false
            }
          }, 1000)
        }, 600 * (i+1))
      }
    },

    addToPattern() {
      this.pattern.push(Math.floor(Math.random() * 4))
    },

    generatePattern() {
      let pattern = []

      for(let i = 0; i < this.count; i++ ) {
        pattern[i] = Math.floor(Math.random() * 4)
        setTimeout(()=> {
          setTimeout(()=> {
            this.blink = pattern[i]

          }, 600)

          setTimeout(()=> {
            this.blink = null
          }, 800)
        }, 600 * (i+1))
      }

      this.pattern = pattern

      return pattern
    }
  }
}
</script>

<style>
html, body{
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background: black;
}
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.simeon-wrapper {
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  -moz-transform: translateX(-50%) translateY(-50%);
  -webkit-transform: translateX(-50%) translateY(-50%);
  transform: translateX(-50%) translateY(-50%);
  display: flex;
  align-items: center;
  vertical-align: middle;
  justify-content: center;
  margin: auto;
  width: 100%;
  max-width: 640px;
  height: 100vw;
  max-height: 640px;
  border: 3px dotted black;
}


.simeon-game-board {
  display: grid;
  grid-template-columns: 50% 50%;
  width: 75%;
  height: 75%;
}

.overlay {
  background: #585858;
  border-radius: 100%;
  width: 30%;
  height: 30%;
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  border: 16px solid black;
  transform: translateX(-50%) translateY(-50%);
}

.score {
  background: black;
  border-radius: 6px;
  color: #fd0010;
  width: 50%;
  height: 32px;
  font-size: 18px;
  font-family: Courier New;
  line-height: 32px;
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
}

.simeon-game-spaces {
  box-sizing: border-box;
  align-content: center;
  justify-content: center;
  vertical-align: middle;
  display: grid;
  width: 100%;
  height: 100%;
  border: 8px solid black;
  box-shadow: inset -12px -9px 20px 2px #000000a6; /*inset 9px 4px 6px 2px white*/

}

.piece-t-l {
  background: #12cb56;
  border-top-left-radius: 100%;
}
.piece-t-r {
  background: #fd0010;
  border-top-right-radius: 100%;
}
.piece-b-l {
  background: #f1c200;
  border-bottom-left-radius: 100%;
}
.piece-b-r {
  background: #1264ca;
  border-bottom-right-radius: 100%;
}

.lite {
  font-size: 25px;
  font-weight: bold;
  line-height: 50px;
  color: white;
  box-sizing: border-box;
  border-radius: 100%;
  height: 50px;;
  width: 50px;
}

.blink {
  background: #ffffff7d;
  box-shadow: 0px 0px 22px 12px white;
}

.start, .reset {
  height: 50%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
}

.start button, .reset button {
  outline: none;
  font-size: 24px;
  font-weight: bold;
  height: 100%;
  background: darkslategray;
  text-shadow: 0px 0px 3px white;
  color: black;
  width: 100%;
}

.start button {
  border-radius: 100px 100px 0 0;
}

.reset button {
  border-radius: 0 0 100px 100px;
}

.fail {
  background: #fd0010;
}

.success {
  /*background: #12cb56;*/
  background: White;
}

.level {
  font-size: 32px;
  font-family: Courier;
  font-weight: bold;
  width: 100%;
  color: #f1c200;
  box-sizing: border-box;
  text-align: center;
  position: absolute;
  bottom: 0;
  left: 0;
  padding: 16px;
}

@media (max-width:640px) {
  .simeon-wrapper {
    max-width: 100%;
  }

  .simeon-game-board {
    width: 100%;
    height: 100%;
  }
  .start button, .reset button {
    font-size: 14px;
  }
  .key {
    display: none;
  }
}
</style>
