import { hasFullscreenSupport, isFullscreen } from "../system/fullscreen.ts";
import CanvasRenderer from "../video/canvas/canvas_renderer.js";
import CanvasRenderTarget from "../video/rendertarget/canvasrendertarget.js";
import { getParent } from "../video/video.js";
import { Batcher } from "../video/webgl/batchers/batcher.js";
import PrimitiveBatcher from "../video/webgl/batchers/primitive_batcher.js";
import QuadBatcher from "../video/webgl/batchers/quad_batcher.js";
import WebGLRenderer from "../video/webgl/webgl_renderer.js";
import { warning } from "./console.js";

/*
 * placeholder for all deprecated classes and corresponding alias for backward compatibility
 */

/**
 * @deprecated since 17.1.0
 * @see CanvasRenderTarget
 */
export class CanvasTexture extends CanvasRenderTarget {
	/**
	 * @param {number} width - the desired width of the canvas
	 * @param {number} height - the desired height of the canvas
	 * @param {object} attributes - The attributes to create both the canvas and context
	 * @param {boolean} [attributes.context="2d"] - the context type to be created ("2d", "webgl", "webgl2")
	 * @param {boolean} [attributes.offscreenCanvas=false] - will create an offscreenCanvas if true instead of a standard canvas
	 * @param {boolean} [attributes.willReadFrequently=false] - Indicates whether or not a lot of read-back operations are planned
	 * @param {boolean} [attributes.antiAlias=false] - Whether to enable anti-aliasing, use false (default) for a pixelated effect.
	 */
	constructor(width, height, attributes) {
		warning("CanvasTexture", "CanvasRenderTarget", "17.1.0");
		super(width, height, attributes);
	}
}

/**
 * return the height of the system Canvas
 * @public
 * @name setLineWidth
 * @memberof CanvasRenderer#
 * @deprecated since 17.3.0
 * @see lineWidth
 */
CanvasRenderer.prototype.setLineWidth = function (width) {
	warning("setLineWidth", "lineWidth", "17.3.0");
	this.lineWidth = width;
};

/**
 * return the height of the system Canvas
 * @public
 * @name setLineWidth
 * @memberof WebGLRenderer#
 * @deprecated since 17.3.0
 * @see lineWidth
 */
WebGLRenderer.prototype.setLineWidth = function (width) {
	warning("setLineWidth", "lineWidth", "17.3.0");
	this.lineWidth = width;
};

/**
 * @deprecated since 18.1.0
 * @see Batcher
 */
export class Compositor extends Batcher {
	/** @param {any[]} args */
	constructor(...args) {
		warning("Compositor", "Batcher", "18.1.0");
		super(...args);
	}
}

/**
 * @deprecated since 18.1.0
 * @see PrimitiveBatcher
 */
export class PrimitiveCompositor extends PrimitiveBatcher {
	/** @param {any[]} args */
	constructor(...args) {
		warning("PrimitiveCompositor", "PrimitiveBatcher", "18.1.0");
		super(...args);
	}
}

/**
 * @deprecated since 18.1.0
 * @see QuadBatcher
 */
export class QuadCompositor extends QuadBatcher {
	/** @param {any[]} args */
	constructor(...args) {
		warning("QuadCompositor", "QuadBatcher", "18.1.0");
		super(...args);
	}
}

/**
 * @deprecated since 18.1.0 — use currentBatcher instead
 */
Object.defineProperty(WebGLRenderer.prototype, "currentCompositor", {
	get() {
		warning("currentCompositor", "currentBatcher", "18.1.0");
		return this.currentBatcher;
	},
	set(value) {
		warning("currentCompositor", "currentBatcher", "18.1.0");
		this.currentBatcher = value;
	},
});

/**
 * @deprecated since 18.1.0 — use batchers instead
 */
Object.defineProperty(WebGLRenderer.prototype, "compositors", {
	get() {
		warning("compositors", "batchers", "18.1.0");
		return this.batchers;
	},
	set(value) {
		warning("compositors", "batchers", "18.1.0");
		this.batchers = value;
	},
});

/**
 * @deprecated since 18.1.0 — use addBatcher instead
 */
WebGLRenderer.prototype.addCompositor = function (
	compositor,
	name = "default",
	activate = false,
) {
	warning("addCompositor", "addBatcher", "18.1.0");
	return this.addBatcher(compositor, name, activate);
};

/**
 * @deprecated since 18.1.0 — use setBatcher instead
 */
WebGLRenderer.prototype.setCompositor = function (name = "default", shader) {
	warning("setCompositor", "setBatcher", "18.1.0");
	return this.setBatcher(name, shader);
};

/**
 * @namespace Math
 * @deprecated since 18.0.0
 * Use lowercase `math` export instead.
 */
export * as Math from "./../math/math.ts";

/**
 * Triggers a fullscreen request. Requires fullscreen support from the browser/device.
 *
 * Re-exported under `me.device.*` for backwards compatibility; the canonical
 * post-19.7 entry point is `Application#requestFullscreen`, which uses the
 * Application's own `parentElement` instead of the deprecated global-game canvas lookup.
 * @param {Element} [element] - the element to be set in full-screen mode
 * @deprecated since 19.7.0 — use {@link Application#requestFullscreen} instead.
 */
export function requestFullscreen(element) {
	warning(
		"device.requestFullscreen",
		"Application#requestFullscreen",
		"19.7.0",
	);
	if (!hasFullscreenSupport || isFullscreen()) {
		return;
	}
	const target = element ?? getParent();
	const request =
		target.requestFullscreen ||
		target.webkitRequestFullscreen ||
		target.mozRequestFullScreen ||
		target.msRequestFullscreen;
	const result = request?.call(target);
	if (result instanceof Promise) {
		result.catch(console.error);
	}
}

/**
 * Exit fullscreen mode. Requires fullscreen support from the browser/device.
 *
 * Re-exported under `me.device.*` for backwards compatibility; the canonical
 * post-19.7 entry point is `Application#exitFullscreen`.
 * @deprecated since 19.7.0 — use {@link Application#exitFullscreen} instead.
 */
export function exitFullscreen() {
	warning("device.exitFullscreen", "Application#exitFullscreen", "19.7.0");
	if (!hasFullscreenSupport || !isFullscreen()) {
		return;
	}
	const doc = globalThis.document;
	const exit =
		doc.exitFullscreen ||
		doc.webkitExitFullscreen ||
		doc.mozCancelFullScreen ||
		doc.msExitFullscreen;
	const result = exit?.call(doc);
	if (result instanceof Promise) {
		result.catch(console.error);
	}
}
