<script>

// import { mapActions, mapState } from 'pinia'
import { computed } from 'vue'
import MapBackground from '@components/MapBackground.vue'

// https://brm.io/matter-js/docs/classes/Engine.html
import Matter from "matter-js";

import MatterAttractors from "matter-attractors";
Matter.use(MatterAttractors);

import paper from 'paper';

import { mapState, mapActions } from 'pinia'
import { ConcernementsStore } from '@/stores/concernements'
import { CommonStore } from '@/stores/common'

import ConcernementMapPopup from '@components/ConcernementMapPopup.vue';

export default {
  data() {
    return {
      canvasMap: {
        canvas: null,
        ctx: null
      },
      animateEvent: new Event('animate'),
      granim: null,
      // MATTER
      engine: null,
      world: null,
      // PAPERJS
      paper: null,
      //
      mapPopupData: null,
    }
  },
  provide() {
    // https://www.digitalocean.com/community/tutorials/vuejs-vue-html5-canvas
    return {
      // explicitly provide a computed property
      canvasMap: computed(() => this.canvasMap),
      matterEngine: computed(() => this.engine)
    }
  },
  computed: {
    ...mapState(ConcernementsStore,['map_mode']),
    ...mapState(ConcernementsStore,['concernements']),
    ...mapState(ConcernementsStore,['concernementsByID']),
    // ...mapState(ConcernementsStore,['opened_concernement']),
    ...mapState(CommonStore,['hover_elmt']),
    ...mapState(CommonStore,['paper_symbol_definitions'])
  },
  created() {
    // MATTER
    // create an engine
    let engineOptions = {
      enableSleeping: true,
      timing: {
        //timestamp: 0.5,
        timeScale: 0.5
      }
    }
    this.engine = Matter.Engine.create(engineOptions);
    this.engine.gravity.scale = 0;
    this.world = this.engine.world;
  },
  mounted() {
    this.canvasMap.canvas = this.$refs['canvas-map'];
    this.canvasMap.ctx = this.canvasMap.canvas.getContext('2d');

    let canvas_w = this.canvasMap.canvas.width = this.canvasMap.canvas.parentElement.clientWidth;
    let canvas_h = this.canvasMap.canvas.height = this.canvasMap.canvas.parentElement.clientHeight;
    console.log(`canvas_w: ${canvas_w}, canvas_h: ${canvas_h}`);

    // PAPER
    this.paper = paper.setup(this.canvasMap.canvas);
    
    // symbol defintions
    this.initPaperSymbols();

    // use the paper.view click to get back if no items is clicked
    this.paper.view.onClick = function(event) {
      console.log("view onClick", this, event.target);
      if(event.target._id === "paper-view-0") {
        this.resetConcernementOpened();
        this.$router.push({
          name: 'home',
          hash: `#${this.map_mode}`
        });
      }
    }.bind(this);

    // MATTER
    let wall_w = 100;
    Matter.Composite.add(this.world, [
        // walls
        Matter.Bodies.rectangle(canvas_w/2,        -wall_w/2,         canvas_w, wall_w,   { isStatic: true }),   // top
        Matter.Bodies.rectangle(canvas_w/2,        canvas_h+wall_w/2, canvas_w, wall_w,   { isStatic: true }),   // bottom
        Matter.Bodies.rectangle(-wall_w/2,         canvas_h/2,        wall_w,   canvas_h, { isStatic: true }),   // left
        Matter.Bodies.rectangle(canvas_w+wall_w/2, canvas_h/2,        wall_w,   canvas_h, { isStatic: true }),   // right
        // make the items never goes under menus
        Matter.Bodies.rectangle(550,          25, 900, 50, { isStatic: true }),  // menu top
        Matter.Bodies.rectangle(550, canvas_h-15, 900, 30, { isStatic: true })   // menu bottom
    ]);

    // add mouse control
    // https://github.com/liabru/matter-js/issues/491#issuecomment-331329404
    // this.mouse = Matter.Mouse.create(this.canvasMap.canvas);

    this.animate()
  },
  watch: {
    hover_elmt: {
      handler (n, o) {
        // console.log(`watch hover_elmt map`, o, n);
        // over highlight effect on paper items
        if (n && n.paper_id) {
          let nitem = paper.project.getItem({id: n.paper_id});
          nitem.bringToFront();
          if (nitem.strokeColor) {
            nitem.data.prevStrokeColor = nitem.strokeColor.toCSS(true);
            nitem.strokeColor = "#01ffe2";          
          } else {
            nitem.data.prevFillColor = nitem.fillColor.toCSS(true);
            nitem.fillColor = "#01ffe2";
          }
        }
        if (o && o.paper_id) {
          let oitem = paper.project.getItem({id: o.paper_id})
          if (oitem.data.prevStrokeColor) {
            oitem.strokeColor = oitem.data.prevStrokeColor;
          } else {
            oitem.fillColor = oitem.data.prevFillColor;
          }
        }
      },
      deep: true
    }
  },
  methods: {
    ...mapActions(ConcernementsStore,['setMapMode']),
    ...mapActions(ConcernementsStore,['resetConcernementOpened']),
    // ...mapActions(ConcernementsStore,['openCloseConcernements']),
    ...mapActions(CommonStore,['addPaperSymbolDefinition']),
    animate () {
      Matter.Engine.update(this.engine, 1);
      window.requestAnimationFrame(this.animate);
    },
    initPaperSymbols(){
      this.addPaperSymbolDefinition('boussole_bg', this.setPaperBoussoleBGSymbol());
    },
    setPaperBoussoleBGSymbol(){
      // BOUSSOLE
      let children = [];
      let ray = 100;
      let pos = {x:0, y:0};

      // cercles pointillés
      for (let i = 1; i < 9; i++) {
        let sw = i === 4 || i === 8 ? 0.5 : 0.25;
        let da = i === 4 || i === 8 ? null : [5,5];
        children.push(new paper.Path.Circle({
          center: [pos.x, pos.y],
          radius: ray/8*i,
          strokeColor: '#fff',
          strokeWidth: sw,
          dashArray: da
        }));
        
      }

      // axes
      // vertical
      children.push(new paper.Path.Line({
        from: [pos.x, pos.y - ray],
        to: [pos.x, pos.y + ray],
        strokeColor: '#fff',
        strokeWidth: 0.5
      }));
      // horizontal
      children.push(new paper.Path.Line({
        from: [pos.x - ray, pos.y],
        to: [pos.x + ray, pos.y],
        strokeColor: '#fff',
        strokeWidth: 0.5
      }))
      
      // fleches
      // haute
      children.push(new paper.Path({
        segments: [
          [pos.x - 8, pos.y - ray + 8],
          [pos.x, pos.y - ray],
          [pos.x + 8, pos.y - ray + 8],
        ],
        strokeWidth: 0.5,
        strokeColor: '#fff',
      }));
      // milieu
      children.push(new paper.Path({
        segments: [
        [pos.x - 8, pos.y + 8],
        [pos.x, pos.y],
        [pos.x + 8, pos.y + 8],
        ],
        strokeWidth: 0.5,
        strokeColor: '#fff',
      }));


      // MOINS - PLUS
      // PLUS
      // horizontal
      children.push(new paper.Path.Line({
        from: [pos.x + ray - 5, pos.y - ray],
        to: [pos.x + ray + 5, pos.y - ray],
        strokeWidth: 2,
        strokeColor: '#fff',
      }))
      // vertical
      children.push(new paper.Path.Line({
        from: [pos.x + ray, pos.y - ray - 5],
        to: [pos.x + ray, pos.y - ray + 5],
        strokeWidth: 2,
        strokeColor: '#fff',
      }))
      
      // MOINS
      // horizontal
      children.push(new paper.Path.Line({
        from: [pos.x - ray - 5, pos.y - ray],
        to: [pos.x - ray + 5, pos.y - ray],
        strokeWidth: 2,
        strokeColor: '#fff',
      }))

      let fontsize = 4;
      let fontFamily = "public_sans";
      
      children.push(new paper.PointText({
        point: [pos.x + 4.5, pos.y - ray - 5],
        content: `entités qui menacent \u2194 entités qui maintiennent`,
        fontSize: fontsize,
        fontFamily: fontFamily,
        justification: 'center',
        fillColor: '#000',
      }))

      children.push(new paper.PointText({
        point: [pos.x - ray - 5, pos.y + 1],
        content: "axe d'intensité",
        fontSize: fontsize,
        fontFamily: fontFamily,
        justification: 'right',
        fillColor: '#000',
      }))

      children.push(new paper.PointText({
        point: [pos.x + ray + 5, pos.y - 3],
        content: "situation future\n\u2195\nsituation actuelle",
        fontSize: fontsize,
        fontFamily: fontFamily,
        justification: 'left',
        fillColor: '#000',
      }))


      let t1 = new paper.PointText({
        point: [pos.x - ray/8*2.3, pos.y - ray/8*2.3],
        content: "avec prise",
        fontSize: fontsize,
        fontFamily: fontFamily,
        justification: 'center',
        fillColor: '#000',
      })
      t1.rotate(-45)
      children.push(t1)

      let t2 = new paper.PointText({
        point: [pos.x - ray/8*2.95, pos.y - ray/8*2.95],
        content: "sans prise",
        fontSize: fontsize,
        fontFamily: fontFamily,
        justification: 'center',
        fillColor: '#000',
      })
      t2.rotate(-45)
      children.push(t2)


      return new paper.Group({
        children: children,
        pivot: new paper.Point(pos),
        name: 'boussole_bg',
        locked: true,
      });

    }
  },
  beforeUpdate () {
  },
  components: {
    MapBackground,
    ConcernementMapPopup
  }
}

