"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AddLayer = void 0;
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var i18n_1 = require("../../api/i18n");
var add_wms_layer_1 = require("./add-wms-layer");
var add_wfs_layer_1 = require("./add-wfs-layer");
var core_1 = require("@blueprintjs/core");
var string_1 = require("../../utils/string");
var projections_1 = require("../../api/registry/projections");
var wfs_capabilities_panel_1 = require("./wfs-capabilities-panel");
var runtime_1 = require("../../api/runtime");
var add_manage_layers_1 = require("../../containers/add-manage-layers");
var color_brewer_1 = require("./color-brewer");
var ol_style_contracts_1 = require("../../api/ol-style-contracts");
var never_1 = require("../../utils/never");
var dompurify_1 = require("dompurify");
var ADD_URL_LAYER_TYPES = {
    "WMS": {
        label: "WMS",
        content: function (props) { return React.createElement(add_wms_layer_1.AddWmsLayer, tslib_1.__assign({}, props)); }
    },
    "WFS": {
        label: "WFS",
        content: function (props) { return React.createElement(add_wfs_layer_1.AddWfsLayer, tslib_1.__assign({}, props)); }
    }
};
var AddLayerKind;
(function (AddLayerKind) {
    AddLayerKind[AddLayerKind["File"] = 0] = "File";
    AddLayerKind[AddLayerKind["Url"] = 1] = "Url";
})(AddLayerKind || (AddLayerKind = {}));
var CreateVectorLayerAs;
(function (CreateVectorLayerAs) {
    CreateVectorLayerAs["Vector"] = "Vector";
    CreateVectorLayerAs["Themed"] = "Themed";
    CreateVectorLayerAs["Clustered"] = "Clustered";
    CreateVectorLayerAs["Heatmap"] = "Heatmap";
})(CreateVectorLayerAs || (CreateVectorLayerAs = {}));
function getCreateVectorLayerOptions(geomTypes, locale) {
    var options = [
        { value: CreateVectorLayerAs.Vector, label: (0, i18n_1.tr)("CREATE_VECTOR_LAYER", locale), isValid: function (geomTypes) { return true; } },
        { value: CreateVectorLayerAs.Themed, label: (0, i18n_1.tr)("CREATE_VECTOR_THEMED", locale), isValid: function (geomTypes) { return true; } },
        { value: CreateVectorLayerAs.Clustered, label: (0, i18n_1.tr)("CREATE_VECTOR_CLUSTERED", locale), isValid: function (geomTypes) { return geomTypes.length == 1 && geomTypes.includes("Point"); } },
        { value: CreateVectorLayerAs.Heatmap, label: (0, i18n_1.tr)("CREATE_VECTOR_HEATMAP", locale), isValid: function (geomTypes) { return geomTypes.length == 1 && geomTypes.includes("Point"); } }
    ];
    return options.filter(function (o) { return o.isValid(geomTypes); });
}
var AddFileLayer = function (props) {
    var locale = props.locale;
    var _a = React.useState(false), isProcessingFile = _a[0], setIsProcessingFile = _a[1];
    var _b = React.useState(false), isAddingLayer = _b[0], setIsAddingLayer = _b[1];
    var _c = React.useState(undefined), addLayerError = _c[0], setAddLayerError = _c[1];
    var _d = React.useState(undefined), loadedFile = _d[0], setLoadedFile = _d[1];
    var _e = React.useState(undefined), addLayerName = _e[0], setAddLayerName = _e[1];
    var _f = React.useState(4326), addProjection = _f[0], setAddProjection = _f[1];
    var _g = React.useState(getCreateVectorLayerOptions([], locale)), createOptions = _g[0], setCreateOptions = _g[1];
    var _h = React.useState(false), enableLabels = _h[0], setEnableLabels = _h[1];
    var _j = React.useState(undefined), labelOnProperty = _j[0], setLabelOnProperty = _j[1];
    var _k = React.useState(undefined), themeOnProperty = _k[0], setThemeOnProperty = _k[1];
    var _l = React.useState([]), themableProperties = _l[0], setThemableProperties = _l[1];
    var _m = React.useState("Blues"), themeToUse = _m[0], setThemeToUse = _m[1];
    var _o = React.useState(CreateVectorLayerAs.Vector), createLayerAs = _o[0], setCreateLayerAs = _o[1];
    var _p = React.useState(10), clusterDistance = _p[0], setClusterDistance = _p[1];
    var _q = React.useState((0, color_brewer_1.getColorBrewerRamps)()), themableRamps = _q[0], _ = _q[1];
    var _r = React.useState(ol_style_contracts_1.ClusterClickAction.ShowPopup), clusterClickAction = _r[0], setClusterClickAction = _r[1];
    var parsedFeaturesRef = React.useRef(undefined);
    var setParsedFile = function (parsed) {
        setEnableLabels(false);
        setCreateOptions(getCreateVectorLayerOptions([], locale));
        parsedFeaturesRef.current = parsed;
        if (parsed) {
            setAddLayerName(parsed.name);
            setLoadedFile({
                name: parsed.name,
                size: parsed.size,
                type: parsed.type,
                defaultProjection: parsed.projection
            });
            setCreateOptions(getCreateVectorLayerOptions(parsed.geometryTypes, locale));
            setThemableProperties(parsed.propertyNames);
            if (parsed.propertyNames.length > 0) {
                setThemeOnProperty(parsed.propertyNames[0]);
                setLabelOnProperty(parsed.propertyNames[0]);
            }
            if (parsed.projection) {
                var epsg = (0, wfs_capabilities_panel_1.parseEpsgCodeFromCRS)(parsed.projection);
                if (epsg) {
                    setAddProjection(epsg);
                }
            }
        }
        else {
            setLoadedFile(undefined);
            parsedFeaturesRef.current = undefined;
        }
    };
    var onFileDropped = function (file) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        var viewer, layerMgr, parsed, e_1;
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    viewer = (0, runtime_1.getViewer)();
                    if (!viewer) return [3 /*break*/, 5];
                    setIsProcessingFile(true);
                    setAddLayerError(undefined);
                    layerMgr = viewer.getLayerManager();
                    _a.label = 1;
                case 1:
                    _a.trys.push([1, 3, , 4]);
                    return [4 /*yield*/, layerMgr.parseFeaturesFromFile({
                            file: file,
                            name: file.name,
                            locale: locale
                        })];
                case 2:
                    parsed = _a.sent();
                    setParsedFile(parsed);
                    return [3 /*break*/, 4];
                case 3:
                    e_1 = _a.sent();
                    setAddLayerError(e_1);
                    return [3 /*break*/, 4];
                case 4:
                    setIsProcessingFile(false);
                    _a.label = 5;
                case 5: return [2 /*return*/];
            }
        });
    }); };
    var onCancelAddFile = function () {
        setParsedFile(undefined);
    };
    var onAddFileLayer = React.useCallback(function (layerProjection) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        var viewer, _a, _1, layerProj, layerMgr, extraOpts, labelProp, layer, e_2;
        return tslib_1.__generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    viewer = (0, runtime_1.getViewer)();
                    if (!(viewer && (parsedFeaturesRef === null || parsedFeaturesRef === void 0 ? void 0 : parsedFeaturesRef.current))) return [3 /*break*/, 6];
                    setIsAddingLayer(true);
                    setAddLayerError(undefined);
                    _b.label = 1;
                case 1:
                    _b.trys.push([1, 4, , 5]);
                    return [4 /*yield*/, (0, projections_1.ensureProjection)(layerProjection, locale)];
                case 2:
                    _a = _b.sent(), _1 = _a[0], layerProj = _a[1];
                    if (!(0, string_1.strIsNullOrEmpty)(addLayerName)) {
                        parsedFeaturesRef.current.name = addLayerName;
                    }
                    layerMgr = viewer.getLayerManager();
                    if (layerMgr.hasLayer(parsedFeaturesRef.current.name)) {
                        throw new Error((0, i18n_1.tr)("LAYER_NAME_EXISTS", locale, { name: parsedFeaturesRef.current.name }));
                    }
                    extraOpts = void 0;
                    switch (createLayerAs) {
                        case CreateVectorLayerAs.Clustered:
                            extraOpts = {
                                kind: "Cluster",
                                clusterDistance: clusterDistance,
                                onClusterClickAction: clusterClickAction
                            };
                            break;
                        case CreateVectorLayerAs.Themed:
                            extraOpts = {
                                kind: "Theme",
                                themeOnProperty: themeOnProperty,
                                colorBrewerTheme: themeToUse
                            };
                            break;
                        case CreateVectorLayerAs.Heatmap:
                            extraOpts = {
                                kind: "Heatmap"
                            };
                            break;
                    }
                    labelProp = void 0;
                    if (enableLabels) {
                        labelProp = labelOnProperty;
                    }
                    return [4 /*yield*/, layerMgr.addLayerFromParsedFeatures({
                            features: parsedFeaturesRef.current,
                            projection: layerProj,
                            extraOptions: extraOpts,
                            labelOnProperty: labelProp
                        })];
                case 3:
                    layer = _b.sent();
                    (0, add_manage_layers_1.zoomToLayerExtents)(layer.name, viewer);
                    setIsAddingLayer(false);
                    viewer.toastSuccess("success", (0, i18n_1.tr)("ADDED_LAYER", props.locale, { name: layer.name }));
                    setAddLayerError(undefined);
                    setLoadedFile(undefined);
                    setAddLayerName(undefined);
                    props.onLayerAdded(layer);
                    return [3 /*break*/, 5];
                case 4:
                    e_2 = _b.sent();
                    setAddLayerError(e_2);
                    if (!(0, string_1.strIsNullOrEmpty)(e_2 === null || e_2 === void 0 ? void 0 : e_2.message)) {
                        viewer.toastError("error", e_2.message);
                    }
                    return [3 /*break*/, 5];
                case 5:
                    setIsAddingLayer(false);
                    _b.label = 6;
                case 6: return [2 /*return*/];
            }
        });
    }); }, [clusterDistance, createLayerAs, themeOnProperty, themeToUse, enableLabels, labelOnProperty, clusterClickAction]);
    if (loadedFile) {
        var canAdd = true;
        if (createLayerAs == CreateVectorLayerAs.Themed) {
            if ((0, string_1.strIsNullOrEmpty)(themeOnProperty)) {
                canAdd = false;
            }
        }
        var labelEl_1 = React.createElement(React.Fragment, null,
            React.createElement(core_1.Switch, { label: (0, i18n_1.tr)("ENABLE_LABELS", locale), checked: enableLabels, onChange: function (e) { return setEnableLabels(e.target.checked); } }),
            enableLabels && React.createElement(core_1.FormGroup, { label: (0, i18n_1.tr)("LABEL_USING_PROPERTY", locale) },
                React.createElement(core_1.HTMLSelect, { value: labelOnProperty, onChange: function (e) { return setLabelOnProperty(e.target.value); } }, themableProperties.map(function (th, i) { return React.createElement("option", { key: th, value: th }, th); }))));
        var colorBrewerLabel = React.createElement("div", { dangerouslySetInnerHTML: { __html: (0, dompurify_1.sanitize)((0, i18n_1.tr)("COLORBREWER_THEME", locale)) } });
        var themeEl_1 = React.createElement(React.Fragment, null,
            React.createElement(core_1.FormGroup, { label: (0, i18n_1.tr)("THEME_ON_PROPERTY", locale) },
                React.createElement(core_1.HTMLSelect, { value: themeOnProperty, onChange: function (e) { return setThemeOnProperty(e.target.value); } }, themableProperties.map(function (th, i) { return React.createElement("option", { key: th, value: th }, th); }))),
            React.createElement(core_1.FormGroup, { label: colorBrewerLabel },
                React.createElement(core_1.HTMLSelect, { value: themeToUse, onChange: function (e) { return setThemeToUse(e.target.value); } }, themableRamps.map(function (th, i) { return React.createElement("option", { key: th.displayName, value: th.scheme }, th.displayName); }))),
            themeToUse && React.createElement(color_brewer_1.ColorBrewerSwatch, { theme: themeToUse }));
        var clusterEl_1 = React.createElement(React.Fragment, null,
            React.createElement(core_1.FormGroup, { label: (0, i18n_1.tr)("POINT_CLUSTER_DISTANCE", locale) },
                React.createElement(core_1.NumericInput, { min: 1, value: clusterDistance, onValueChange: function (v) { return setClusterDistance(v); } })),
            React.createElement(core_1.FormGroup, { label: (0, i18n_1.tr)("CLUSTER_CLICK_ACTION", locale) },
                React.createElement(core_1.HTMLSelect, { value: clusterClickAction, onChange: function (e) { return setClusterClickAction(e.target.value); } },
                    React.createElement("option", { value: ol_style_contracts_1.ClusterClickAction.ShowPopup }, (0, i18n_1.tr)("CLUSTER_CLICK_ACTION_SHOW_POPUP", locale)),
                    React.createElement("option", { value: ol_style_contracts_1.ClusterClickAction.ZoomToClusterExtents }, (0, i18n_1.tr)("CLUSTER_CLICK_ACTION_ZOOM_EXTENTS", locale)))));
        return React.createElement(core_1.NonIdealState, { title: React.createElement(core_1.EditableText, { value: addLayerName, onChange: function (v) { return setAddLayerName(v); } }), icon: "upload", description: (0, i18n_1.tr)("FMT_UPLOADED_FILE", locale, { size: loadedFile.size, type: ((0, string_1.strIsNullOrEmpty)(loadedFile.type) ? (0, i18n_1.tr)("UNKNOWN_FILE_TYPE", locale) : loadedFile.type) }), action: React.createElement(React.Fragment, null,
                addLayerError && React.createElement(core_1.Callout, { intent: core_1.Intent.DANGER, title: (0, i18n_1.tr)("ADDING_LAYER_ERROR", locale) }, addLayerError.message),
                React.createElement(core_1.FormGroup, { label: (0, i18n_1.tr)("ADD_LAYER_PROJECTION", locale) }, loadedFile.defaultProjection ? React.createElement("strong", null,
                    "EPSG:",
                    addProjection) : React.createElement(core_1.FormGroup, { label: React.createElement("a", { href: "https://epsg.io", target: "_blank" }, "EPSG:"), inline: true },
                    React.createElement(core_1.NumericInput, { style: { width: 60 }, min: 0, value: addProjection, onValueChange: function (v) { return setAddProjection(v); } }))),
                React.createElement(core_1.FormGroup, { label: "Create Layer As" },
                    React.createElement(core_1.HTMLSelect, { value: createLayerAs, onChange: function (e) { return setCreateLayerAs(e.target.value); } }, createOptions.map(function (kind, i) { return React.createElement("option", { key: kind.value, value: kind.value }, kind.label); }))),
                (function () {
                    switch (createLayerAs) {
                        case CreateVectorLayerAs.Vector:
                            return React.createElement(React.Fragment, null, labelEl_1);
                        case CreateVectorLayerAs.Themed:
                            return React.createElement(React.Fragment, null,
                                labelEl_1,
                                themeEl_1);
                        case CreateVectorLayerAs.Clustered:
                            return React.createElement(React.Fragment, null,
                                labelEl_1,
                                clusterEl_1);
                        case CreateVectorLayerAs.Heatmap:
                            return React.createElement(React.Fragment, null);
                        default:
                            (0, never_1.assertNever)(createLayerAs);
                    }
                })(),
                React.createElement(core_1.ButtonGroup, null,
                    React.createElement(core_1.Button, { disabled: !canAdd, loading: isAddingLayer, onClick: function (e) { return onAddFileLayer(addProjection); }, intent: core_1.Intent.PRIMARY }, (0, i18n_1.tr)("ADD_LAYER", locale)),
                    React.createElement(core_1.Button, { loading: isAddingLayer, onClick: function (e) { return onCancelAddFile(); }, intent: core_1.Intent.DANGER }, (0, i18n_1.tr)("CANCEL", locale)))) });
    }
    else if (isProcessingFile) {
        return React.createElement(core_1.NonIdealState, { icon: React.createElement(core_1.Spinner, { intent: core_1.Intent.NONE, size: core_1.SpinnerSize.LARGE }), title: (0, i18n_1.tr)("ADD_FILE_PROCESSING", locale) });
    }
    else {
        return React.createElement(React.Fragment, null,
            addLayerError && React.createElement(core_1.Callout, { intent: core_1.Intent.DANGER, title: (0, i18n_1.tr)("ADDING_LAYER_ERROR", locale) }, addLayerError.message),
            React.createElement(core_1.NonIdealState, { title: (0, i18n_1.tr)("ADD_FILE", locale), icon: "upload", description: (0, i18n_1.tr)("ADD_FILE_INSTRUCTIONS", locale), action: React.createElement(core_1.FileInput, { fill: true, text: (0, i18n_1.tr)("CHOOSE_FILE", locale), buttonText: (0, i18n_1.tr)("BROWSE", locale), onInputChange: function (e) { return e.target.files && onFileDropped(e.target.files[0]); } }) }));
    }
};
var AddUrlLayer = function (props) {
    var locale = props.locale;
    var _a = React.useState(undefined), selectedUrlType = _a[0], setSelectedUrlType = _a[1];
    var onUrlLayerTypeChanged = function (e) {
        setSelectedUrlType(e.target.value);
    };
    var items = Object.keys(ADD_URL_LAYER_TYPES).map(function (lt) { return ({ value: lt, label: ADD_URL_LAYER_TYPES[lt].label }); });
    return React.createElement("div", null,
        React.createElement(core_1.Label, null,
            (0, i18n_1.tr)("LAYER_TYPE", locale),
            React.createElement(core_1.HTMLSelect, { value: selectedUrlType || "", onChange: onUrlLayerTypeChanged },
                React.createElement("option", null, (0, i18n_1.tr)("SELECT_LAYER_TYPE", locale)),
                items.map(function (it) { return React.createElement("option", { key: it.value, value: it.value }, it.value); }))),
        (function () {
            if (selectedUrlType && ADD_URL_LAYER_TYPES[selectedUrlType]) {
                var cprops = {
                    locale: locale,
                    onLayerAdded: props.onLayerAdded,
                    onAddLayerBusyWorker: props.onAddLayerBusyWorker,
                    onRemoveLayerBusyWorker: props.onRemoveLayerBusyWorker
                };
                return ADD_URL_LAYER_TYPES[selectedUrlType].content(cprops);
            }
        })());
};
/**
 * @hidden
 */
var AddLayer = function (props) {
    var _a = React.useState(AddLayerKind.File), addLayerKind = _a[0], setAddLayerKind = _a[1];
    var onAddLayerKindChanged = function (e) {
        setAddLayerKind(parseInt(e.target.value, 10));
    };
    return React.createElement("div", null,
        React.createElement(core_1.RadioGroup, { label: (0, i18n_1.tr)("ADD_LAYER_KIND_PROMPT", props.locale), onChange: onAddLayerKindChanged, selectedValue: addLayerKind },
            React.createElement(core_1.Radio, { label: (0, i18n_1.tr)("LAYER_KIND_FILE", props.locale), value: AddLayerKind.File }),
            React.createElement(core_1.Radio, { label: (0, i18n_1.tr)("LAYER_KIND_URL", props.locale), value: AddLayerKind.Url })),
        React.createElement("hr", null),
        (function () {
            switch (addLayerKind) {
                case AddLayerKind.File:
                    return React.createElement(AddFileLayer, tslib_1.__assign({}, props));
                case AddLayerKind.Url:
                    return React.createElement(AddUrlLayer, tslib_1.__assign({}, props));
            }
        })());
};
exports.AddLayer = AddLayer;
//# sourceMappingURL=add-layer.js.map