print("*** LOADING MAP.nas ... ***");
var zoom  = 10;
var width = 768;
var height = 576;

#------------------------------------------------------------------------------- thanks to Harbal1
#===============================================================================
#                                                                      FUNCTIONS

#-------------------------------------------------------------------------------
#                                                                       draw_arc
# this function draws an arc
# params :
# - element     : canvas object created by createChild()
# - center_x    : coord x of the center of the arc in px
# - center_y    : coord y of the center of the arc in px
# - radius      : radius
# - start_angle : start angle in deg ()
# - end_angle   : end angle in deg ()
# - color       : color
# - line_width  : line_width
#
var draw_arc = func(element, center_x, center_y, radius, start_angle, end_angle, color, line_width) {
  var coord_start_x = center_x + (radius * math.cos(start_angle * D2R));
  var coord_start_y = center_y - (radius * math.sin(start_angle * D2R));

  var to_x = -(radius * math.cos(start_angle * D2R)) + (radius * math.cos(end_angle * D2R));
  var to_y = (radius * math.sin(start_angle * D2R)) - (radius * math.sin(end_angle * D2R));

  element.setStrokeLineWidth(line_width)
    .set("stroke", color)
    .moveTo(coord_start_x, coord_start_y)
    .arcSmallCCW(radius, radius, 0, to_x, to_y);

  print("coord_start_x:"~coord_start_x~"| coord_start_y:"~coord_start_y~"| radius:"~ radius ~"| to_x:"~to_x~"| to_y:"~ to_y);
}

#-------------------------------------------------------------------------------
#                                                                     draw_piste
# this function creates a piste
#
# params :
# - element  : canvas object created by createChild()
#
var draw_piste = func(element) {
  element.setStrokeLineWidth(5)
    .set("stroke", "rgba(40, 240, 40, 1)")
    .moveTo(-13, 13)
    .lineTo(-13, -13)
    .moveTo(13, 13)
    .lineTo(13, -13);

  # creation du vecteur vitesse+cap de la cible
  element.setStrokeLineWidth(4)
    .set("stroke", "rgba(40, 240, 40, 1)")
    .moveTo(0, 0)
    .lineTo(0, 0);

  element.setStrokeLineWidth(4)
    .set("stroke", "rgba(40, 240, 40, 1)")
    .moveTo(-12, 11)
    .lineTo(12, 11)
    .moveTo(-12, -11)
    .lineTo(12, -11);
}

#-------------------------------------------------------------------------------
#                                                                   update_piste
# this function updates piste - length of vector = distance in 15s
#
# params :
# - element  : canvas object created by createChild()
# - FIXME ...
#
var update_piste = func(element, my_heading, my_alt, target_heading, target_alt, target_speed, pixel_range, radar_range) {
  var vector_x = ((target_speed * pixel_range / radar_range) / 240) * math.sin((target_heading - my_heading) * D2R);
  var vector_y = ((target_speed * pixel_range / radar_range) / 240) * math.cos((target_heading - my_heading) * D2R);

  if ((target_alt - 1000 ) < my_alt) {
    element._node.getNode("coord[12]", 1).setValue(-12);
  } else {
    element._node.getNode("coord[12]", 1).setValue(12);
  }
  if ((target_alt + 1000 ) > my_alt) {
    element._node.getNode("coord[16]", 1).setValue(-12);
  } else {
    element._node.getNode("coord[16]", 1).setValue(12);
  }
  element._node.getNode("coord[8]", 1).setValue(vector_x);
  element._node.getNode("coord[9]", 1).setValue(-vector_y);
}

#-------------------------------------------------------------------------------
#                                                                update_piste_fl
# this function updates flight level piste label position
#
# params :
# - element  : canvas object created by createChild()
# - FIXME ...
#
var update_piste_fl = func(element, my_heading, target_heading) {
  var vector_x = -30 * math.sin((target_heading - my_heading) * D2R);
  var vector_y =  30 * math.cos((target_heading - my_heading) * D2R);

  element.setTranslation(vector_x, vector_y);
}

