<template>
  <div>
    <canvas width="600px" height="200px" v-render-wave="{frequency:frequency, amplitude:amplitude, phase:phase}" >
    </canvas>
  </div>
</template>

<script>
export default {
  props : ['amplitudes', 'size', 'frequency', 'amplitude', 'phase'],
  directives : {
    renderWave : function(canvas, data){
      var waves = [{frequency: data.value.frequency, amplitude:data.value.amplitude, phase:data.value.phase}];
      
      var plot = new LinePlot({
        canvas : canvas
      });

      var wavgen = new WaveGenerator({width: canvas.width});
      var buffer = wavgen.render(waves);

      plot.plot(buffer, 2, -2);
    }
  },
  data () {
    return {}
  }
}

function WaveGenerator(opts){
  var buffer = new Float32Array(opts.width||400)

  function renderFn(fn, buffer){
    for(var i=0; i<buffer.length; i++){
      buffer[i] = fn(i); 
    }
  }

  this.render = function(state){
    buffer.fill(0);
    for(var waveIdx=0; waveIdx<state.length; waveIdx++){
      var wave = state[waveIdx];
      var amp = wave.amplitude;
      var freq = wave.frequency;
      var phase = wave.phase / 100;

      for(var x=0; x<buffer.length; x++){
        buffer[x] += Math.sin((freq * -(x / opts.width) + phase) * (Math.PI * 2)) * amp / 100;
      }
    }
    return buffer; 
  }
}

function LinePlot(opts){
  this.canvas = typeof(opts.canvas) === "string" 
              ? document.getElementById(opts.canvas) 
              : opts.canvas;
}
LinePlot.prototype = {
  plot : function(buffer, min, max){
    var hscale = buffer.length / this.canvas.width;
    var vscale = this.canvas.height / (max - min);
    var ctx = this.canvas.getContext("2d");
    ctx.clearRect(0,0,this.canvas.width, this.canvas.height);
    ctx.strokeStyle = "white";
    ctx.beginPath();
    for(var i=0; i < this.canvas.width; i++){
      var bufferIdx = Math.floor(i * hscale)
      var val = Math.floor((buffer[bufferIdx] - min) * vscale);
      ctx[i==0 ? "moveTo" : "lineTo"](i, this.canvas.height - val, 1, 1);
    }
    ctx.stroke();
  }
}
</script>

<style>
</style>
