import BaseTool from './BaseTool.js';
import * as CAL from 'cal';
import TolerancePointer from '../TolerancePointer.js';
import * as actions from '../../actions/index.js';
import { calculateTolerance } from '../../utils/traceUtils';
import { MAX_TRACE_TOLERANCE } from '../../constants/d2Constants';
// import createDebug from 'debug';
// const debug = createDebug('d3d:tool:photoguide');

export default class PhotoGuideTool extends BaseTool {
  constructor(dispatch, sceneSpaceContainer, renderRequest) {
    super(dispatch, sceneSpaceContainer, renderRequest);
    this.enableHitDetection = true;

    this.preview = new CAL.Surface();
    this.preview.visible = false;

    this.maxToleranceView = new CAL.Surface();
    this.maxToleranceView.visible = false;

    this.tolerancePointer = new TolerancePointer();

    this.start = new CAL.Vector();

    this.add(this.maxToleranceView, this.preview, this.tolerancePointer);
  }

  dragStart(event) {
    this.start.copy(event.position);
    this.intersectionId = event.intersections.find(id => this.state.objectsById[id].type === 'IMAGE_GUIDE');
    super.dragStart(event);
  }

  drag(event) {
    if (this.intersectionId) {
      this._dispatch(actions.traceDrag, event.position, this.start, this.intersectionId);
    }
    super.drag(event);
  }

  dragEnd(event) {
    this._dispatch(actions.traceDragEnd);
    super.dragEnd(event);
  }

  tap(event) {
    this._dispatch(actions.traceTap, event.position, event.intersections);
    super.tap(event);
  }

  update(newState) {
    let needRender = false;
    if (newState === this.state) return needRender;
    super.update(newState);

    this.tolerancePointer.visible = newState.d2.trace.active;

    if (!this.state || (this.state && newState.d2.trace !== this.state.d2.trace)) {
      const { trace } = newState.d2;

      needRender = true;

      const maxTolerance = calculateTolerance(trace.start, trace.position) > MAX_TRACE_TOLERANCE;

      this.preview.visible = trace.active && !maxTolerance;
      this.maxToleranceView.visible = trace.active && maxTolerance;
      const UID = newState.d2.activeShape || (this.state ? this.state.d2.activeShape : null);
      if (UID && trace.active) {
        const shapeData = newState.objectsById[UID];
        const { width, height } = shapeData.imageData;

        if (this.preview.image.width !== width || this.preview.image.height !== height) {
          this.preview.centerX = width / 2;
          this.preview.centerY = height / 2;
          this.preview.setSize(width, height);
        }

        this.preview.copyMatrix(shapeData.transform);

        if (this.maxToleranceView.image.width !== width || this.maxToleranceView.image.height !== height) {
          this.maxToleranceView.centerX = width / 2;
          this.maxToleranceView.centerY = height / 2;
          this.maxToleranceView.setSize(width, height);

          this.maxToleranceView.context.fillStyle = 'rgba(255, 0, 0, 0.5)';
          this.maxToleranceView.context.fillRect(0, 0, width, height);
        }

        this.maxToleranceView.copyMatrix(shapeData.transform);

        this.tolerancePointer.update(trace);

        if (trace.floodFillData !== this.state.d2.trace.floodFillData) {
          const imageData = this.preview.context.createImageData(this.preview.width, this.preview.height);

          // Color red trace line based on edges in flood data from state
          for (let i = 0; i < trace.floodFillData.edge.length; i ++) {
            const index = trace.floodFillData.edge[i] * 4;
            imageData.data[index] = 255;
            imageData.data[index + 3] = 255;
          }
          this.preview.context.putImageData(imageData, 0, 0);
        }
      }
    }
    this.state = newState;
    return needRender;
  }
}
