"use strict";

const Promise = require("bluebird");
const asExpression = require("as-expression");
const unreachable = require("@joepie91/unreachable")("@modular-matrix/client"); // FIXME when packaging
const getImageDimensions = require("../get-image-dimensions");
const getVideoDimensions = require("../get-video-dimensions");
const calculateThumbnailSize = require("../calculate-thumbnail-size");
const canvasToBlob = require("../canvas-to-blob");

const { validateOptions } = require("@validatem/core");
const required = require("@validatem/required");
const isInteger = require("@validatem/is-integer");
const oneOf = require("@validatem/one-of");

module.exports = function elementToThumbnail(_options) {
	// TODO: Add a 'crop' method in the future?
	let { element, maximumWidth, maximumHeight, mimetype } = validateOptions(arguments, {
		element: [ required ], // FIXME: Element type validation
		maximumWidth: [ required, isInteger ], // FIXME: Positive integer
		maximumHeight: [ required, isInteger ], // FIXME: Positive integer
		mimetype: [ required, oneOf([ "image/png", "image/jpeg" ]) ]
	});

	let dimensions = asExpression(() => {
		if (element instanceof HTMLImageElement) {
			return getImageDimensions(element);
		} else if (element instanceof HTMLVideoElement) {
			return getVideoDimensions(element);
		} else {
			unreachable("Unrecognized element type");
		}
	});

	let { width, height } = calculateThumbnailSize({
		sourceWidth: dimensions.width,
		sourceHeight: dimensions.height,
		targetWidth: maximumWidth,
		targetHeight: maximumHeight
	});
	
	let canvas = document.createElement("canvas");
	canvas.width = width;
	canvas.height = height;

	canvas.getContext("2d").drawImage(element, 0, 0, width, height);

	return Promise.try(() => {
		return canvasToBlob(canvas, mimetype);
	}).then((blob) => {
		return {
			width: width,
			height: height,
			blob: blob
		};
	});
};
