import { DEFAULT_CENTRAL_AREA_RATIO, ShapeStyle, StrokeStyle, } from '../../../consts.js';
import { Bound } from '../../../utils/bound.js';
import { getCenterAreaBounds, getPointsFromBoundsWithRotation, linePolygonIntersects, pointInPolygon, pointOnPolygonStoke, polygonGetPointTangent, polygonNearestPoint, rotatePoints, } from '../../../utils/math-utils.js';
import { PointLocation } from '../../../utils/point-location.js';
import {} from '../../../utils/vec.js';
import { ShapeType } from '../consts.js';
import { drawGeneralShape, hitTestOnShapeText } from '../utils.js';
export const TriangleMethods = {
    points({ x, y, w, h }) {
        return [
            [x, y + h],
            [x + w / 2, y],
            [x + w, y + h],
        ];
    },
    render(ctx, matrix, rc, element) {
        const { seed, strokeWidth, filled, realFillColor, realStrokeColor, strokeStyle, roughness, rotate, shapeStyle, } = element;
        const [, , w, h] = element.deserializeXYWH();
        const renderOffset = Math.max(strokeWidth, 0) / 2;
        const renderWidth = w - renderOffset * 2;
        const renderHeight = h - renderOffset * 2;
        const cx = renderWidth / 2;
        const cy = renderHeight / 2;
        ctx.setTransform(matrix
            .translateSelf(renderOffset, renderOffset)
            .translateSelf(cx, cy)
            .rotateSelf(rotate)
            .translateSelf(-cx, -cy));
        if (shapeStyle === ShapeStyle.General) {
            drawGeneralShape(ctx, ShapeType.Triangle, {
                x: 0,
                y: 0,
                width: renderWidth,
                height: renderHeight,
                strokeWidth,
                strokeColor: realStrokeColor,
                strokeStyle: strokeStyle,
                fillColor: realFillColor,
            });
        }
        else {
            rc.polygon([
                [renderWidth / 2, 0],
                [renderWidth, renderHeight],
                [0, renderHeight],
            ], {
                seed,
                roughness: shapeStyle === ShapeStyle.Scribbled ? roughness : 0,
                strokeLineDash: strokeStyle === StrokeStyle.Dashed ? [12, 12] : undefined,
                stroke: strokeStyle === StrokeStyle.None ? 'none' : realStrokeColor,
                strokeWidth,
                fill: filled ? realFillColor : undefined,
            });
        }
    },
    hitTest(x, y, options) {
        const points = getPointsFromBoundsWithRotation(this, TriangleMethods.points);
        let hit = pointOnPolygonStoke([x, y], points, (options?.expand ?? 1) / (this.renderer?.zoom ?? 1));
        if (!hit) {
            if (!options.ignoreTransparent || this.filled) {
                hit = pointInPolygon([x, y], points);
            }
            else {
                // If shape is not filled or transparent
                const text = this.text;
                if (!text || !text.length) {
                    // Check the center area of the shape
                    const centralBounds = getCenterAreaBounds(this, DEFAULT_CENTRAL_AREA_RATIO);
                    const centralPoints = getPointsFromBoundsWithRotation(centralBounds, TriangleMethods.points);
                    hit = pointInPolygon([x, y], centralPoints);
                }
                else {
                    hit = hitTestOnShapeText([x, y], this);
                }
            }
        }
        return hit;
    },
    containedByBounds(bounds, element) {
        const points = getPointsFromBoundsWithRotation(element, TriangleMethods.points);
        return points.some(point => bounds.containsPoint(point));
    },
    getNearestPoint(point, element) {
        const points = getPointsFromBoundsWithRotation(element, TriangleMethods.points);
        return polygonNearestPoint(points, point);
    },
    intersectWithLine(start, end, element) {
        const points = getPointsFromBoundsWithRotation(element, TriangleMethods.points);
        return linePolygonIntersects(start, end, points);
    },
    getRelativePointLocation(position, element) {
        const bound = Bound.deserialize(element.xywh);
        const point = bound.getRelativePoint(position);
        let points = TriangleMethods.points(bound);
        points.push(point);
        points = rotatePoints(points, bound.center, element.rotate);
        const rotatePoint = points.pop();
        const tangent = polygonGetPointTangent(points, rotatePoint);
        return new PointLocation(rotatePoint, tangent);
    },
};
//# sourceMappingURL=triangle.js.map