"use strict";
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.usePolygonDrawing = exports.MAP_DRAWING_CROSSHAIR_CURSOR = void 0;
var react_1 = require("react");
var helpers_1 = require("../../helpers");
var polygonRingHelpers_1 = require("./polygonRingHelpers");
var useDrawingCursors_1 = require("./useDrawingCursors");
var usePreviewPolylines_1 = require("./usePreviewPolylines");
var useVertexHandles_1 = require("./useVertexHandles");
var useDrawingCursors_2 = require("./useDrawingCursors");
Object.defineProperty(exports, "MAP_DRAWING_CROSSHAIR_CURSOR", { enumerable: true, get: function () { return useDrawingCursors_2.MAP_DRAWING_CROSSHAIR_CURSOR; } });
var usePolygonDrawing = function (_a) {
    var map = _a.map, isActive = _a.isActive, previewPolylineOptions = _a.previewPolylineOptions, completedPolygonOptions = _a.completedPolygonOptions, onPolygonComplete = _a.onPolygonComplete;
    var _b = (0, react_1.useState)([]), vertices = _b[0], setVertices = _b[1];
    var verticesRef = (0, react_1.useRef)([]);
    var completionLockRef = (0, react_1.useRef)(false);
    var previewPolylineOptionsRef = (0, react_1.useRef)(previewPolylineOptions);
    previewPolylineOptionsRef.current = previewPolylineOptions;
    verticesRef.current = vertices;
    var prevDisableDoubleClickZoom = (0, react_1.useRef)(undefined);
    var prevClickableIcons = (0, react_1.useRef)(undefined);
    var prevDraggableCursor = (0, react_1.useRef)(undefined);
    var syncDisposeVertexHandlesRef = (0, react_1.useRef)(function () { });
    (0, react_1.useEffect)(function () {
        if (map && isActive) {
            setVertices([]);
            completionLockRef.current = false;
        }
        else if (!isActive) {
            setVertices([]);
        }
    }, [map, isActive]);
    var reapplyCursors = (0, useDrawingCursors_1.useDrawingCursors)(map, isActive).reapplyCursors;
    var _c = (0, usePreviewPolylines_1.usePreviewPolylines)(map, previewPolylineOptionsRef, isActive), polylineRef = _c.polylineRef, rubberBandPolylineRef = _c.rubberBandPolylineRef, handleZIndexRef = _c.handleZIndexRef;
    var reapplyCursorsRef = (0, react_1.useRef)(reapplyCursors);
    reapplyCursorsRef.current = reapplyCursors;
    var onPolygonCompleteRef = (0, react_1.useRef)(onPolygonComplete);
    onPolygonCompleteRef.current = onPolygonComplete;
    var completedPolygonOptionsRef = (0, react_1.useRef)(completedPolygonOptions);
    completedPolygonOptionsRef.current = completedPolygonOptions;
    var tryComplete = (0, react_1.useCallback)(function () {
        var _a, _b;
        if (completionLockRef.current) {
            return;
        }
        var verts = (0, polygonRingHelpers_1.dedupeTrailingDuplicateVertex)(verticesRef.current);
        if (!(0, polygonRingHelpers_1.validateRing)(verts)) {
            return;
        }
        completionLockRef.current = true;
        syncDisposeVertexHandlesRef.current();
        (_a = rubberBandPolylineRef.current) === null || _a === void 0 ? void 0 : _a.setPath([]);
        var polygon = (0, polygonRingHelpers_1.buildPolygonFromVertices)(verts, completedPolygonOptionsRef.current);
        (_b = polylineRef.current) === null || _b === void 0 ? void 0 : _b.setPath([]);
        setVertices([]);
        reapplyCursorsRef.current();
        onPolygonCompleteRef.current(polygon);
    }, [polylineRef, rubberBandPolylineRef]);
    var resetDraftPolygon = (0, react_1.useCallback)(function () {
        var _a, _b;
        if (verticesRef.current.length === 0) {
            return;
        }
        setVertices([]);
        (_a = polylineRef.current) === null || _a === void 0 ? void 0 : _a.setPath([]);
        (_b = rubberBandPolylineRef.current) === null || _b === void 0 ? void 0 : _b.setPath([]);
        reapplyCursorsRef.current();
    }, [polylineRef, rubberBandPolylineRef]);
    var tryCompleteRef = (0, react_1.useRef)(tryComplete);
    tryCompleteRef.current = tryComplete;
    var resetDraftPolygonRef = (0, react_1.useRef)(resetDraftPolygon);
    resetDraftPolygonRef.current = resetDraftPolygon;
    var previewPathVertexCountRef = (0, react_1.useRef)(0);
    (0, useVertexHandles_1.useVertexHandles)({
        map: map,
        isActive: isActive,
        vertices: vertices,
        handleZIndexRef: handleZIndexRef,
        onFirstHandleClick: tryComplete,
        syncDisposeRef: syncDisposeVertexHandlesRef
    });
    (0, react_1.useEffect)(function () {
        if (!isActive) {
            previewPathVertexCountRef.current = 0;
            return;
        }
        var line = polylineRef.current;
        var band = rubberBandPolylineRef.current;
        if (!line) {
            return;
        }
        var path = line.getPath();
        var prev = previewPathVertexCountRef.current;
        var vertexCount = vertices.length;
        if (vertexCount === 0) {
            if (path.getLength() > 0) {
                path.clear();
            }
            band === null || band === void 0 ? void 0 : band.setPath([]);
            previewPathVertexCountRef.current = 0;
            return;
        }
        var pathLen = path.getLength();
        if (vertexCount < prev) {
            line.setPath(vertices);
        }
        else if (vertexCount === prev + 1 && pathLen === prev) {
            var added = vertices[vertexCount - 1];
            if (added) {
                path.push(added);
            }
        }
        else if (vertexCount !== prev || pathLen !== vertexCount) {
            line.setPath(vertices);
        }
        previewPathVertexCountRef.current = vertexCount;
        var last = vertices[vertexCount - 1];
        if (last) {
            band === null || band === void 0 ? void 0 : band.setPath([last, last]);
        }
    }, [isActive, vertices, polylineRef, rubberBandPolylineRef]);
    (0, react_1.useEffect)(function () {
        if (!map || !isActive) {
            return undefined;
        }
        prevDisableDoubleClickZoom.current = map.get('disableDoubleClickZoom');
        prevClickableIcons.current = map.get('clickableIcons');
        prevDraggableCursor.current = map.get('draggableCursor');
        var mapDiv = map.getDiv();
        var rubber = rubberBandPolylineRef;
        var updateRubberBand = function (latLngFromEvent) {
            var _a, _b, _c;
            var verts = verticesRef.current;
            if (!verts.length || !latLngFromEvent) {
                (_a = rubber.current) === null || _a === void 0 ? void 0 : _a.setPath([]);
                return;
            }
            var last = verts[verts.length - 1];
            if (!last) {
                (_b = rubber.current) === null || _b === void 0 ? void 0 : _b.setPath([]);
                return;
            }
            (_c = rubber.current) === null || _c === void 0 ? void 0 : _c.setPath([last, latLngFromEvent]);
        };
        map.setOptions({
            disableDoubleClickZoom: true,
            clickableIcons: false,
            draggableCursor: useDrawingCursors_1.MAP_DRAWING_CROSSHAIR_CURSOR
        });
        var mouseMoveListener = map.addListener('mousemove', function (e) {
            var _a;
            updateRubberBand((_a = e.latLng) !== null && _a !== void 0 ? _a : null);
        });
        var onDrawingClick = function (e) {
            var latLng = e.latLng;
            if (!latLng) {
                return;
            }
            if (completionLockRef.current) {
                return;
            }
            setVertices(function (vs) { return __spreadArray(__spreadArray([], vs, true), [latLng], false); });
        };
        var clickListener = map.addListener('click', onDrawingClick);
        var onMapDivDblClick = function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            tryCompleteRef.current();
        };
        var onMapDivMouseLeave = function () {
            resetDraftPolygonRef.current();
        };
        if ((0, helpers_1.isDomElement)(mapDiv)) {
            mapDiv.addEventListener('dblclick', onMapDivDblClick, true);
            mapDiv.addEventListener('mouseleave', onMapDivMouseLeave);
        }
        return function () {
            var _a;
            if ((0, helpers_1.isDomElement)(mapDiv)) {
                mapDiv.removeEventListener('dblclick', onMapDivDblClick, true);
                mapDiv.removeEventListener('mouseleave', onMapDivMouseLeave);
            }
            google.maps.event.removeListener(mouseMoveListener);
            google.maps.event.removeListener(clickListener);
            map.setOptions({
                disableDoubleClickZoom: (_a = prevDisableDoubleClickZoom.current) !== null && _a !== void 0 ? _a : false,
                clickableIcons: prevClickableIcons.current !== undefined ? prevClickableIcons.current : true,
                draggableCursor: prevDraggableCursor.current
            });
        };
    }, [map, isActive]);
};
exports.usePolygonDrawing = usePolygonDrawing;
