pragma ComponentBehavior: Bound

import QtQuick
import ZShell.Internal

Item {
	id: root

	property color inkColor: "#ff3b30"
	property real inkWidth: 4
	property string tool: "none"

	signal changed

	function clearAll() {
		committedCanvas.clear();
		previewCanvas.clear();
		changed();
	}

	function sampleShape(tool, x1, y1, x2, y2) {
		const pts = [];
		switch (tool) {
		case "line":
			pts.push([x1, y1], [x2, y2]);
			break;
		case "arrow":
			{
				const angle = Math.atan2(y2 - y1, x2 - x1);
				const headLen = 14 + root.inkWidth * 2;
				pts.push([x1, y1], [x2, y2]);
				pts.push([x2 - headLen * Math.cos(angle - Math.PI / 6), y2 - headLen * Math.sin(angle - Math.PI / 6)]);
				pts.push([x2, y2]);
				pts.push([x2 - headLen * Math.cos(angle + Math.PI / 6), y2 - headLen * Math.sin(angle + Math.PI / 6)]);
				break;
			}
		case "rect":
			pts.push([x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]);
			break;
		case "ellipse":
			{
				const cx = (x1 + x2) / 2, cy = (y1 + y2) / 2;
				const rx = Math.abs(x2 - x1) / 2, ry = Math.abs(y2 - y1) / 2;
				const perimeter = Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));
				const steps = Math.max(48, Math.min(256, Math.ceil(perimeter / 4)));
				for (let i = 0; i <= steps; i++) {
					const a = (i / steps) * Math.PI * 2;
					pts.push([cx + rx * Math.cos(a), cy + ry * Math.sin(a)]);
				}
				break;
			}
		}
		return pts;
	}

	function undo() {
		committedCanvas.undoLastGroup();
		changed();
	}

	anchors.fill: parent

	StrokeCanvas {
		id: committedCanvas

		anchors.fill: parent
		penColor: root.inkColor
		penWidth: root.inkWidth
	}

	StrokeCanvas {
		id: previewCanvas

		anchors.fill: parent
		penColor: root.inkColor
		penWidth: root.inkWidth
	}

	PointHandler {
		id: drawHandler

		property real startX
		property real startY
		property bool started: false

		acceptedButtons: Qt.LeftButton | Qt.RightButton
		enabled: root.tool !== "none"

		onActiveChanged: {
			if (active)
				return;

			if (root.tool === "pen") {
				committedCanvas.endStroke();
			} else if (started) {
				const pts = root.sampleShape(root.tool, startX, startY, point.position.x, point.position.y);
				if (pts.length > 0) {
					committedCanvas.beginStroke(pts[0][0], pts[0][1], true);
					for (let i = 1; i < pts.length; i++)
						committedCanvas.appendPoint(pts[i][0], pts[i][1]);
					committedCanvas.endStroke();
				}
				previewCanvas.clear();
			}
			started = false;
			root.changed();
		}
		onPointChanged: {
			if (!active)
				return;

			if (point.pressedButtons & Qt.RightButton) {
				root.clearAll();
				return;
			}

			const x = point.position.x;
			const y = point.position.y;

			if (root.tool === "pen") {
				if (!started) {
					started = true;
					committedCanvas.beginStroke(x, y);
					return;
				}
				committedCanvas.appendPoint(x, y);
				return;
			}

			if (!started) {
				started = true;
				startX = point.pressPosition.x;
				startY = point.pressPosition.y;
			}
			const pts = root.sampleShape(root.tool, startX, startY, x, y);
			if (pts.length > 0) {
				previewCanvas.beginStroke(pts[0][0], pts[0][1], true);
				for (let i = 1; i < pts.length; i++)
					previewCanvas.appendPoint(pts[i][0], pts[i][1]);
			}
		}
	}
}
