import { Frames } from '../App';

export function zoomViewportIn(
  viewport: Frames,
  numFrames: number,
  selection: Frames,
  position: number,
  factor: number
): Frames {
  if (!canZoomViewportIn(viewport, selection, factor)) {
    return viewport;
  }

  return zoom(
    Math.round((viewport.end - viewport.start) / factor),
    viewport,
    numFrames,
    selection,
    position
  );
}

export function zoomViewportOut(
  viewport: Frames,
  numFrames: number,
  selection: Frames,
  position: number,
  factor: number
): Frames {
  if (!canZoomViewportOut(viewport, numFrames)) {
    return viewport;
  }

  return zoom(
    Math.round((viewport.end - viewport.start) * factor),
    viewport,
    numFrames,
    selection,
    position
  );
}

function zoom(
  newWidth: number,
  viewport: Frames,
  numFrames: number,
  selection: Frames,
  position: number
): Frames {
  let newStart;

  if (selection.start != selection.end) {
    const selectionWidth = selection.end - selection.start;

    // disallow zooming beyond the selection:
    if (newWidth < selectionWidth) {
      return viewport;
    }

    const selectionMidpoint = selection.end - selectionWidth / 2;
    newStart = selectionMidpoint - Math.round(newWidth / 2);
  } else {
    newStart = position - newWidth / 2;
  }

  if (newStart < 0) {
    newStart = 0;
  }
  let newEnd = newStart + newWidth;
  if (newEnd > numFrames) {
    newEnd = numFrames;
    newStart = Math.max(0, newEnd - newWidth);
  }

  return { start: newStart, end: newEnd };
}

export function canZoomViewportIn(
  viewport: Frames,
  selection: Frames,
  factor: number
): boolean {
  if (viewport.start == viewport.end) {
    return false;
  }

  if (selection.start != selection.end) {
    const newWidth = Math.round((viewport.end - viewport.start) / factor);
    return newWidth > selection.end - selection.start;
  }

  return true;
}

export function canZoomViewportOut(
  viewport: Frames,
  numFrames: number
): boolean {
  if (viewport.start == viewport.end) {
    return false;
  }

  return viewport.start > 0 || viewport.end < numFrames;
}
