import {PeekCanvasConfig} from "../canvas/PeekCanvasConfig.web";
import {DrawModeE, PeekDispRenderDelegateABC} from "./PeekDispRenderDelegateABC.web";
import {DispBaseT, DispHandleTypeE, PointI} from "../canvas-shapes/DispBase";
import {PeekCanvasBounds} from "../canvas/PeekCanvasBounds";
import {DispGroupPointer, DispGroupPointerT} from "../canvas-shapes/DispGroupPointer";
import {PeekCanvasModel} from "../canvas/PeekCanvasModel.web";

export class PeekDispRenderDelegateGroupPtr extends PeekDispRenderDelegateABC {

    constructor(config: PeekCanvasConfig,
                model: PeekCanvasModel) {
        super(config, model);

    }

    updateBounds(disp: DispBaseT): void {
        disp.bounds = PeekCanvasBounds.fromGeom(DispGroupPointer.geom(disp));
    }

    draw(disp: DispBaseT, ctx, zoom: number, pan: PointI, drawMode: DrawModeE) {

        const dispGroup = <DispGroupPointerT>disp;
        if (DispGroupPointer.targetGroupName(dispGroup) != null)
            return;

        this.drawNoTarget(dispGroup, ctx, zoom, pan, drawMode);
    }

    /** Draw No Target
     *
     * If the DispGroup is unset and invisible, then we need to draw something to
     * show that it's there.
     *
     * @param dispGroup
     * @param ctx
     * @param zoom
     * @param pan
     * @param drawMode
     */
    private drawNoTarget(dispGroup: DispGroupPointerT, ctx,
                         zoom: number, pan: PointI, drawMode: DrawModeE) {
        if (drawMode != DrawModeE.ForEdit)
            return;

        const box = PeekCanvasBounds.fromGeom(DispGroupPointer.geom(dispGroup));
        const selectionConfig = this.config.renderer.editSelection;

        // We'll use the margin from the selected config if there is just one point.
        if (box.w == 0) {
            let offset = (selectionConfig.width + selectionConfig.lineGap) / zoom;
            box.x -= offset;
            box.y -= offset;
            box.w = 2 * offset;
            box.h = 2 * offset;
        }

        const rotation = DispGroupPointer.rotation(dispGroup);
        const center = box.center();


        ctx.save();
        if (rotation != 0) {
            ctx.translate(center.x, center.y);
            ctx.rotate(rotation * Math.PI / 180);
            ctx.translate(-center.x, -center.y);
        }

        ctx.beginPath();
        // Top left to Bottom right
        ctx.moveTo(box.x, box.y);
        ctx.lineTo(box.x + box.w, box.y + box.h);

        // Bottom left to top right
        ctx.moveTo(box.x, box.y + box.h);
        ctx.lineTo(box.x + box.w, box.y);

        ctx.strokeStyle = selectionConfig.color;
        ctx.lineWidth = selectionConfig.width / zoom;
        ctx.stroke();

        // Show an indication of rotation
        ctx.beginPath();
        // Top left to Bottom right
        ctx.moveTo(box.x, box.y);
        ctx.lineTo(box.x + box.w / 2, box.y + box.h / 2);

        ctx.strokeStyle = 'red';
        ctx.lineWidth = selectionConfig.width / zoom;
        ctx.stroke();

        ctx.restore();

    };

    drawSelected(disp, ctx, zoom: number, pan: PointI, drawMode: DrawModeE) {
        let bounds = disp.bounds;
        if (bounds == null)
            return;

        // DRAW THE SELECTED BOX
        let selectionConfig = this.config.getSelectionDrawDetailsForDrawMode(drawMode);

        // Move the selection line a bit away from the object
        let offset = (selectionConfig.width + selectionConfig.lineGap) / zoom;

        let twiceOffset = 2 * offset;
        let x = bounds.x - offset;
        let y = bounds.y - offset;
        let w = bounds.w + twiceOffset;
        let h = bounds.h + twiceOffset;

        ctx.dashedRect(x, y, w, h, selectionConfig.dashLen / zoom);
        ctx.strokeStyle = selectionConfig.color;
        ctx.lineWidth = selectionConfig.width / zoom;
        ctx.stroke();
    };

    drawEditHandles(disp, ctx, zoom: number, pan: PointI) {

        // DRAW THE EDIT HANDLES
        ctx.fillStyle = this.config.editor.selectionHighlightColor;
        const handles = this.handles(disp);

        for (const handle of handles) {
            const b = handle.box;
            ctx.beginPath();
            switch (handle.handleType) {
                case DispHandleTypeE.freeRotate:
                    ctx.arc(b.x + b.w / 2, b.y + b.h / 2, b.h / 2, 0, 2 * Math.PI);
                    break;
                case DispHandleTypeE.snapRotate:
                    ctx.rect(b.x, b.y, b.w, b.h);
                    break;
                default:
                    // pass
                    break;
            }
            ctx.fill();
        }

    }

}