var MAPCanvas = {
  canvas_settings: {
    "name": "PFD-Test",       # The name is optional but allow for easier identification
    "size": [1024, 1024],     # Size of the underlying texture (should be a power of 2, required) [Resolution]
    "view": [width, height],  # Virtual resolution (Defines the coordinate system of the canvas [Dimensions]
                              # which will be stretched the size of the texture, required)
    "mipmapping": 1           # Enable mipmapping (optional)
  },
  new: func(placement) {
    var m = {
      parents: [MAPCanvas],
      canvas: canvas.new(MAPCanvas.canvas_settings)
    };
    ## Base for the canvas
    m.canvas.addPlacement(placement);
    m.root = m.canvas.createGroup();
    m.mapStuff = m.root.createChild("group");
    m.radarStuff = m.root.createChild("group"); #Should be replaced by rwr

    #MAP stuff
    m.g_front = m.mapStuff.createChild("group");
    m.g_back = m.mapStuff.createChild("group");

    #Aircraft orientation/position stuff
    m.myHeadingProp = props.globals.getNode("orientation/heading-deg");
    m.myCoord = geo.aircraft_position();

    #Center of the canvas
    m.root.setCenter(384,256);

    ##MAP stuff : Set up of the tiles
    m.tile_size = 256;
    m.num_tiles = [4, 3];

    m.type = "map";
    m.home =  props.globals.getNode("/sim/fg-home");
    m.maps_base = m.home.getValue() ~ '/cache/maps';

    #----------------  Make the url where to take the tiles ------------
    #Some alternative can exist
    # http://otile1.mqcdn.com/tiles/1.0.0/map
    # http://otile1.mqcdn.com/tiles/1.0.0/sat
    # (also see http://wiki.openstreetmap.org/wiki/Tile_usage_policy)

    #var makeUrl  = string.compileTemplate('http://{server}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg');
    #var servers = ["otile1", "otile2", "otile3", "otile4"];

    m.makeUrl  = string.compileTemplate('http://{server}.tile.osm.org/{z}/{x}/{y}.png');
    m.servers = ["a", "b", "c"];
    m.makePath = string.compileTemplate(m.maps_base ~ '/osm-{type}/{z}/{x}/{y}.png');

    #Setting up red little aircraft
    m.center_tile_offset = [
      (m.num_tiles[0] - 1) / 2,
      (m.num_tiles[1] - 1) / 2
    ];
    # simple aircraft icon at current position/center of the map
    m.filename = "Nasal/littleaircraftRed.svg";
    m.svg_symbol = m.root.createChild("group");
    canvas.parsesvg(m.svg_symbol, m.filename);
    m.svg_symbol.setScale(0.05);

    m.svg_symbol.setTranslation((width/2)-20,height/2-45);

    m.myVector = m.svg_symbol.getBoundingBox();
    #svg_symbol.setCenter(width/2,height/2);
    m.svg_symbol.updateCenter();
    m.svg_symbol.set("z-index", 1);

    var make_tiles = func (canvas_group) {
      var tiles = setsize([], m.num_tiles[0]);
      for (var x = 0; x < m.num_tiles[0]; x += 1) {
          tiles[x] = setsize([], m.num_tiles[1]);
          for (var y = 0; y < m.num_tiles[1]; y += 1) {
              tiles[x][y] = canvas_group.createChild("image", "map-tile");
          }
      }
      return tiles;
    }

    #MAP Stuff
    m.tiles_front = make_tiles(m.g_front);
    m.tiles_back  = make_tiles(m.g_back);

    m.use_front = 1;

    m.last_tile = [-1,-1];
    m.last_type = m.type;

    ##ETC all needed for MAP and RWR canvas
    m.zoom = 10;
    m.update_timer = nil;

    ## RADAR STUFF ##
    m.MapToggle = 1;

    ## creation des arcs "range"
    #m.arc_range1 = m.radarStuff.createChild("path", "arc_range1");
    ##m.arc_range1.moveTo(334,256).arcSmallCCW(50, 50, 0,  434, 256);
    #m.arc_range1.setStrokeLineWidth(3)
    #.moveTo(484, 256)
    #.set("stroke", "rgba(100, 100, 100, 1)")
    #.arcSmallCCW(100, 100, 0, -200, 0)
    #.arcSmallCCW(100, 100, 0, 200, 0);

    # draw_arc(m.arc_range1, 384,256 , 100 , 0, 180, "rgba(100, 100, 100, 1)", 3);

    return m;
  },

  changeZoomMap: func(d) {
    new_zoom = math.max(2, math.min(15, me.zoom + d));
    if (new_zoom != me.zoom) {
      me.zoom = new_zoom;
      #debug.dump(zoom);
      #updateTiles();
    }
  },

  updateTiles: func() {
    #print("updateTiles is working");
    me.svg_symbol.setRotation(me.myHeadingProp.getValue()*D2R);
    #g.setRotation(myHeadingProp.getValue()*D2R);
    me.myCoord = geo.aircraft_position();
    lat = me.myCoord.lat();
    lon = me.myCoord.lon();

    var n = math.pow(2, me.zoom);
    var offset = [
      n * ((lon + 180) / 360) - me.center_tile_offset[0],
      (1 - math.ln(math.tan(lat * math.pi/180) + 1 / math.cos(lat * math.pi/180)) / math.pi) / 2 * n - me.center_tile_offset[1]
    ];
    var tile_index = [int(offset[0]), int(offset[1])];

    var ox = tile_index[0] - offset[0];
    var oy = tile_index[1] - offset[1];
    me.g_front.setVisible(me.use_front);
    me.g_back.setVisible(!me.use_front);

    me.use_front = math.mod(me.use_front + 1, 2);

    for (var x = 0; x < me.num_tiles[0]; x += 1) {
      for (var y = 0; y < me.num_tiles[1]; y += 1) {
        if (me.use_front) {
          me.tiles_back[x][y].setTranslation(int((ox + x) * me.tile_size + 0.5), int((oy + y) * me.tile_size + 0.5));
          #debug.dump("updating back");
        } else {
          me.tiles_front[x][y].setTranslation(int((ox + x) * me.tile_size + 0.5), int((oy + y) * me.tile_size + 0.5));
          #debug.dump("updating front");
        }
      }
    }

    if (tile_index[0] != me.last_tile[0] or tile_index[1] != me.last_tile[1] or me.type != me.last_type) {
      for (var x = 0; x < me.num_tiles[0]; x += 1) {
        for (var y = 0; y < me.num_tiles[1]; y += 1) {
          var server_index = math.round(rand() * (size(me.servers) - 1));
          var server_name = me.servers[server_index];
          var pos = {
            z: me.zoom,
            x: int(offset[0] + x),
            y: int(offset[1] + y),
            type: me.type,
            server: server_name
          };

          (func {
            var img_path = me.makePath(pos);

            if (io.stat(img_path) == nil) {
              var img_url = me.makeUrl(pos);
              var message = "Requesting %s...";
              #printf(message, img_url);
              http.save(img_url, img_path)
              .done(func {
                var message = "Received image %s";
                #printf(message, img_path);
                #if (pos.z == zoom) {
                #  tile.setFile(img_path);
                #}
              })
              .fail(func (r) {
                var message = "Failed to get image %s %s: %s";
                #printf(message, img_path, r.status, r.reason);
                me.tiles_back[x-1][y-1].setFile("");
                me.tiles_front[x-1][y-1].setFile("");
              });
            } else {
              if (pos.z == me.zoom) {
                var message = "Loading %s";
                #printf(message, img_path);
                me.tiles_back[x][y].setFile(img_path);
                me.tiles_front[x][y].setFile(img_path);
              }
            }
          })();
        }
      }

      me.last_tile = tile_index;
      me.last_type = me.type;
    }
  },

  updateRadar:func() {
    #Rotating aircraft to the front.
    me.svg_symbol.setRotation(0*D2R);
  },

  changeMfD_Displaying:func() {
    #Temporary function : we change the displaying called : mirage2000.changeMfD_Displaying()
    if (me.MapToggle) {
      me.mapStuff.hide();
      me.radarStuff.show();
      me.MapToggle = 0;
    } else {
      me.mapStuff.show();
      me.radarStuff.hide();
      me.MapToggle = 1;
    }
  },

  update: func() {
    #Whatever need to be updated
    var update_timer = maketimer(0, func(){
      #print("Hello World");
      if (me.MapToggle) {
        me.updateTiles();
      } else {
        me.updateRadar()
      }
    });
    update_timer.start();

  },
  #Other function like zoom in/out changing tile index, etc
};

var MapCanvas = da40.MAPCanvas.new({"node": "canvasCadre", "texture": "canvasTex.png"});

MapCanvas.update();
