pragma ComponentBehavior: Bound

import QtQuick

Item {
	id: root

	property color handleBorder: "#3584e4"
	property color handleFill: "white"
	property real hs: 12
	property real minSize: 24
	required property real selH
	required property real selW
	required property real selX
	required property real selY

	signal boundsChanged(x: real, y: real, w: real, h: real)
	signal dragFinished
	signal moveBy(dx: real, dy: real)

	height: selH
	width: selW
	x: selX
	y: selY

	DragHandler {
		id: moveHandler

		property real accumX: 0
		property real accumY: 0

		target: null

		onActiveChanged: {
			accumX = 0;
			accumY = 0;
			if (!active)
				root.dragFinished();
		}
		onTranslationChanged: {
			const t = moveHandler.translation;
			root.moveBy(t.x - accumX, t.y - accumY);
			accumX = t.x;
			accumY = t.y;
		}
	}

	Handle {
		edge: "tl"
		x: -root.hs / 2
		y: -root.hs / 2
	}

	Handle {
		edge: "t"
		x: root.width / 2 - root.hs / 2
		y: -root.hs / 2
	}

	Handle {
		edge: "tr"
		x: root.width - root.hs / 2
		y: -root.hs / 2
	}

	Handle {
		edge: "r"
		x: root.width - root.hs / 2
		y: root.height / 2 - root.hs / 2
	}

	Handle {
		edge: "br"
		x: root.width - root.hs / 2
		y: root.height - root.hs / 2
	}

	Handle {
		edge: "b"
		x: root.width / 2 - root.hs / 2
		y: root.height - root.hs / 2
	}

	Handle {
		edge: "bl"
		x: -root.hs / 2
		y: root.height - root.hs / 2
	}

	Handle {
		edge: "l"
		x: -root.hs / 2
		y: root.height / 2 - root.hs / 2
	}

	component Handle: Rectangle {
		id: handle

		required property string edge

		border.color: root.handleBorder
		border.width: 2
		color: root.handleFill
		height: root.hs
		radius: root.hs / 2
		width: root.hs
		z: 10

		HoverHandler {
			cursorShape: {
				switch (handle.edge) {
				case "tl":
				case "br":
					return Qt.SizeFDiagCursor;
				case "tr":
				case "bl":
					return Qt.SizeBDiagCursor;
				case "t":
				case "b":
					return Qt.SizeVerCursor;
				default:
					return Qt.SizeHorCursor;
				}
			}
		}

		DragHandler {
			id: dh

			property real startH
			property real startW
			property real startX
			property real startY

			grabPermissions: PointerHandler.CanTakeOverFromAnything | PointerHandler.TakeOverForbidden
			target: null

			onActiveChanged: {
				if (active) {
					startX = root.x;
					startY = root.y;
					startW = root.width;
					startH = root.height;
				} else {
					root.dragFinished();
				}
			}
			onTranslationChanged: {
				const delta = dh.translation;
				const e = handle.edge;
				let nx = startX, ny = startY, nw = startW, nh = startH;

				if (e.includes("l")) {
					nx = startX + delta.x;
					nw = startW - delta.x;
				}
				if (e.includes("r")) {
					nw = startW + delta.x;
				}
				if (e.includes("t")) {
					ny = startY + delta.y;
					nh = startH - delta.y;
				}
				if (e.includes("b")) {
					nh = startH + delta.y;
				}

				if (nw < root.minSize) {
					if (e.includes("l"))
						nx = startX + startW - root.minSize;
					nw = root.minSize;
				}
				if (nh < root.minSize) {
					if (e.includes("t"))
						ny = startY + startH - root.minSize;
					nh = root.minSize;
				}

				root.boundsChanged(nx, ny, nw, nh);
			}
		}
	}
}