</script>

<template>
  <div id="map-backgrounds">
    <MapBackground />
  </div>
  <div id="map-matter">
    <canvas ref="canvas-engine"></canvas>
  </div>
  <div id="map-concernements">
    <canvas ref="canvas-map"></canvas>
    <slot></slot>
  </div>
  <nav id="map-nav">
    <ul>
      <li>
        <a href="#terraindevie" @click="setMapMode('terraindevie')"><span class="icon terraindevie"></span>  terrain de vie</a>
      </li>
      <li>
        <a href="#proximite" @click="setMapMode('proximite')"><span class="icon proximite"></span>  proximité</a>
      </li>
      <li>
        <a href="#superposition" @click="setMapMode('superposition')"><span class="icon superposition"></span>  superposition</a>
      </li>
      <li>
        <a href="#puissancedagir" @click="setMapMode('puissancedagir')"><span class="icon puissancedagir"></span>  puissance d'agir</a>
      </li>
      <li>
        <a href="#action" @click="setMapMode('action')"><span class="icon action"></span>  action</a>
      </li>
      <li>
        <a href="#doleancer" @click="setMapMode('doleancer')"><span class="icon doleancer"></span>  cercle politique</a>
      </li>
    </ul>
  </nav>
  <ConcernementMapPopup
    v-if="hover_elmt && hover_elmt.type !== 'doleance_step'"
    :infos="hover_elmt"
  />  
</template>

<style lang="css" scoped>

</style>
