<script>

// https://brm.io/matter-js/docs/classes/Engine.html
// import {
//   // Engine,
//   // Render,
//   // World,
//   Bodies,
//   Body,
//   Events,
//   Composite,
//   // Composites,
//   // Constraint,
//   // Vertices,
//   // Mouse,
//   // MouseConstraint,
//   // Query,
//   // Common
// } from "matter-js";

import Matter from "matter-js";
import MatterAttractors from "matter-attractors";
// Matter.use(MatterAttractors);
// import polydecomp from "poly-decomp";

// import { easeInOutQuad, easeInOutQuart } from 'easing-utils';
import Tween from "@tweenjs/tween.js";

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

export default {
  inject: ['canvasMap', 'matterEngine'],
  data() {
    return {
      id: null,
      entities: null,
      // opened_entite_id: null,
      canvas: null,
      ctx: null,
      pos : {
        x: 0,
        y: 0
      },
      ray: 60,
      time: 0,
      salientPoints: [],
      scale: 1,
      opacity: 0,
      tween: null,
      body: null,
      body_parts: [],
      constraint: null,
      isHover: false
    }
  },
  props: ['concernement', 'opened'],
  computed: {
    ...mapState(ConcernementsStore,['map_mode']),
    ...mapState(ConcernementsStore,['concernementsByID']),
    ...mapState(ConcernementsStore,['opened_entite_id']),
    ...mapState(CommonStore,['hover_elmt'])
  },
  created () {
    // console.log(`ConcernementsMapItem ${this.concernement.id} created`, this.canvasMap, this.matterEngine);
    this.id = this.concernement.id
    this.entites = this.concernement.entites
    this.entites_byid = this.concernement.entites_byid

    // console.log(`ConcernementsMapItem ${this.concernement.id} $route`, this.id, this.$route);
    // if (this.$route.name === 'concernement'
    //   && parseInt(this.$route.params.id) === this.id
    //   && typeof this.$route.params.eid !== "undefined") {
    //     // console.log("we have an entity");
    //     this.opened_entite_id = parseInt(this.$route.params.eid);
    // }
    
    this.parsePoints()
    this.getSalientPoints()

    if (this.salientPoints.length > 3) { // do not build item if it doesn't get enougth salient points
      if (this.canvasMap) {
        this.initCanvasMap()
      }  
    }

  },
  // mounted() {
  //   console.log(`ConcernementsMapItem ${this.concernement.id} mounted`, this.canvasMap.canvas);
    
  // },
  watch: {
    // canvasMap (n, o) {
    //   console.log("concernementItem watch canvasMap", o, n);
    // }
    canvasMap: {
      handler (n, o){
        // console.log("concernementItem watch canvasMap.ctx", typeof this.canvas, o, n);
        if (!this.canvas) {
          this.initCanvasMap()
        }
      },
      deep: true
    },
    opened: {
      handler (n, o) {

        if(n){ // opened
          this.openClose(true);
        }else{ // closed
          this.openClose(false)
        }
      },
      deep: true
    },
    map_mode: {
      handler (n, o) {
        console.log('watch map_mode', o, n);
        if (n === 'terraindevie') {
          this.applyShuffleForces();
        }
      },
      deep: true
    },
    hover_elmt: {
      handler (n, o) {
        // console.log('watch hover_elmt', o, n);
        if (n && n.type === 'concernement' && n.id === this.id) {
          this.isHover = true;
        } else {
          this.isHover = false;
        }
      },
      deep: true
    }
  },
  methods: {
    parsePoints (){
      // converts data (menace/maintien, actuel/future, prise) into atcual position x,y
      for (let i = 0; i < this.entites.length; i++) {
        let entite = this.entites[i]
        // console.log('entite', entite);
        
        this.entites[i].display = {
          alpha: null,
          ray: null
        }
        // RAYON
        // https://stackoverflow.com/questions/5731863/mapping-a-numeric-range-onto-another
        // slope = (output_end - output_start) / (input_end - input_start)
        // output = output_start + slope * (input - input_start)
        // from range 0 -> 100 to range 0 -> this.ray
        let init_max = 100
        let slope = this.ray / init_max
        this.entites[i].display.ray = slope * (init_max - entite.prise);
        // if (this.concernement.id === 28) {
        //   console.log(`entity prise: ${entite.prise} | ray: ${this.entites[i].display.ray}`);
        // }
        

        // ANGLE
        // -90 <= mm <= 90
        if (entite.actuelfuture) {
          // future en haut : 180 <= a <= 360
          // from -90 -> 90 to range 180 -> 360
          this.entites[i].display.alpha = entite.menacemaintien + 270
        } else {
          // actuel: en bas : O <= a <= 180
          // from -90 -> 90 to range 180 -> 0
          this.entites[i].display.alpha = -1 * entite.menacemaintien + 90
        }

        // POSITION X Y (par rapport au centre du concernement)
        this.entites[i].display.pos = {
          x: this.entites[i].display.ray * Math.cos(this.entites[i].display.alpha * (Math.PI/180)),
          y: this.entites[i].display.ray * Math.sin(this.entites[i].display.alpha * (Math.PI/180))
        }

        this.entites_byid[entite.entite.id].display = this.entites[i].display;
      }
    },
    getSalientPoints () {
      // debugger
      // console.log(this.entites);
      let arc = 360/10;
      // loop through arcs
      // for (let i = 360/arc; i >= 0 ; i--) {
      for (let i = 0; i <= 360/arc ; i++) {
        // loop through entities to find the farest on the arc
        let max_r = 0;
        let farest = null;
        for (let j = 0; j < this.entites.length; j++) {
          let entite = this.entites[j];
          if(arc*i <= entite.display.alpha && entite.display.alpha <= arc*i+arc) { // if entity is in arc
            if (entite.display.ray > max_r) { //  && entite.display.ray > this.ray/2 // and farest from minimu
              // if entity is farest from precedent one 
              max_r = entite.display.ray;
              // recalcul x & y to get a little padding between entite and contour by increasing ray
              farest = {
                alpha: entite.display.alpha,
                ray: entite.display.ray,
                pos: {
                  x: (entite.display.ray + 3) * Math.cos(entite.display.alpha * (Math.PI/180)),
                  y: (entite.display.ray + 3) * Math.sin(entite.display.alpha * (Math.PI/180))
                }
              };
            }
          }
        }
        if (farest) {
          this.salientPoints.push(farest)
        }
      }
      console.log(`this.salientPoints ${this.concernement.id}`, this.salientPoints);
    },
    initCanvasMap (){
      // console.log(`ConcernementsMapItem ${this.concernement.id} initCanvasMap`);
      // record canvas and ctx for rendering (drawing)
      this.canvas = this.canvasMap.canvas
      this.ctx = this.canvasMap.ctx

      // define init position of the item
      this.pos = this.getRandomPos();
      //
      this.initMatterBody()
    },
    getRandomPos(){
      let pad = 200;
      return {
        x: pad + this.ray/2 + Math.random()*(this.canvas.width - this.ray - pad),
        y: pad + this.ray/2 + Math.random()*(this.canvas.height - this.ray - pad)
      };
    },
    initMatterBody (){
      
      // MATTER
      // create the matter body and add it to the engine
      if (!this.body) {
        // console.log('concernementItem creating body');

        // https://github.com/liabru/matter-attractors/issues/8        
        // https://github.com/liabru/matter-attractors/blob/master/index.js
        // MatterAttractors.Attractors.gravityConstant = -5;
        
        // Create parts of the body : main big circle & entities
        this.body_parts = [
          Matter.Bodies.circle(0, 0, this.ray, {
            item_type: 'concernement',
            id: this.concernement.id,
          })
        ];

        // // Create parts of the body : contours
        // if (this.salientPoints.length > 2) {
        //   var decomp = require('poly-decomp');
        //   // window.decomp = decomp;
        //   // debugger;
        //   Matter.Common.setDecomp(decomp);
        //   // Matter.Common.setDecomp(require('poly-decomp'));
          
        //   // let contourpoints = [];
        //   // for (let j = 0; j < this.salientPoints.length; j++) {
        //   //   contourpoints.push(this.salientPoints[j].pos);
        //   // }
        //   let contourpoints = this.salientPoints.map(function(point) {
        //     return point.pos; //[point.pos.x, point.pos.y]
        //   });
        //   // console.log('contourpoints', contourpoints);
        //   // let contourpoints = Matter.Vertices.fromPath('35 7 19 17 14 38 14 58 25 79 45 85 65 84 65 66 46 67 34 59 30 44 33 29 45 23 66 23 66 7 53 7');
          
        //   // let ccw_contourpoints = decomp.makeCCW(contourpoints);
        //   // console.log('ccw_contourpoints', ccw_contourpoints);
        //   let vertices_contour = Matter.Vertices.create(contourpoints);
        //   // console.log('vertices_contour', vertices_contour);
        //   // let vertices_contour_bounds = Matter.Bounds.create(vertices_contour);
        //   // console.log('vertices_contour_bounds', vertices_contour_bounds);
        //   // debugger;
        //   let body_contour = Matter.Bodies.fromVertices(0, 0, vertices_contour, {
        //     mass: 0,
        //     item_type: 'concernement-contours',
        //     id: this.concernement.id,
        //   }, false, 0, 0, 0);
        //   // debugger;
        //   // console.log('body_contour.bounds', body_contour.bounds);
        //   // // https://github.com/liabru/matter-js/issues/186
        //   // Matter.Body.translate(body_contour, Matter.Vector.sub(vertices_contour_bounds.min, body_contour.bounds.min))
        //   this.body_parts.push(body_contour);
        // }

        // Create parts of the body : entities
        for (let i = 0; i < this.entites.length; i++) {
          // parts.push(Matter.Bodies.circle(this.pos.x+this.entites[i].display.pos.x, this.pos.y+this.entites[i].display.pos.y, 15, {
          //   item_type: 'entite',
          //   id: this.entites[i].id  
          // }))
          this.body_parts.push(Matter.Bodies.circle(this.entites[i].display.pos.x, this.entites[i].display.pos.y, 0.8, {
            item_type: 'entite',
            id: this.entites[i].entite.id,
            cid: this.concernement.id,
            agissante: this.entites[i].entite.agissante,
            isSensor: true
          }))
        }
        
        // Create parts of the body : besoins and responses
        this.createBesoinsBodyParts();
        
        // create the body
        this.body = Matter.Body.create({
          parts: this.body_parts,
          item_type: 'concernement',
          id: this.concernement.id,
          frictionAir: 0,
          // mass: Math.pow(3, this.entites.length),
          mass: 10,
          restitution: 0.15,
          collisionFilter: {
            group: -1
          },
          plugin: {
            attractors: [
              // there is a built in helper function for Newtonian gravity!
              // you can find out how it works in index.js
              MatterAttractors.Attractors.gravity
            ]
          }
        });
        Matter.Body.setPosition(this.body, this.pos);

        // add init velocity
        let delta = 10;
        Matter.Body.setVelocity(this.body, {
            x: -delta + Math.random()*delta*2,
            y: -delta + Math.random()*delta*2
          });
        // console.log('concernementItem mass', this.body.mass);
        Matter.Composite.add(this.matterEngine.world, this.body);
        // console.log('concernement body', this.body);

        // // listen for animate event dispatched from parent
        // this.canvas.addEventListener('animate', this.animate)

        // listen for afterUpdate event from Matter.Engine object
        Matter.Events.on(this.matterEngine, "beforeUpdate", this.onBeforeEngineUpdate);
        Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
      }
    },
    createBesoinsBodyParts(){
      let res_fields = ['qui','quoi','ou','avec'];
      let arc = (360 / 16);               // unit arc
      let r = (this.ray * this.scale)/5;  // unit ray
      let br = r - r/3;                   // besoin ray
      for (let i = 0; i < this.concernement.besoins.length; i++) {
        let start_a = arc * i;              // angle depart (for reponses)
        let center_a = start_a + arc/2;     // angle central
        let x = Math.cos(center_a*(Math.PI/180)) * br;
        let y = Math.sin(center_a*(Math.PI/180)) * br;

        this.body_parts.push(Matter.Bodies.circle(x, y, 0.8, {
          item_type: 'besoin',
          id: this.concernement.besoins[i].id,
          cid: this.concernement.id,
          isSensor: true
        }));

        let res_arc = arc / (1 + this.concernement.besoins[i].reponses.length); // unit arc for responses depending responses number
        for (let j = 0; j < this.concernement.besoins[i].reponses.length; j++) {
          let res_a = start_a + res_arc * (j+1); // angle for response line
          for (let f = 0; f < res_fields.length; f++) {
            if(this.concernement.besoins[i].reponses[j][res_fields[f]]){
              let rr = this.ray * this.scale - r*f - r/2; // reponse field ray
              let rx = Math.cos(res_a*(Math.PI/180)) * rr;
              let ry = Math.sin(res_a*(Math.PI/180)) * rr;
              
              this.body_parts.push(Matter.Bodies.circle(rx, ry, 0.8, {
                item_type: 'reponse',
                id: this.concernement.besoins[i].reponses[j].id,
                bid: this.concernement.besoins[i].id,
                cid: this.concernement.id,
                isSensor: true
              }));
            }
          }
        }
      }
    },
    // onBeforeEngineUpdate (event) {
    //   if (this.opened) {
    //     // Matter.Body.setPosition(this.body, this.pos);
    //   }
    // },
    openClose(open) {
      // console.log(`ConcernementsMapItem ${this.concernement.id} openClose: ${open}`);
      if (this.tween) {
        this.tween.stop();
      }
      if (open) {
        // opening tweening
        this.tween = new Tween.Tween({s: this.scale, x: this.pos.x, y: this.pos.y, o: 0})
          .to({
            s: 7,
            x: (this.canvas.width - 450) / 2,
            y: this.canvas.height / 2,
            o: 0.8
          }, 800)
          .onUpdate((obj) => {
            // https://github.com/liabru/matter-js/issues/986#issuecomment-812488873
            // revert to the original size (by reverting the previous scale)
            Matter.Body.scale(this.body, 1 / this.scale, 1 / this.scale)
            // then scale again to new scale
            Matter.Body.scale(this.body, obj.s, obj.s)
            // record new scale
            this.scale = obj.s;
            this.opacity = obj.o;
            
            Matter.Body.setPosition(this.body, {x:obj.x, y:obj.y});
            this.pos = {x:obj.x, y:obj.y};
          })
          .onComplete((obj) => {
            this.constraint = Matter.Constraint.create({
              pointA: this.pos,
              bodyB: this.body,
              stiffness: 1,
              damping: 0,
              length: 0
            });
            Matter.Composite.add(this.matterEngine.world, [this.body, this.constraint]);
          });
          // recreate the matter engine event to get it a the end of the events stack
          Matter.Events.off(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
          Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
      } else {
        // closing
        if(this.constraint){
          Matter.Composite.remove(this.matterEngine.world, this.constraint);
        }
        this.tween = new Tween.Tween({s: this.scale, o: 1})
          .to({s: 1, o: 0}, 500)
          .onUpdate((obj) => {
            // https://github.com/liabru/matter-js/issues/986#issuecomment-812488873
            // revert to the original size (by reverting the previous scale)
            Matter.Body.scale(this.body, 1 / this.scale, 1 / this.scale)
            // then scale again to new scale
            Matter.Body.scale(this.body, obj.s, obj.s)
            // record new scale
            this.scale = obj.s;
            this.opacity = obj.o;
          });
      }
      this.tween.easing(Tween.Easing.Quadratic.InOut).start();
    },
    onBeforeEngineUpdate (event) {
      if (this.tween) {
        this.tween.update();
      }
      if (this.map_mode === 'action' || this.map_mode === 'puissancedagir'){
        this.applyFocusForces();
        // TODO apply a little force to check the map when returning to terrain de vie
      }
      Matter.Body.setAngle(this.body, 0);
      Matter.Body.setAngularSpeed(this.body, 0);
    },
    applyFocusForces(){
      // map_mode action
      var dist, dir, ori_pos;
      var x_force = 0;
      if(!this.isFocused()) {
        // does not has actions -> take a side
        // apply a force in direction of one side or an other depending of the start position
        // the force is exponentialy proportional to the distance from the side
        dir = this.pos.x > this.canvas.width/2 ? 1 : -1; // get the direction to the closest side
        dist = (dir < 0 ? this.pos.x : this.canvas.width - this.pos.x); // get the distance from the side
        ori_pos = {x:this.canvas.width/2, y:this.body.position.y};
        x_force = Math.pow(dist/700,10) * dir;
      }else{
        // has action, get to the centre
        dir = this.pos.x > this.canvas.width/2 ? -1 : 1; // get the direction to the centre
        dist = (dir < 0 ? this.pos.x - this.canvas.width/2 : this.canvas.width/2 - this.pos.x); // get the distance from the side
        ori_pos = dir < 0 ? {x:this.canvas.width, y:this.body.position.y} : {x:0, y:this.body.position.y}
        x_force = Math.pow(dist/800,10) * dir;
        
        this.body.frictionAir = 0.05;
      }
      // x_force = (dist > 200 ? Math.pow(dist/700,10) : 0) * dir
      Matter.Body.applyForce(
        this.body, 
        ori_pos, 
        {
          x: x_force,
          y: 0
        }
      );
    },
    applyShuffleForces() {
      var dist, dir, x_velocity;
      dir = this.pos.x > this.canvas.width/2 ? -1 : 1; // get the direction to the centre
      dist = (dir < 0 ? this.pos.x - this.canvas.width/2 : this.canvas.width/2 - this.pos.x); // get the distance from the side
      x_velocity = Math.pow(dist/650,10) * dir;

      Matter.Body.setVelocity(this.body, {x: x_velocity, y: 0});
    },
    onAfterEngineUpdate (event) {
      // respawn element if outside screen
      if(this.pos.x < 0
        || this.pos.x > this.canvas.width
        || this.pos.y < 0
        || this.pos.y > this.canvas.height){
          this.pos = this.getRandomPos()
          Matter.Body.setPosition(this.body, {x:this.pos.x, y:this.pos.y});
        }
      
      this.draw()
    },
    draw() {

      if (!this.ctx) return;

      // record the position from the main matter body
      this.pos = this.body.position;

      if (this.opened) {
        switch (this.map_mode) {
          case 'terraindevie':
            this.drawBoussole();
            break;
          case 'puissancedagir':
            this.drawPuissanceagir();
            break;
        }
      }

      // contours
      if (!this.opened 
        || (this.opened && this.map_mode !== "puissancedagir")) {
        this.drawContour();
      } 

      // map mode puissance d'agir
      // if not opened and has_puissancedagir draw the puissance d'agir icone
      if (this.concernement.has_puissancedagir && this.map_mode === "puissancedagir") {
        if (!this.opened) {
          this.drawPuissanceagirIcon();
        } else {
          this.drawBesoins()
        }
      }

      if (this.map_mode !== 'puissancedagir') {
        this.drawEntites()
      }
      
      
    },
    drawPuissanceagir(){
      
      for (let i = 1; i < 6; i++) {
        this.ctx.beginPath();
        this.ctx.lineWidth = 0.5;
        this.ctx.strokeStyle = `rgba(255,255,255,1)`;
        this.ctx.arc(this.pos.x, this.pos.y, ((this.ray*this.scale)/5)*i, 0, 2 * Math.PI, false);
        this.ctx.stroke(); 
      }

      this.ctx.beginPath();
      this.ctx.lineWidth = 1;
      this.ctx.strokeStyle = `rgba(255,255,255,1)`;
      this.ctx.setLineDash([5,5]);
      for (let j = 0; j < 4; j++) {
        let a  = (90 / 4) * j;
        // diagonale
        // https://fr.wikipedia.org/wiki/Trigonom%C3%A9trie#/media/Fichier:Unit_circle_angles_color.svg
        // https://fr.wikipedia.org/wiki/Identit%C3%A9_trigonom%C3%A9trique_pythagoricienne#Preuve_utilisant_le_cercle_unit%C3%A9
        // radians = degrees * (pi/180)
        // degrees = radians * (180/pi)
        let x = Math.cos(a*(Math.PI/180)) * this.ray * this.scale;
        let y = Math.sin(a*(Math.PI/180)) * this.ray * this.scale;
        // console.log('m', m);
        this.ctx.moveTo(this.pos.x + x, this.pos.y + y);
        this.ctx.lineTo(this.pos.x - x, this.pos.y - y);
        //
        this.ctx.moveTo(this.pos.x - y, this.pos.y + x);
        this.ctx.lineTo(this.pos.x + y, this.pos.y - x);
      }
      this.ctx.stroke(); 
      this.ctx.setLineDash([]);

      this.ctx.beginPath();
      this.ctx.fillStyle = `rgba(255,255,255,0.6)`;
      this.ctx.lineWidth = 2;
      this.ctx.strokeStyle = `#fff`;
      this.ctx.arc(this.pos.x, this.pos.y, this.ray*this.scale, 0, 2 * Math.PI, false);
      this.ctx.fill();
      this.ctx.stroke()
      this.ctx.closePath();
    },
    drawPuissanceagirIcon(){
      var r = 20 * this.scale; // ray
      var dr = r/2;            // demi ray
      var d = r*2;              // diameter

      this.ctx.beginPath();
      this.ctx.lineWidth = 1;
      this.ctx.strokeStyle = `#000`;
      this.ctx.arc(this.pos.x, this.pos.y, r, 0, 2 * Math.PI, false);
      this.ctx.stroke();
      
      this.ctx.beginPath();
      this.ctx.lineWidth = 1;
      this.ctx.strokeStyle = `#000`;
      this.ctx.arc(this.pos.x, this.pos.y, dr, 0, 2 * Math.PI, false);
      this.ctx.stroke();
      
      this.ctx.beginPath();
      this.ctx.lineWidth = 1;
      this.ctx.strokeStyle = `#000`;
      this.ctx.fillStyle = '#000';
      this.ctx.arc(this.pos.x, this.pos.y, 2*this.scale, 0, 2 * Math.PI, false);
      this.ctx.fill();
      this.ctx.stroke();

      // axes
      this.ctx.beginPath();
      this.ctx.lineWidth = 1;
      this.ctx.strokeStyle = `#000`;
      // vertical
      // this.ctx.moveTo(this.pos.x, this.pos.y - r);
      // this.ctx.lineTo(this.pos.x , this.pos.y - dr);
      // this.ctx.moveTo(this.pos.x, this.pos.y + r);
      // this.ctx.lineTo(this.pos.x , this.pos.y + dr);
      this.ctx.moveTo(this.pos.x, this.pos.y - r);
      this.ctx.lineTo(this.pos.x , this.pos.y + r);
      
      // horizontal
      // this.ctx.moveTo(this.pos.x - r, this.pos.y);
      // this.ctx.lineTo(this.pos.x - dr, this.pos.y);
      // this.ctx.moveTo(this.pos.x + r, this.pos.y);
      // this.ctx.lineTo(this.pos.x + dr, this.pos.y);
      this.ctx.moveTo(this.pos.x - r, this.pos.y);
      this.ctx.lineTo(this.pos.x + r, this.pos.y);

      // diagonale
      // https://fr.wikipedia.org/wiki/Trigonom%C3%A9trie#/media/Fichier:Unit_circle_angles_color.svg
      // https://fr.wikipedia.org/wiki/Identit%C3%A9_trigonom%C3%A9trique_pythagoricienne#Preuve_utilisant_le_cercle_unit%C3%A9
      // radians = degrees * (pi/180)
      // degrees = radians * (180/pi)
      var m = Math.sin(45*(Math.PI/180)) * r;
      // console.log('m', m);
      this.ctx.moveTo(this.pos.x + m, this.pos.y + m);
      this.ctx.lineTo(this.pos.x - m, this.pos.y - m);
      //
      this.ctx.moveTo(this.pos.x - m, this.pos.y + m);
      this.ctx.lineTo(this.pos.x + m, this.pos.y - m);
      
      this.ctx.stroke();
    },
    drawBesoins(){
      for (let i = 0; i < this.body.parts.length; i++) {
        if (this.body.parts[i].item_type === 'besoin' || this.body.parts[i].item_type === 'reponse') {
          let part = this.body.parts[i];
          
          switch (part.item_type) {
            case 'besoin':
              this.ctx.beginPath();
              this.ctx.fillStyle = "#000";
              this.drawDiamond(part.position.x, part.position.y, 4);
              this.ctx.fill();  
              break;
            case 'reponse':
              this.ctx.beginPath();
              this.ctx.fillStyle = "#eee";
              this.ctx.strokeStyle = "#000";
              this.ctx.lineWidth = 1;
              // this.ctx.arc(this.pos.x + rx, this.pos.y + ry, 2*(f+1), 0, 2 * Math.PI, false);
              this.drawDiamond(part.position.x, part.position.y, 5);
              this.ctx.fill();
              this.ctx.stroke();   
              break;
          }
        }
      }
    },
    drawDiamond(x,y,r){
      this.ctx.moveTo(x, y - r);
      this.ctx.lineTo(x + r, y);
      this.ctx.lineTo(x, y + r);
      this.ctx.lineTo(x - r, y);
      this.ctx.lineTo(x, y - r);
    },
    drawBoussole(){
      // BOUSSOLE
      // exterieur circle
      this.ctx.beginPath();
      this.ctx.lineWidth = 2;
      this.ctx.strokeStyle = `rgba(255,255,255,${this.opacity})`;
      // external circle is %8 less than max ray = (*0.92)
      this.ctx.arc(this.pos.x, this.pos.y, this.ray*this.scale*0.92, 0, 2 * Math.PI, false);
      // this.ctx.stroke();

      // interieur circle
      this.ctx.arc(this.pos.x, this.pos.y, this.ray/2*this.scale, 0, 2 * Math.PI, false);
      // this.ctx.stroke();      

      // axes
      // vertical
      this.ctx.moveTo(this.pos.x, this.pos.y - this.ray*this.scale);
      this.ctx.lineTo(this.pos.x, this.pos.y + this.ray*this.scale);
      // horizontal
      this.ctx.moveTo(this.pos.x - this.ray*this.scale, this.pos.y);
      this.ctx.lineTo(this.pos.x + this.ray*this.scale, this.pos.y);
      // this.ctx.stroke();
      
      // fleches
      // haute
      this.ctx.moveTo(this.pos.x - (8*this.scale), this.pos.y - this.ray*this.scale*0.92 + (8*this.scale));
      this.ctx.lineTo(this.pos.x, this.pos.y - this.ray*this.scale*0.92);
      this.ctx.lineTo(this.pos.x + (8*this.scale), this.pos.y - this.ray*this.scale*0.92 + (8*this.scale));      
      // milieu
      this.ctx.moveTo(this.pos.x - (8*this.scale), this.pos.y + (8*this.scale));
      this.ctx.lineTo(this.pos.x, this.pos.y);
      this.ctx.lineTo(this.pos.x + (8*this.scale), this.pos.y + (8*this.scale));

      this.ctx.stroke();

      // MOINS - PLUS
      this.ctx.beginPath();
      this.ctx.lineWidth = 8;
      this.ctx.strokeStyle = `rgba(255,255,255,${this.opacity})`;;
      // PLUS
      // horizontal
      this.ctx.moveTo(this.pos.x + this.ray*this.scale - (5 * this.scale), this.pos.y - this.ray*this.scale);
      this.ctx.lineTo(this.pos.x + this.ray*this.scale + (5 * this.scale), this.pos.y - this.ray*this.scale);
      // vertical
      this.ctx.moveTo(this.pos.x + this.ray*this.scale, this.pos.y - this.ray*this.scale - (5 * this.scale));
      this.ctx.lineTo(this.pos.x + this.ray*this.scale, this.pos.y - this.ray*this.scale + (5 * this.scale));
      
      // MOINS
      // horizontal
      this.ctx.moveTo(this.pos.x - this.ray*this.scale - (5 * this.scale), this.pos.y - this.ray*this.scale);
      this.ctx.lineTo(this.pos.x - this.ray*this.scale + (5 * this.scale), this.pos.y - this.ray*this.scale);
      // vertical

      this.ctx.stroke();
    },
    drawEntites(){
      // IF OPENED
      if (this.opened) { 
        // place all entities points
        // OR using entitées matter bodies
        for (let i = 0; i < this.body.parts.length; i++) {
          if (this.body.parts[i].item_type === 'entite' 
            // draw only entite agissante if map mode is action
            && ((this.map_mode === 'action' && this.body.parts[i].agissante) || this.map_mode !== "action")) {
            let part = this.body.parts[i];
            this.ctx.beginPath();
            this.ctx.arc(part.position.x, part.position.y, 0.3*this.scale, 0, 2 * Math.PI, false);
            // console.log(part.id, this.opened_entite_id);
            if (part.id === this.opened_entite_id) {
              this.ctx.fillStyle = "#01ffe2";
            } else {
              this.ctx.fillStyle = "#000";
            }
            this.ctx.fill();
          }
        }
      }
        // IF CLOSED
      else {
        // map mode action
        // if not opened and has_agissantes draw only entites agissantes
        if (this.concernement.has_agissantes && this.map_mode === "action") {
          for (let i = 0; i < this.body.parts.length; i++) {
            if (this.body.parts[i].item_type === 'entite' && this.body.parts[i].agissante) {
              let part = this.body.parts[i];
              this.ctx.beginPath();
              this.ctx.arc(part.position.x, part.position.y, 1*this.scale, 0, 2 * Math.PI, false);
              // console.log(part.id, this.opened_entite_id);
              if (part.id === this.opened_entite_id) {
                this.ctx.fillStyle = "#01ffe2";
              } else {
                this.ctx.fillStyle = "#000";
              }
              this.ctx.fill();
            }
          }
        }
        

      }
    },
    drawContour(){
      if (this.salientPoints.length > 3) {
        var fillStyle;
        let strokeStyle = "#000";
        if (!this.isFocused()){
          fillStyle = "rgba(255,255,255,0.3)";
        }else{
          fillStyle = "rgba(255,255,255,0.8)"
          if (this.isHover) {
            strokeStyle = "#01ffe2";
          }
        }
        this.ctx.beginPath();
        this.ctx.lineWidth = 1;
        this.ctx.strokeStyle = strokeStyle;
        this.ctx.fillStyle = fillStyle;
        let gap = 1;//1.15;
        this.ctx.moveTo(this.pos.x+this.salientPoints[0].pos.x*this.scale*gap, this.pos.y+this.salientPoints[0].pos.y*this.scale*gap)
        for (let j = 1; j < this.salientPoints.length; j++) {
          this.ctx.lineTo(this.pos.x+this.salientPoints[j].pos.x*this.scale*gap, this.pos.y+this.salientPoints[j].pos.y*this.scale*gap)
        }
        this.ctx.lineTo(this.pos.x+this.salientPoints[0].pos.x*this.scale*gap, this.pos.y+this.salientPoints[0].pos.y*this.scale*gap)
        this.ctx.fill();
        this.ctx.stroke();

        // // test draw contour from body part
        // for (let i = 0; i < this.body.parts.length; i++) {
        //   if (this.body.parts[i].item_type === 'concernement-contours'){
        //     // console.log('concernement contours', this.body.parts[i]);
        //     this.ctx.beginPath();
        //     this.ctx.lineWidth = 1;
        //     this.ctx.strokeStyle = "#F00";
        //     this.ctx.moveTo(this.body.parts[i].vertices[0].x, this.body.parts[i].vertices[0].y);
        //     for (let j = 1; j < this.body.parts[i].vertices.length; j++) {
        //       this.ctx.lineTo(this.body.parts[i].vertices[j].x, this.body.parts[i].vertices[j].y);
        //     }
        //     this.ctx.lineTo(this.body.parts[i].vertices[0].x, this.body.parts[i].vertices[0].y);
        //     this.ctx.stroke();
          
        //       // for (let k = 0; k < this.body.parts[i].parts.length; k++) {
        //     //   let part = this.body.parts[i];
        //     //   let partpart = part.parts[k];
        //     //   debugger;
        //     //   this.ctx.beginPath();
        //     //   this.ctx.lineWidth = 1;
        //     //   this.ctx.strokeStyle = "#F00";
        //     //   this.ctx.moveTo(this.body.parts[i].parts[k].vertices[0].x, this.body.parts[i].parts[k].vertices[0].y);
        //     //   for (let j = 1; j < this.body.parts[i].parts[k].vertices.length; j++) {
        //     //     this.ctx.lineTo(this.body.parts[i].parts[k].vertices[j].x, this.body.parts[i].parts[k].vertices[j].y);
        //     //   }
        //     //   this.ctx.lineTo(this.body.parts[i].parts[k].vertices[0].x, this.body.parts[i].parts[k].vertices[0].y);
        //     //   this.ctx.stroke();
              
        //     // }
        //   } 
        // }
      }
    },
    isFocused(){
      return this.map_mode === 'terraindevie'
          || (this.map_mode === 'action' && this.concernement.has_agissantes)
          || (this.map_mode === 'puissancedagir' && this.concernement.has_puissancedagir);
    }
  },
  render() {
    // console.log('render()', this.ctx);
  },
}

</script>
