import * as EXIF from "exif-js";

export function fileToDataURL(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.addEventListener(
      "load",
      function() {
        resolve(reader.result as string);
      },
      false
    );

    if (file) {
      reader.readAsDataURL(file);
    } else {
      reject("No file");
    }
  });
}

export function blobToDataURL(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.addEventListener(
      "load",
      function() {
        resolve(reader.result as string);
      },
      false
    );

    if (blob) {
      reader.readAsDataURL(blob);
    } else {
      reject("No file");
    }
  });
}

export function dataUrlToBlob(dataUrl: string) {
  const [mimeType, data] = dataUrl.split(/,/);
  const dataDecoded = atob(data);
  const charCodes = new Uint8Array(dataDecoded.length);

  for (let i = 0; i < dataDecoded.length; ++i) {
    charCodes[i] = dataDecoded.charCodeAt(i);
  }

  return new Blob([charCodes], {
    type: mimeType
  });
}

type OrientationTransformation = {
  flipX: boolean;
  flipY: boolean;
  roation: number;
};

export type EXIFOrientation = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;

const orientationTransformations: {
  1: OrientationTransformation;
  2: OrientationTransformation;
  3: OrientationTransformation;
  4: OrientationTransformation;
  5: OrientationTransformation;
  6: OrientationTransformation;
  7: OrientationTransformation;
  8: OrientationTransformation;
} = {
  1: {
    flipX: false,
    flipY: false,
    roation: 0
  },
  2: {
    flipX: true,
    flipY: false,
    roation: 0
  },
  3: {
    flipX: true,
    flipY: true,
    roation: 0
  },
  4: {
    flipX: false,
    flipY: true,
    roation: 0
  },
  5: {
    flipX: true,
    flipY: false,
    roation: 90
  },
  6: {
    flipX: false,
    flipY: false,
    roation: 90
  },
  7: {
    flipX: true,
    flipY: false,
    roation: -90
  },
  8: {
    flipX: false,
    flipY: false,
    roation: -90
  }
};

export function orient(
  ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
  orientation: EXIFOrientation,
  canvasSize: number
) {
  const { flipX, flipY, roation } = orientationTransformations[orientation];

  if (flipX) {
    ctx.translate(canvasSize, 0);
    ctx.scale(-1, 1);
  }

  if (flipY) {
    ctx.translate(0, canvasSize);
    ctx.scale(1, -1);
  }

  ctx.translate(canvasSize / 2, canvasSize / 2);
  ctx.rotate(roation * (Math.PI / 180));
  ctx.translate(-canvasSize / 2, -canvasSize / 2);
}
