import {
  EVENT_ZOOM,
  SCALE_POWER_MAX,
  SCALE_POWER_MIN,
} from './config.js';
import {div, sub} from './vector.js';

export class Zoom {
  sim = undefined;
  nextZoom = undefined;

  constructor(sim) {
    this.sim = sim;
  }

  // velocity should be in Sim coordinate scale
  scheduleZoom({x, y}, factor, velocity) {
    this.nextZoom = {x, y, factor, velocity};
  }

  frame() {
    if (this.nextZoom) {
      this.zoom(this.nextZoom);
      this.nextZoom = undefined;
    }
  }

  // x, y should be in Sim coordinates
  // velocity should be in Sim coordinate scale
  zoom({x, y, factor, velocity}) {
    const {display} = this.sim;
    // x, y are the mouse coordinates, which should be the center of the new view frame
    // the new view origin should be x, y minus half the new view width and height
    // compute new scale
    // TODO: Lossy rescaling to expand zoom range
    let scalePower = display.scalePower + factor;
    scalePower = Math.max(scalePower, SCALE_POWER_MIN);
    scalePower = Math.min(scalePower, SCALE_POWER_MAX);
    display.scalePower = scalePower;

    // compute coordinates of new view frame
    display.viewOrigin = sub({x, y}, div({x: display.width, y: display.height}, 2));

    // TODO: If paused, set panning velocity on resume
    // if (this.sim.playing && velocity) {
    if (velocity) {
      this.sim.panning.setVelocity(velocity);
    }

    const e = new CustomEvent(EVENT_ZOOM);
    this.sim.div.dispatchEvent(e);
  }

}
