<!-- The <crosshair-sk> custom element declaration.

  The crosshair-sk element works with the canvas-layers-sk element
  and draws a crosshair on one of the given layers. Use the update_on
  attribute to control when the crosshair is moved.

  Attributes:
    x, y - The x,y coords of the crosshair, as measured in the natural
      dimensions of the image. I.e. not in the coords of the img
      if it has a different size as determined by CSS styling.

    target - The id of the canvas-layers-sk element we are drawing
      a crosshair on.

    name - The name of the layer in the canvas-layer-sk element
       we are drawing a crosshair on.

    hidden - If true then don't actually draw the crosshair.

    update_on - Update the crosshair:
      "move" - when the mouse moves.
      "click" - when the user clicks.
      "none" - (default) do not update the crosshair based on user action.

  Events:
    crosshair - Produced if the crosshair is moved by clicking in the image.
      The coordinates of the click are in e.detail.x and e.detail.y. They
      are in offsets from the image origin in the images natural dimensions.
      That is, even if the image is sized using CSS the x and y values
      will be reported as values in the images original size.

  Methods:
    coordinatesUpdated - to be called if the x or y attribute was changed by other code.
      prefer calling this and setting useObservers=false if you control all the places which modify
      x and y.

-->
<link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
<dom-module id="crosshair-sk">
  <template>
  </template>
  <script>
    Polymer({
      is: 'crosshair-sk',

      properties: {
        x: {
          type: Number,
          value: 0,
          reflectToAttribute: true,
          notify: true,
          observer: "_updatedOneCoord",
        },
        y: {
          type: Number,
          value: 0,
          reflectToAttribute: true,
          notify: true,
          observer: "_updatedOneCoord",
        },
        useObservers: {
          type: Boolean,
          value: true,
          reflectToAttribute: true,
        },
        target: {
          type: String,
          value: "",
          observer: '_layerChanged',
          reflectToAttribute: true
        },
        hidden: {
          type: Boolean,
          value: false,
          observer: '_hiddenChanged',
          reflectToAttribute: true
        },
        name: {
          type: String,
          value: "",
          observer: '_layerChanged',
          reflectToAttribute: true
        },
        update_on: {
          // Valid values are "click", "move", and "none".
          type: String,
          value: "none",
          observer: '_registerCallbacks',
          reflectToAttribute: true
        },
      },

      ready: function () {
        // The current location of the crosshair, in CSS units.
        this.thumb = {
          x: 0,
          y: 0,
        };

        // If we are tracking mousemove events we'll store the coords here.
        this._move = {
          x: 0,
          y: 0,
        };

        // If we are tracking mousemove events we'll store the previous coords
        // here, so we only redraw the crosshair if it's actually moved.
        this._lastMove = {
          x: 0,
          y: 0,
        };

        this.willUpdate = null;

        this._xyChangedBound = this.coordinatesUpdated.bind(this);
        this._moveEventHandlerBound = this._moveEventHandler.bind(this);
        this._clickEventHandlerBound = this._clickEventHandler.bind(this);
        this._moveToMouseBound = this._moveToMouse.bind(this);

        this._animRequest = null;
      },

      _updatedOneCoord() {
        if (!this.useObservers) { return; }
        // Wait and see if the other coordinate updates.
        if (!this.willUpdate) {
          this.willUpdate = setTimeout(() => {
            this.coordinatesUpdated();
          }, 1);
        }
      },

      coordinatesUpdated() {
        this.willUpdate = null;
        if (!this._img) { return; }
        this._imgSize = this._standardSize(this._img);
        this.thumb.x = this._imgSize.visibleWidth * (this.x / this._imgSize.naturalWidth);
        this.thumb.y = this._imgSize.visibleHeight * (this.y / this._imgSize.naturalHeight);
        this._drawCrosshair();
        this._event();
      },

      // Returns both the visible and natural size of a canvas or image element,
      // Natural size - the width and height of it in it's native resolution.
      // Visible size - the width and height of it on the screen as controlled by css
      _standardSize(element) {
        if (element.nodeName === 'IMG') {
          return {
            'visibleWidth': element.width,
            'visibleHeight': element.height,
            'naturalWidth': element.naturalWidth,
            'naturalHeight': element.naturalHeight,
          };
        } else {
          var strW = window.getComputedStyle(element, null).width;
          var strH = window.getComputedStyle(element, null).height;
          return {
            // Trim 'px' off the end of the style string and convert to a number.
            'visibleWidth': parseFloat(strW.substring(0, strW.length-2)),
            'visibleHeight': parseFloat(strH.substring(0, strH.length-2)),
            'naturalWidth': element.width,
            'naturalHeight': element.height,
          };
        }
      },

      _layerChanged: function() {
        if (!(this.target && this.name)) {
          return;
        }
        $$$("#" + this.target, this._findParent()).addEventListener(
          'canvas-layers-updated', this._canvasLayersUpdated.bind(this));
      },

      _hiddenChanged: function() {
        if (this._ctx) {
          this._drawCrosshair();
        }
      },

      _findParent: function() {
        var p = this.parentNode;
        while (p.parentNode != null) {
          p = p.parentNode;
        }
        return p
      },

      _canvasLayersUpdated: function() {
        var layer = $$$("#" + this.target, Polymer.dom(this).parentNode);
        if (this._canvas) {
          // If we are switching to a new canvas then unregister all of our old callbacks.
          this._unregisterAllCallbacks();
        }
        this._canvas = layer.canvas(this.name);
        this._img = layer.subject();
        if (this._canvas) {
          this._registerCallbacks();
          this._ctx = this._canvas.getContext('2d');
        }
        this._imgSize = this._standardSize(this._img);
      },

      _registerCallbacks: function() {
        if (!this._canvas) {
          return;
        }
        this._canvas.addEventListener('canvas-update', this._xyChangedBound);
        if (this.update_on === "click") {
          this._canvas.addEventListener('click', this._clickEventHandlerBound);
          this._canvas.removeEventListener('mousemove', this._moveEventHandlerBound);
        } else if (this.update_on === "move")  {
          this._canvas.addEventListener('mousemove', this._moveEventHandlerBound);
          this._canvas.removeEventListener('click', this._clickEventHandlerBound);
        } else {
          this._canvas.removeEventListener('mousemove', this._moveEventHandlerBound);
          this._canvas.removeEventListener('click', this._clickEventHandlerBound);
        }
      },

      _unregisterAllCallbacks: function() {
        this._canvas.removeEventListener('mousemove', this._moveEventHandlerBound);
        this._canvas.removeEventListener('click', this._clickEventHandlerBound);
        this._canvas.removeEventListener('canvas-update', this._xyChangedBound);
      },

      _moveEventHandler: function (e) {
        this._move.x = e.clientX;
        this._move.y = e.clientY;

        if (this._lastMove.x != this._move.x || this._lastMove.y != this._move.y) {
          // Don't necessarily move it right now. Several more mouse move events may be triggered
          // before it's time to draw the next frame. register or replace our callback with the
          // window to move the crosshair before the next frame.
          this._animRequest = window.requestAnimationFrame(this._moveToMouseBound);
          this._lastMove.x = this._move.x;
          this._lastMove.y = this._move.y;
        }
      },

      // Moving to the last recorded mouse position. Registered as the callback
      // of window.requestAnimationFrame
      _moveToMouse(_) {
        this._moveCrosshair(this._move.x, this._move.y);
      },

      // moving to a clicked position.
      _clickEventHandler: function (e) {
        this._moveCrosshair(e.clientX, e.clientY);
      },

      _moveCrosshair: function (clientX, clientY) {
        if (!this._img.width || !this._img.height) {
          return;
        }
        var p = sk.elePos(this._canvas);
        this.thumb.x = clientX - p.x;
        this.thumb.y = clientY - p.y;
        this._drawCrosshair();
        // Cannot set properties atomically in Polymer 1
        this.x = Math.floor(this.thumb.x / this._imgSize.visibleWidth * this._imgSize.naturalWidth);
        this.y = Math.floor(this.thumb.y / this._imgSize.visibleHeight * this._imgSize.naturalHeight);
        this._event();
      },

      _event: function() {
        var detail = {
          x: this.x,
          y: this.y
        };
        var evt = new CustomEvent('crosshair', {
          detail: detail,
          bubbles: true
        });
        this.dispatchEvent(evt);
      },

      _drawCrosshair: function () {
        this._ctx.clearRect(0, 0, this._ctx.canvas.width, this._ctx.canvas.height);
        if (this.hidden) {
          return;
        }
        this._ctx.lineWidth = 1;
        this._ctx.strokeStyle = '#F00';
        this._ctx.beginPath();
        this._ctx.moveTo(0, this.thumb.y + 0.5);
        this._ctx.lineTo(this._ctx.canvas.width, this.thumb.y + 0.5);
        this._ctx.stroke();
        this._ctx.beginPath();
        this._ctx.moveTo(this.thumb.x + 0.5, 0);
        this._ctx.lineTo(this.thumb.x + 0.5, this._ctx.canvas.height);
        this._ctx.stroke();
      }
    });
  </script>
</dom-module>
