<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babylonjs/2.5.0/babylon.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <template id="stage">
      <div class="stage-container">
      <div class="controls">
        <button @click="addBall">Add Tree</button>
        <p style="color:white; ;">Add trees, click 'em. That's it.</p>
      </div>
      <div class="info" v-if="hoveredMesh">{{hoveredMesh}}</div>
        <canvas class="stage" id="stage" ref="canvas" @click="canvasClick" @mousemove="canvasHover"></canvas>
      </div>
    </template>
    <script src="script.js"></script>
  </body>
</html>



// Code goes here

class Piece {
  constructor(scene, key, x, y, z, size) {
    this.scene = scene
    this.key = key;
    this.x = x;
    this.y = y;
    this.z=z;
    this.position = new BABYLON.Vector3(this.x, this.y, this.z);
    this.meshes = [];
    let stumpMaterial = new BABYLON.StandardMaterial('stump-mat-' + key, this.scene);
    stumpMaterial.diffuseColor = new BABYLON.Color3(.3, .15, .13);
    this.top = this.makeTop();
    this.bottom = this.makeBottom();
    this.stump = this.makeStump();
    this.stump.material = stumpMaterial;
    this.meshes= [...this.meshes, ...[this.top, this.bottom, this.stump]];
  }
  makeTop(){
    let _this = this;
    var top = BABYLON.MeshBuilder.CreateCylinder("cone", {diameterTop: 0, height:1, size: .5, tessellation: 6}, _this.scene);
    var newY = this.position.y + .7;
    top.parentMesh = _this;
    top.position = new BABYLON.Vector3(this.position.x, newY, this.position.z)
    return top;
  }
  makeBottom(){
    let _this = this;
    var bottom = BABYLON.MeshBuilder.CreateCylinder("cone", {diameterTop: 0, diameterBottom: 1.5, height: 1.2, tessellation: 6}, _this.scene);
    bottom.position = this.position
    bottom.parentMesh = _this;
    return bottom;
  }
  makeStump(){
    let _this = this;
    var stump = BABYLON.MeshBuilder.CreateCylinder("cone", {diameterTop: 0, diameterBottom: .5, diameterTop:.5, height: 1, tessellation: 6}, _this.scene);
    var newY = this.position.y - .8;
    stump.parentMesh = _this;
    stump.position = new BABYLON.Vector3(this.position.x, newY, this.position.z);
    stump.ignoreMaterials = true;
    return stump;
  }
  assignMaterial(mat){
    this.meshes.forEach(mesh=>{
      if(mesh.ignoreMaterials) return;
      mesh.material = mat;
    })
  }
  remove(){
    this.meshes.forEach( mesh=>{
      mesh.dispose();
    });
  }
}
const Stage = {
  data() {
    return {
      app: null,
      balls: 0,
      engine: null,
      canvas: null,
      scene: null,
      hoveredMesh: null,
      assets: {},
      selectedBall: null,
      previousMaterial: null
    }
  },
  mounted() { 
    this.init()
    console.log(this.scene)
  },
  methods: {
     init() {
       const _this = this;
       this.canvas = this.$refs.canvas;
       this.engine = new BABYLON.Engine(this.canvas, true);
        this.scene = new BABYLON.Scene(this.engine);
       this.mainCamera =  new BABYLON.ArcRotateCamera("ArcRotateCamera", 1.5, 1.3, 20, BABYLON.Vector3.Zero(), this.scene);
       this.mainLight = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0,1,0), this.scene);
       this.scene.beforeRender = function() {
       }
       this.engine.runRenderLoop(function() {
         _this.scene.render();
       });
       window.addEventListener('resize', function() {
         _this.engine.resize();
       });
       setTimeout(() => {
         this.addBall();
       }, 500);
       setTimeout(() => {
         this.addBall();
       }, 1000);
       setTimeout(() => {
         this.addBall();
       }, 1500);
     },
     addBall() {
      if (this.balls >= 25)
      {
        alert('Play with the trees you\'ve got!');
        return;
      }
      let x = Math.random() * 10;
      x = Math.random() > .5 ? x : -x;
      let y = 1
      //Math.random() * 5;
      let z = Math.random() * 5;
      let size = Math.random() * 5;
      this.balls ++;
      let key = this.balls;
      let orb = new Piece(this.scene, key, x, y, z, size)
      orb.top.actionManager = new BABYLON.ActionManager(this.scene);	
      let orbMat = new BABYLON.StandardMaterial('orbMat-' + key, this.scene);
      orbMat.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
      orb.assignMaterial(orbMat);
    },
    canvasHover(e) {
      console.log(this.hoveredItem)
    },
    canvasClick(evt) {
      var _this = this;
      var pickResult = this.scene.pick(evt.clientX, evt.clientY);
      var mesh = pickResult.pickedMesh;
      if(!mesh) return false;
      if(this.selectedMesh && this.previousMaterial)
      {
        this.selectedMesh.material = this.previousMaterial;
      }
      this.selectedMesh = mesh;
      var mat = mesh.material;
      this.previousMaterial = mat;
      var newMat = new BABYLON.StandardMaterial('testMat', this.scene);
      newMat.diffuseColor = new BABYLON.Color3(1, 1, 1);
      mesh.parentMesh.assignMaterial(newMat);
      setTimeout(() => {
        this.balls--;
        mesh.parentMesh.remove();
      }, 30)
    },
    canvasHover() {
      this.hoveredMesh = this.scene.meshUnderPointer || false
    },
    mouseOverMesh (unit_mesh) {
    },
    mouseOutUnit (unit_mesh) {
    }
  },
  computed: {
    hoveredItem() {
      return this.scene && this.scene.meshUnderPointer || false;
    }
  },
  template: "#stage"
};
new Vue({
  el: "#app",
  render: h => h(Stage)
})



/* Styles go here */

body{
  display:block;
  width:100%;
  height:100vh;
  overflow:hidden;
}
.stage-container{
  width:100%;
  height:100%;
  position:relative;
}
.stage{
  display:block;
  width:100%;
  height:100%;
}
.controls{
  position:absolute;
  top:10px;
  left:10px;
  z-index:9999;
}
.info{
  display:block;
  position:absolute;
  right:0;
  top:0;
  z-index:9999;
}