import * as React from 'react';
import { NOTCHES_LENGTH } from '../../../utils/default';

interface IDimensionProps {
  id: string
  xStart: number
  yStart: number
  xEnd: number
  yEnd: number
  text: string
  strokeWidth: number
}

/**
 * 2D Parametric function. Returns a new coordinate from the origin coordinate
 * See for more details https://en.wikipedia.org/wiki/Parametric_equation.
 * TL;DR a parametric function is a function with a parameter
 * @param x0 Origin coordinate
 * @param t The parameter
 * @param vx Transform vector
 * @returns Returns a new coordinate from the origin coordinate
 */
const applyParametric = (x0: number, t: number, vx: number): number => x0 + t * vx;

export const Dimension: React.FC<IDimensionProps> = (props: IDimensionProps) => {
  const style: React.CSSProperties = {
    stroke: 'black'
  };

  /// We need to find the points of the notches
  // Get the vector of the line
  const [deltaX, deltaY] = [(props.xEnd - props.xStart), (props.yEnd - props.yStart)];

  // Get the unit vector
  const norm = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
  const [unitX, unitY] = [deltaX / norm, deltaY / norm];

  // Get the perpandicular vector
  const [perpVecX, perpVecY] = [unitY, -unitX];

  // Use the parametric function to get the coordinates (x = x0 + t * v.x)
  const startTopX = applyParametric(props.xStart, NOTCHES_LENGTH, perpVecX);
  const startTopY = applyParametric(props.yStart, NOTCHES_LENGTH, perpVecY);
  const startBottomX = applyParametric(props.xStart, -NOTCHES_LENGTH, perpVecX);
  const startBottomY = applyParametric(props.yStart, -NOTCHES_LENGTH, perpVecY);

  const endTopX = applyParametric(props.xEnd, NOTCHES_LENGTH, perpVecX);
  const endTopY = applyParametric(props.yEnd, NOTCHES_LENGTH, perpVecY);
  const endBottomX = applyParametric(props.xEnd, -NOTCHES_LENGTH, perpVecX);
  const endBottomY = applyParametric(props.yEnd, -NOTCHES_LENGTH, perpVecY);

  return (
    <g key={props.id}>
      <line
        x1={startTopX}
        y1={startTopY}
        x2={startBottomX}
        y2={startBottomY}
        strokeWidth={props.strokeWidth}
        style={style}
      />
      <line
        x1={props.xStart}
        y1={props.yStart}
        x2={props.xEnd}
        y2={props.yEnd}
        strokeWidth={props.strokeWidth}
        style={style}
      />
      <line
        x1={endTopX}
        y1={endTopY}
        x2={endBottomX}
        y2={endBottomY}
        strokeWidth={props.strokeWidth}
        style={style}
      />
      <text
        x={(props.xStart + props.xEnd) / 2}
        y={props.yStart}
      >
        {props.text}
      </text>
    </g>
  );
};
