text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  const dom_1 = require("../../../core/dom");
  const types_1 = require("../../../core/util/types");
  const poly_tool_1 = require("./poly_tool");
  const icons_1 = require("../../../styles/icons");
  class PolyEditToolView extends poly_tool_1.PolyToolView {
      constructor() {
          super(...arguments);
          this._drawing = false;
      }
      _doubletap(ev) {
          if (!this.model.active)
              return;
          const point = this._map_drag(ev.sx, ev.sy, this.model.vertex_renderer);
          if (point == null)
              return;
          const [x, y] = point;
          // Perform hit testing
          const vertex_selected = this._select_event(ev, false, [this.model.vertex_renderer]);
          const point_cds = this.model.vertex_renderer.data_source;
          // Type once dataspecs are typed
          const point_glyph = this.model.vertex_renderer.glyph;
          const [pxkey, pykey] = [point_glyph.x.field, point_glyph.y.field];
          if (vertex_selected.length && this._selected_renderer != null) {
              // Insert a new point after the selected vertex and enter draw mode
              const index = point_cds.selected.indices[0];
              if (this._drawing) {
                  this._drawing = false;
                  point_cds.selection_manager.clear();
              }
              else {
                  point_cds.selected.indices = [index + 1];
                  if (pxkey)
                      point_cds.get_array(pxkey).splice(index + 1, 0, x);
                  if (pykey)
                      point_cds.get_array(pykey).splice(index + 1, 0, y);
                  this._drawing = true;
              }
              point_cds.change.emit();
              this._emit_cds_changes(this._selected_renderer.data_source);
          }
          else {
              this._show_vertices(ev);
          }
      }
      _show_vertices(ev) {
          if (!this.model.active)
              return;
          const renderers = this._select_event(ev, false, this.model.renderers);
          if (!renderers.length) {
              this._set_vertices([], []);
              this._selected_renderer = null;
              this._drawing = false;
              return;
          }
          const renderer = renderers[0];
          const glyph = renderer.glyph;
          const cds = renderer.data_source;
          const index = cds.selected.indices[0];
          const [xkey, ykey] = [glyph.xs.field, glyph.ys.field];
          let xs;
          let ys;
          if (xkey) {
              xs = cds.data[xkey][index];
              if (!types_1.isArray(xs))
                  cds.data[xkey][index] = xs = Array.from(xs);
          }
          else {
              xs = glyph.xs.value;
          }
          if (ykey) {
              ys = cds.data[ykey][index];
              if (!types_1.isArray(ys))
                  cds.data[ykey][index] = ys = Array.from(ys);
          }
          else {
              ys = glyph.ys.value;
          }
          this._selected_renderer = renderer;
          this._set_vertices(xs, ys);
      }
      _move(ev) {
          if (this._drawing && this._selected_renderer != null) {
              const renderer = this.model.vertex_renderer;
              const cds = renderer.data_source;
              const glyph = renderer.glyph;
              const point = this._map_drag(ev.sx, ev.sy, renderer);
              if (point == null)
                  return;
              let [x, y] = point;
              const indices = cds.selected.indices;
              [x, y] = this._snap_to_vertex(ev, x, y);
              cds.selected.indices = indices;
              const [xkey, ykey] = [glyph.x.field, glyph.y.field];
              const index = indices[0];
              if (xkey)
                  cds.data[xkey][index] = x;
              if (ykey)
                  cds.data[ykey][index] = y;
              cds.change.emit();
              this._selected_renderer.data_source.change.emit();
          }
      }
      _tap(ev) {
          const renderer = this.model.vertex_renderer;
          const point = this._map_drag(ev.sx, ev.sy, renderer);
          if (point == null)
              return;
          else if (this._drawing && this._selected_renderer) {
              let [x, y] = point;
              const cds = renderer.data_source;
              // Type once dataspecs are typed
              const glyph = renderer.glyph;
              const [xkey, ykey] = [glyph.x.field, glyph.y.field];
              const indices = cds.selected.indices;
              [x, y] = this._snap_to_vertex(ev, x, y);
              const index = indices[0];
              cds.selected.indices = [index + 1];
              if (xkey) {
                  const xs = cds.get_array(xkey);
                  const nx = xs[index];
                  xs[index] = x;
                  xs.splice(index + 1, 0, nx);
              }
              if (ykey) {
                  const ys = cds.get_array(ykey);
                  const ny = ys[index];
                  ys[index] = y;
                  ys.splice(index + 1, 0, ny);
              }
              cds.change.emit();
              this._emit_cds_changes(this._selected_renderer.data_source, true, false, true);
              return;
          }
          const append = ev.shiftKey;
          this._select_event(ev, append, [renderer]);
          this._select_event(ev, append, this.model.renderers);
      }
      _remove_vertex() {
          if (!this._drawing || !this._selected_renderer)
              return;
          const renderer = this.model.vertex_renderer;
          const cds = renderer.data_source;
          // Type once dataspecs are typed
          const glyph = renderer.glyph;
          const index = cds.selected.indices[0];
          const [xkey, ykey] = [glyph.x.field, glyph.y.field];
          if (xkey)
              cds.get_array(xkey).splice(index, 1);
          if (ykey)
              cds.get_array(ykey).splice(index, 1);
          cds.change.emit();
          this._emit_cds_changes(this._selected_renderer.data_source);
      }
      _pan_start(ev) {
          this._select_event(ev, true, [this.model.vertex_renderer]);
          this._basepoint = [ev.sx, ev.sy];
      }
      _pan(ev) {
          if (this._basepoint == null)
              return;
          this._drag_points(ev, [this.model.vertex_renderer]);
          if (this._selected_renderer)
              this._selected_renderer.data_source.change.emit();
      }
      _pan_end(ev) {
          if (this._basepoint == null)
              return;
          this._drag_points(ev, [this.model.vertex_renderer]);
          this._emit_cds_changes(this.model.vertex_renderer.data_source, false, true, true);
          if (this._selected_renderer) {
              this._emit_cds_changes(this._selected_renderer.data_source);
          }
          this._basepoint = null;
      }
      _keyup(ev) {
          if (!this.model.active || !this._mouse_in_frame)
              return;
          let renderers;
          if (this._selected_renderer) {
              renderers = [this.model.vertex_renderer];
          }
          else {
              renderers = this.model.renderers;
          }
          for (const renderer of renderers) {
              if (ev.keyCode === dom_1.Keys.Backspace) {
                  this._delete_selected(renderer);
                  if (this._selected_renderer) {
                      this._emit_cds_changes(this._selected_renderer.data_source);
                  }
              }
              else if (ev.keyCode == dom_1.Keys.Esc) {
                  if (this._drawing) {
                      this._remove_vertex();
                      this._drawing = false;
                  }
                  else if (this._selected_renderer) {
                      this._hide_vertices();
                  }
                  renderer.data_source.selection_manager.clear();
              }
          }
      }
      deactivate() {
          if (!this._selected_renderer) {
              return;
          }
          else if (this._drawing) {
              this._remove_vertex();
              this._drawing = false;
          }
          this._hide_vertices();
      }
  }
  exports.PolyEditToolView = PolyEditToolView;
  PolyEditToolView.__name__ = "PolyEditToolView";
  class PolyEditTool extends poly_tool_1.PolyTool {
      constructor(attrs) {
          super(attrs);
          this.tool_name = "Poly Edit Tool";
          this.icon = icons_1.bk_tool_icon_poly_edit;
          this.event_type = ["tap", "pan", "move"];
          this.default_order = 4;
      }
      static init_PolyEditTool() {
          this.prototype.default_view = PolyEditToolView;
      }
  }
  exports.PolyEditTool = PolyEditTool;
  PolyEditTool.__name__ = "PolyEditTool";
  PolyEditTool.init_PolyEditTool();
  