"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Point = /** @class */ (function () {
    function Point() {
        this.lat = 0.00;
        this.lng = 0.00;
    }
    return Point;
}());
var OverlayType;
(function (OverlayType) {
    OverlayType[OverlayType["POINT"] = 0] = "POINT";
    OverlayType[OverlayType["CIRCLE"] = 1] = "CIRCLE";
    OverlayType[OverlayType["POLYGON"] = 2] = "POLYGON";
})(OverlayType || (OverlayType = {}));
var OverlayData = /** @class */ (function () {
    function OverlayData(type, name, desc, points, options) {
        this.type = type;
        this.name = name;
        this.desc = desc;
        this.points = points;
        this.options = options;
    }
    return OverlayData;
}());
var OverlayBase = /** @class */ (function () {
    function OverlayBase(name, desc, points, options) {
        this.name = name;
        this.desc = desc;
        this.points = points;
        this.options = options;
    }
    OverlayBase.prototype.add = function (map) {
        this.self.addTo(map);
    };
    OverlayBase.prototype.remove = function (map) {
        this.self.removeFrom(map);
    };
    return OverlayBase;
}());
var Marker = /** @class */ (function (_super) {
    __extends(Marker, _super);
    function Marker(name, desc, point, options) {
        var _this_1 = _super.call(this, name, desc, [point], options) || this;
        _this_1.self = L.marker(point);
        _this_1.self.bindPopup("<h3>" + name + "</h3><p>" + desc + "</p>");
        return _this_1;
    }
    return Marker;
}(OverlayBase));
var Circle = /** @class */ (function (_super) {
    __extends(Circle, _super);
    function Circle(name, desc, point, options) {
        var _this_1 = _super.call(this, name, desc, [point], options) || this;
        _this_1.self = L.circle(point, options);
        return _this_1;
    }
    return Circle;
}(OverlayBase));
var Polygon = /** @class */ (function (_super) {
    __extends(Polygon, _super);
    function Polygon(name, desc, points, options) {
        var _this_1 = _super.call(this, name, desc, points, options) || this;
        _this_1.self = L.polygon(points, options);
        return _this_1;
    }
    return Polygon;
}(OverlayBase));
var OverlayState = /** @class */ (function () {
    function OverlayState() {
        this.markers = [];
        this.circles = [];
        this.polygons = [];
    }
    OverlayState.load = function () {
        var store = localStorage.getItem("overlay_state");
        if (store) {
            var model = JSON.parse(store);
            return {
                markers: model.markers.map(function (m) { return OverlayState.fromData(m); }),
                circles: model.circles.map(function (c) { return OverlayState.fromData(c); }),
                polygons: model.polygons.map(function (p) { return OverlayState.fromData(p); })
            };
        }
        else {
            return new OverlayState();
        }
    };
    OverlayState.save = function (overlayState) {
        localStorage.setItem("overlay_state", JSON.stringify({
            markers: overlayState.markers.map(function (m) { return OverlayState.toData(m); }),
            circles: overlayState.circles.map(function (c) { return OverlayState.toData(c); }),
            polygons: overlayState.polygons.map(function (p) { return OverlayState.toData(p); })
        }));
    };
    OverlayState.clear = function (overlayState, map) {
        overlayState.markers.forEach(function (m) { return m.remove(map); });
        overlayState.circles.forEach(function (c) { return c.remove(map); });
        overlayState.polygons.forEach(function (p) { return p.remove(map); });
        return new OverlayState();
    };
    OverlayState.toData = function (source) {
        var type = OverlayType.POINT;
        if (source.points.length > 1) {
            type = OverlayType.POLYGON;
        }
        else if (source.options.radius) {
            type = OverlayType.CIRCLE;
        }
        return new OverlayData(type, source.name, source.desc, source.points, source.options);
    };
    OverlayState.fromData = function (data) {
        switch (data.type) {
            case OverlayType.POINT:
                return new Marker(data.name, data.desc, data.points[0], data.options);
            case OverlayType.CIRCLE:
                return new Circle(data.name, data.desc, data.points[0], data.options);
            case OverlayType.POLYGON:
                return new Polygon(data.name, data.desc, data.points, data.options);
        }
    };
    return OverlayState;
}());
var TileLayerWrapper = /** @class */ (function () {
    function TileLayerWrapper(name, self) {
        this.visible = false;
        this.self = self;
        this.name = name;
    }
    TileLayerWrapper.constructLayer = function (name, self) {
        var wrapper = new TileLayerWrapper(name, self);
        TileLayerWrapper.layers.push(wrapper);
        return wrapper;
    };
    TileLayerWrapper.getActiveLayer = function () {
        for (var _i = 0, _a = TileLayerWrapper.layers; _i < _a.length; _i++) {
            var l = _a[_i];
            if (l.visible == true) {
                return l;
            }
        }
        return null;
    };
    TileLayerWrapper.enableOnly = function (self, map) {
        for (var _i = 0, _a = TileLayerWrapper.layers; _i < _a.length; _i++) {
            var l = _a[_i];
            if (l.visible) {
                l.self.removeFrom(map);
                l.visible = false;
            }
            if (l.name == self.name) {
                l.self.addTo(map);
                l.visible = true;
            }
        }
    };
    TileLayerWrapper.layers = new Array();
    return TileLayerWrapper;
}());
var Modal = /** @class */ (function () {
    function Modal() {
        var _this = this;
        var closeBtn = document.getElementById("modalCloseBtn");
        if (closeBtn) {
            closeBtn.onclick = function () { _this.setVisible(false); };
        }
    }
    Modal.prototype.self = function () {
        return document.getElementById("modal-container");
    };
    Modal.prototype.title = function () {
        return document.getElementById("modal-title");
    };
    Modal.prototype.content = function () {
        return document.getElementById("modal-content");
    };
    Modal.prototype.submitBtn = function () {
        return document.getElementById("modal-submitBtn");
    };
    Modal.prototype.nameField = function () {
        var _a, _b;
        return (_b = (_a = document.getElementById("modal-name")) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : "";
    };
    Modal.prototype.descField = function () {
        var _a, _b;
        return (_b = (_a = document.getElementById("modal-desc")) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : "";
    };
    Modal.prototype.visible = function () {
        var _a;
        return ((_a = this.self()) === null || _a === void 0 ? void 0 : _a.style.display) != "none";
    };
    Modal.prototype.setVisible = function (v) {
        var modal = this.self();
        if (modal) {
            modal.style.display = v ? "block" : "none";
        }
    };
    Modal.prototype.setState = function (state, args) {
        var _this = this;
        switch (state) {
            case OverlayType.POINT:
                var title = this.title();
                if (title) {
                    title.innerHTML = "Add Marker";
                }
                fetch("/static/pointModal.html")
                    .then(function (r) { return r.text(); })
                    .then(function (t) {
                    var content = _this.content();
                    if (content) {
                        content.innerHTML = t;
                    }
                    var submitBtn = _this.submitBtn();
                    if (submitBtn) {
                        submitBtn.onclick = function () {
                            var name = _this.nameField();
                            var desc = _this.descField();
                            var point = new Marker(name, desc, args.latlng, { title: name, alt: name });
                            point.add(args.map);
                            args.overlays.markers.push(point);
                            _this.setVisible(false);
                        };
                    }
                });
                break;
            case OverlayType.CIRCLE:
                break;
            case OverlayType.POLYGON:
                break;
        }
    };
    return Modal;
}());
var MapHandlers = /** @class */ (function () {
    function MapHandlers() {
    }
    return MapHandlers;
}());
function init() {
    var _a;
    var overlays = (_a = OverlayState.load()) !== null && _a !== void 0 ? _a : new OverlayState();
    var map = L.map('map').setView([35.6653, -105.9507], 13);
    var streetLayer = TileLayerWrapper.constructLayer("streetLayer", L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '© OpenStreetMap'
    }));
    var satelliteLayer = TileLayerWrapper.constructLayer("satelliteLayer", L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        maxZoom: 19,
        attribution: "&copy; Esri"
    }));
    TileLayerWrapper.enableOnly(streetLayer, map);
    overlays.markers.forEach(function (m) { return m.add(map); });
    overlays.circles.forEach(function (m) { return m.add(map); });
    overlays.polygons.forEach(function (m) { return m.add(map); });
    var modal = new Modal();
    var addMarkerHandler = function (e) {
        modal.setVisible(true);
        modal.setState(OverlayType.POINT, {
            latlng: e.latlng,
            map: map,
            overlays: overlays
        });
        map.off("click", addMarkerHandler);
    };
    var addMarkerBtn = document.getElementById("addPoint-btn");
    if (addMarkerBtn) {
        addMarkerBtn.onclick = function (e) {
            try {
                map.off("click", addMarkerHandler);
            }
            finally {
                map.on("click", addMarkerHandler);
            }
        };
    }
    var saveBtn = document.getElementById("save-btn");
    if (saveBtn) {
        saveBtn.onclick = function (e) {
            OverlayState.save(overlays);
        };
    }
    var clearBtn = document.getElementById("clear-btn");
    if (clearBtn) {
        clearBtn.onclick = function (e) {
            overlays = OverlayState.clear(overlays, map);
        };
    }
    var tilesBtn = document.getElementById("tiles-btn");
    if (tilesBtn) {
        tilesBtn.onclick = function (e) {
            if (TileLayerWrapper.getActiveLayer() == satelliteLayer) {
                TileLayerWrapper.enableOnly(streetLayer, map);
            }
            else {
                TileLayerWrapper.enableOnly(satelliteLayer, map);
            }
        };
    }
}
init();
