import { createContext, useContext } from 'react';

/**
 * @typedef {Object} Transform
 * @property {number} x - amount to translate in the x axis
 * @property {number} y - amount to translate in the y axis
 * @property {number} k - amount to scale (multiplicative scale factor)
 * @property {number} zoomLevel - linear zoom scale in [0, 1]
 *
 * @typedef {Object} Canvas
 * @property {number} svgWidth
 *           The width of the canvas in SVG coordinate space
 * @property {number} svgHeight
 *           The height of the canvas in SVG coordinate space
 * @property {number} nodeWidth
 *           The width of the canvas in pixels on the screen
 * @property {number} nodeHeight
 *           The height of the canvas in pixels on the screen
 * @property {number} svgToPixelScale
 *           The ratio pixels to SVG coordinate units
 *
 * @typedef {Object} ZoomConfig
 * @property {boolean} zoomable
 *           Whether zooming is enabled
 * @property {number[]} size
 *           The `[w,h]` size of the canvas in SVG coordinates
 * @property {number} scaleMax
 *           The maximum multiplicative scale you can zoom to
 * @property {number} zoomBy
 *           The multiplicative scale factor used by zoom buttons
 *
 * @typedef {Object} Zoom
 * @property {Transform} transform
 *           An object representing the current tranform to apply to the SVG
 *           content given the zoom interactions
 * @property {Canvas} canvas
 *           An object describing the dimensions of the canvas
 * @property {Object} canvasRef
 *           A React ref that should be attached to the SVG canvas itself
 * @property {function()} zoomIn
 *           A function that will programmatically zoom in, for use in
 *           button-based controls
 * @property {function()} zoomOut
 *           A function that will programmatically zoom out, for use in
 *           button-based controls
 * @property {function(Transform)} setTransform
 *           Setter function to change transform explicitly
 * @property {ZoomConfig} config
 *           Configuration information about how the hook was set up
 *
 * @type {Zoom}
 */
const initialValue = {
  transform: {
    x: 0,
    y: 0,
    k: 1,
    zoomLevel: 0
  },
  canvas: {
    svgWidth: 0,
    svgHeight: 0,
    nodeWidth: 0,
    nodeHeight: 0,
    svgToPixelScale: 1
  },
  canvasRef: null,
  zoomIn: () => {},
  zoomOut: () => {},
  setTransform: () => {},
  config: {
    zoomable: false,
    size: [0, 0],
    scaleMax: 1,
    zoomBy: 1
  }
};
export const ZoomContext = createContext(initialValue);

/**
 * Hook to access the zoom context
 *
 * @returns {ZoomContext}
 */
const useZoomContext = function useZoomContext() {
  return useContext(ZoomContext);
};
export default useZoomContext;