"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getActiveSelectedFeatureXml = exports.buildSelectionXml = exports.deArrayify = exports.isQueryMapFeaturesResponse = exports.isSiteVersion = exports.isTileSet = exports.isMapDef = exports.isAppDef = exports.isWebLayout = void 0;
/**
 * deArrayify.ts
 *
 * This module provides JSON sanitization of JSON responses from the mapagent
 *
 * Being a transformation of the XML form, and taking a lowest-common-denominator
 * approach to JSON conversion, the JSON responses from MapGuide are un-wieldy to
 * use from the client-side due to:
 *
 *  a) All properties being arrays
 *  b) All property values being strings
 *
 * These functions help "clean" those responses to be of the form we expect (and prefer)
 */
var error_1 = require("../error");
var constants_1 = require("../../constants");
function buildPropertyGetter() {
    return function (el, name, type) {
        if (type === void 0) { type = "string"; }
        return tryGetAsProperty(el, name, type);
    };
}
function tryGetAsProperty(el, name, type) {
    if (type === void 0) { type = "string"; }
    if (!el[name]) {
        return null;
    }
    else if (el[name].length === 1) {
        var val = el[name][0];
        switch (type) {
            case "int":
                return parseInt(val, 10);
            case "float":
                return parseFloat(val);
            case "boolean":
                return val.toLowerCase() === "true";
            default:
                return val;
        }
    }
}
function deArrayifyRules(rules) {
    var getter = buildPropertyGetter();
    return rules.map(function (r) {
        var rule = {
            LegendLabel: getter(r, "LegendLabel"),
            Filter: getter(r, "Filter"),
            Icon: getter(r, "Icon")
        };
        return rule;
    });
}
function deArrayifyFeatureStyles(fts) {
    if (!fts) {
        return [];
    }
    var getter = buildPropertyGetter();
    return fts.map(function (ft) {
        var featureStyle = {
            Type: getter(ft, "Type", "int"),
            Rule: deArrayifyRules(ft.Rule)
        };
        return featureStyle;
    });
}
function deArrayifyScaleRanges(scales) {
    if (!scales) { //Happens with raster layers (this is probably a bug in CREATERUNTIMEMAP)
        var defaultRange = {
            MinScale: 0,
            MaxScale: constants_1.MDF_INFINITY,
            FeatureStyle: []
        };
        return [defaultRange];
    }
    var getter = buildPropertyGetter();
    return scales.map(function (sc) {
        var scale = {
            MinScale: getter(sc, "MinScale", "float"),
            MaxScale: getter(sc, "MaxScale", "float"),
            FeatureStyle: deArrayifyFeatureStyles(sc.FeatureStyle)
        };
        return scale;
    });
}
function deArrayifyFeatureSourceInfo(fs) {
    if (!fs || fs.length !== 1) {
        return undefined;
    }
    var getter = buildPropertyGetter();
    return {
        ResourceId: getter(fs[0], "ResourceId"),
        ClassName: getter(fs[0], "ClassName"),
        Geometry: getter(fs[0], "Geometry")
    };
}
function deArrayifyLayers(layers) {
    if (!layers)
        return layers;
    var getter = buildPropertyGetter();
    return layers.map(function (lyr) {
        var layer = {
            Type: getter(lyr, "Type", "int"),
            Selectable: getter(lyr, "Selectable", "boolean"),
            LayerDefinition: getter(lyr, "LayerDefinition"),
            Name: getter(lyr, "Name"),
            LegendLabel: getter(lyr, "LegendLabel"),
            ObjectId: getter(lyr, "ObjectId"),
            ParentId: getter(lyr, "ParentId"),
            DisplayInLegend: getter(lyr, "DisplayInLegend", "boolean"),
            ExpandInLegend: getter(lyr, "ExpandInLegend", "boolean"),
            Visible: getter(lyr, "Visible", "boolean"),
            ActuallyVisible: getter(lyr, "ActuallyVisible", "boolean"),
            FeatureSource: deArrayifyFeatureSourceInfo(lyr.FeatureSource),
            ScaleRange: deArrayifyScaleRanges(lyr.ScaleRange)
        };
        //This is either a raster or drawing layer, in this case disregard the
        //selectability flag (and set it to false). This is to prevent false positive
        //errors trying to do tooltip/selections against raster/drawing layers
        if (!lyr.ScaleRange) {
            layer.Selectable = false;
        }
        return layer;
    });
}
function deArrayifyGroups(groups) {
    if (!groups)
        return undefined;
    var getter = buildPropertyGetter();
    return groups.map(function (grp) {
        var group = {
            Type: getter(grp, "Type", "int"),
            Name: getter(grp, "Name"),
            LegendLabel: getter(grp, "LegendLabel"),
            ObjectId: getter(grp, "ObjectId"),
            ParentId: getter(grp, "ParentId"),
            DisplayInLegend: getter(grp, "DisplayInLegend", "boolean"),
            ExpandInLegend: getter(grp, "ExpandInLegend", "boolean"),
            Visible: getter(grp, "Visible", "boolean"),
            ActuallyVisible: getter(grp, "ActuallyVisible", "boolean")
        };
        return group;
    });
}
function deArrayifyCoordinateSystem(cs) {
    if (!cs || cs.length !== 1) {
        throw new error_1.MgError("Malformed input. Expected CoordinateSystem element");
    }
    var getter = buildPropertyGetter();
    var res = {
        Wkt: getter(cs[0], "Wkt"),
        MentorCode: getter(cs[0], "MentorCode"),
        EpsgCode: getter(cs[0], "EpsgCode"),
        MetersPerUnit: getter(cs[0], "MetersPerUnit", "float")
    };
    return res;
}
function deArrayifyCoordinate(coord) {
    if (!coord || coord.length !== 1) {
        throw new error_1.MgError("Malformed input. Expected coordinate array");
    }
    var getter = buildPropertyGetter();
    return {
        X: getter(coord[0], "X", "float"),
        Y: getter(coord[0], "Y", "float")
    };
}
function deArrayifyExtents(extents) {
    if (!extents || extents.length !== 1) {
        throw new error_1.MgError("Malformed input. Expected extent element");
    }
    var env = {
        LowerLeftCoordinate: deArrayifyCoordinate(extents[0].LowerLeftCoordinate),
        UpperRightCoordinate: deArrayifyCoordinate(extents[0].UpperRightCoordinate)
    };
    return env;
}
function deArrayifyFiniteDisplayScales(fds) {
    if (!fds)
        return undefined;
    return fds.map(parseFloat);
}
function deArrayifyRuntimeMap(json) {
    var root = json;
    var getter = buildPropertyGetter();
    var rtMap = {
        SessionId: getter(root, "SessionId"),
        SiteVersion: getter(root, "SiteVersion"),
        Name: getter(root, "Name"),
        MapDefinition: getter(root, "MapDefinition"),
        TileSetDefinition: getter(root, "TileSetDefinition"),
        TileWidth: getter(root, "TileWidth", "int"),
        TileHeight: getter(root, "TileHeight", "int"),
        BackgroundColor: getter(root, "BackgroundColor"),
        DisplayDpi: getter(root, "DisplayDpi", "int"),
        IconMimeType: getter(root, "IconMimeType"),
        CoordinateSystem: deArrayifyCoordinateSystem(root.CoordinateSystem),
        Extents: deArrayifyExtents(root.Extents),
        Group: deArrayifyGroups(root.Group),
        Layer: deArrayifyLayers(root.Layer),
        FiniteDisplayScale: deArrayifyFiniteDisplayScales(root.FiniteDisplayScale),
        TilePixelRatio: getter(root, "TilePixelRatio", "int"),
        TileSetProvider: getter(root, "TileSetProvider")
    };
    return rtMap;
}
function deArrayifyFeatureSetClass(json) {
    var root = json;
    var getter = buildPropertyGetter();
    if (root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected Class element");
    }
    var cls = {
        "@id": getter(root[0], "@id"),
        ID: root[0].ID
    };
    return cls;
}
function deArrayifyFeatureSetLayers(json) {
    var getter = buildPropertyGetter();
    return (json || []).map(function (root) {
        var layer = {
            "@id": getter(root, "@id"),
            "@name": getter(root, "@name"),
            Class: deArrayifyFeatureSetClass(root.Class)
        };
        return layer;
    });
}
function deArrayifyFeatureSet(json) {
    var root = json;
    if (root == null || root.length != 1) {
        return undefined;
    }
    var fs = {
        Layer: deArrayifyFeatureSetLayers(root[0].Layer)
    };
    return fs;
}
function deArrayifyInlineSelectionImage(json) {
    var root = json;
    if (root == null || root.length != 1) {
        return undefined;
    }
    var getter = buildPropertyGetter();
    var img = {
        MimeType: getter(root[0], "MimeType"),
        Content: getter(root[0], "Content")
    };
    return img;
}
function deArrayifyFeatureProperties(json) {
    var getter = buildPropertyGetter();
    return (json || []).map(function (root) {
        var prop = {
            Name: getter(root, "Name"),
            Value: getter(root, "Value")
        };
        return prop;
    });
}
function deArrayifyFeatures(json) {
    var getter = buildPropertyGetter();
    return (json || []).map(function (root) {
        var feat = {
            Bounds: getter(root, "Bounds"),
            Property: deArrayifyFeatureProperties(root.Property),
            SelectionKey: getter(root, "SelectionKey")
        };
        return feat;
    });
}
function deArrayifyLayerMetadataProperties(json) {
    var getter = buildPropertyGetter();
    return (json || []).map(function (root) {
        var prop = {
            DisplayName: getter(root, "DisplayName"),
            Name: getter(root, "Name"),
            Type: getter(root, "Type", "int")
        };
        return prop;
    });
}
function deArrayifyLayerMetadata(json) {
    var root = json;
    //NOTE: root could be null if the layer selected has no properties beyond id/geom
    if (root == null || root.length != 1) {
        return undefined;
    }
    var meta = {
        Property: deArrayifyLayerMetadataProperties(root[0].Property)
    };
    return meta;
}
function deArrayifySelectedLayer(json) {
    var getter = buildPropertyGetter();
    return (json || []).map(function (root) {
        var layer = {
            "@id": getter(root, "@id"),
            "@name": getter(root, "@name"),
            Feature: deArrayifyFeatures(root.Feature),
            LayerMetadata: deArrayifyLayerMetadata(root.LayerMetadata)
        };
        return layer;
    });
}
function deArrayifySelectedFeatures(json) {
    var root = json;
    if (root == null || root.length != 1) {
        return undefined;
    }
    var sf = {
        SelectedLayer: deArrayifySelectedLayer(root[0].SelectedLayer)
    };
    return sf;
}
function deArrayifyFeatureInformation(json) {
    var root = json;
    var getter = buildPropertyGetter();
    var resp = {
        FeatureSet: deArrayifyFeatureSet(root.FeatureSet),
        Hyperlink: getter(root, "Hyperlink"),
        InlineSelectionImage: deArrayifyInlineSelectionImage(root.InlineSelectionImage),
        SelectedFeatures: deArrayifySelectedFeatures(root.SelectedFeatures),
        Tooltip: getter(root, "Tooltip")
    };
    return resp;
}
function deArrayifyWebLayoutControl(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected control element");
    }
    var getter = buildPropertyGetter();
    var control = {
        Visible: getter(root[0], "Visible", "boolean")
    };
    return control;
}
function deArrayifyWebLayoutInfoPane(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected InformationPane element");
    }
    var getter = buildPropertyGetter();
    var infoPane = {
        Visible: getter(root[0], "Visible", "boolean"),
        Width: getter(root[0], "Width", "int"),
        LegendVisible: getter(root[0], "LegendVisible", "boolean"),
        PropertiesVisible: getter(root[0], "PropertiesVisible", "boolean")
    };
    return infoPane;
}
function deArrayifyWebLayoutInitialView(json) {
    var root = json;
    if (root == null || root.length != 1) {
        return undefined;
    }
    var getter = buildPropertyGetter();
    var view = {
        CenterX: getter(root[0], "CenterX", "float"),
        CenterY: getter(root[0], "CenterY", "float"),
        Scale: getter(root[0], "Scale", "float")
    };
    return view;
}
function deArrayifyWebLayoutMap(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected Map element");
    }
    var getter = buildPropertyGetter();
    var map = {
        ResourceId: getter(root[0], "ResourceId"),
        InitialView: deArrayifyWebLayoutInitialView(root[0].InitialView),
        HyperlinkTarget: getter(root[0], "HyperlinkTarget"),
        HyperlinkTargetFrame: getter(root[0], "HyperlinkTargetFrame")
    };
    return map;
}
function deArrayifyTaskButton(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected TaskButton element");
    }
    var getter = buildPropertyGetter();
    var button = {
        Name: getter(root[0], "Name"),
        Tooltip: getter(root[0], "Tooltip"),
        Description: getter(root[0], "Description"),
        ImageURL: getter(root[0], "ImageURL"),
        DisabledImageURL: getter(root[0], "DisabledImageURL")
    };
    return button;
}
function deArrayifyWebLayoutTaskBar(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected TaskBar element");
    }
    var getter = buildPropertyGetter();
    var taskbar = {
        Visible: getter(root[0], "Visible", "boolean"),
        Home: deArrayifyTaskButton(root[0].Home),
        Forward: deArrayifyTaskButton(root[0].Forward),
        Back: deArrayifyTaskButton(root[0].Back),
        Tasks: deArrayifyTaskButton(root[0].Tasks),
        MenuButton: []
    };
    if (root[0].MenuButton) {
        for (var _i = 0, _a = root[0].MenuButton; _i < _a.length; _i++) {
            var mb = _a[_i];
            taskbar.MenuButton.push(deArrayifyUIItem(mb));
        }
    }
    return taskbar;
}
function deArrayifyWebLayoutTaskPane(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected TaskPane element");
    }
    var getter = buildPropertyGetter();
    var taskPane = {
        Visible: getter(root[0], "Visible", "boolean"),
        InitialTask: getter(root[0], "InitialTask"),
        Width: getter(root[0], "Width", "int"),
        TaskBar: deArrayifyWebLayoutTaskBar(root[0].TaskBar)
    };
    return taskPane;
}
function deArrayifyUIItem(json) {
    var root = json;
    var getter = buildPropertyGetter();
    var func = getter(root, "Function");
    //Wouldn't it be nice if we could incrementally build up a union type that then becomes a specific
    //type once certain properties are set?
    //
    //Well, that's currently not possible. So we have to resort to "any"
    var item = {
        Function: func
    };
    switch (func) {
        case "Command":
            item.Command = getter(root, "Command");
            break;
        case "Flyout":
            item.Label = getter(root, "Label");
            item.Tooltip = getter(root, "Tooltip");
            item.Description = getter(root, "Description");
            item.ImageURL = getter(root, "ImageURL");
            item.DisabledImageURL = getter(root, "DisabledImageURL");
            item.SubItem = [];
            for (var _i = 0, _a = root.SubItem; _i < _a.length; _i++) {
                var si = _a[_i];
                item.SubItem.push(deArrayifyUIItem(si));
            }
            break;
    }
    return item;
}
function deArrayifyItemContainer(json, name) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected container element");
    }
    var getter = buildPropertyGetter();
    var container = {};
    container[name] = [];
    for (var _i = 0, _a = root[0][name]; _i < _a.length; _i++) {
        var item = _a[_i];
        container[name].push(deArrayifyUIItem(item));
    }
    if (typeof (root[0].Visible) != 'undefined') {
        container.Visible = getter(root[0], "Visible", "boolean");
    }
    return container;
}
function deArrayifyWebLayoutSearchResultColumnSet(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected ResultColumns element");
    }
    var getter = buildPropertyGetter();
    var res = {
        Column: []
    };
    for (var _i = 0, _a = root[0].Column; _i < _a.length; _i++) {
        var col = _a[_i];
        res.Column.push({
            Name: getter(col, "Name"),
            Property: getter(col, "Property")
        });
    }
    return res;
}
function deArrayifyWebLayoutInvokeURLLayerSet(json) {
    var root = json;
    if (root == null || root.length != 1) {
        return undefined;
    }
    var layerset = {
        Layer: root[0].Layer
    };
    return layerset;
}
function deArrayifyWebLayoutParameterPairs(json) {
    var root = json;
    var pairs = [];
    if (!root) {
        return pairs;
    }
    var getter = buildPropertyGetter();
    for (var _i = 0, root_1 = root; _i < root_1.length; _i++) {
        var kvp = root_1[_i];
        pairs.push({
            Key: getter(kvp, "Key"),
            Value: getter(kvp, "Value")
        });
    }
    return pairs;
}
function deArrayifyCommand(json) {
    var root = json;
    var getter = buildPropertyGetter();
    var cmd = {
        "@xsi:type": getter(root, "@xsi:type"),
        Name: getter(root, "Name"),
        Label: getter(root, "Label"),
        Tooltip: getter(root, "Tooltip"),
        Description: getter(root, "Description"),
        ImageURL: getter(root, "ImageURL"),
        DisabledImageURL: getter(root, "DisabledImageURL"),
        TargetViewer: getter(root, "TargetViewer")
    };
    //Basic
    if (typeof (root.Action) != 'undefined') {
        cmd.Action = getter(root, "Action");
    }
    //Targeted
    if (typeof (root.Target) != 'undefined') {
        cmd.Target = getter(root, "Target");
    }
    if (typeof (root.TargetFrame) != 'undefined') {
        cmd.TargetFrame = getter(root, "TargetFrame");
    }
    //Search
    if (typeof (root.Layer) != 'undefined') {
        cmd.Layer = getter(root, "Layer");
        cmd.Prompt = getter(root, "Prompt");
        cmd.ResultColumns = deArrayifyWebLayoutSearchResultColumnSet(root.ResultColumns);
        cmd.Filter = getter(root, "Filter");
        cmd.MatchLimit = getter(root, "MatchLimit", "int");
    }
    //InvokeURL | Help
    if (typeof (root.URL) != 'undefined') {
        cmd.URL = getter(root, "URL");
    }
    if (typeof (root.DisableIfSelectionEmpty) != 'undefined') {
        cmd.LayerSet = deArrayifyWebLayoutInvokeURLLayerSet(root.LayerSet);
        cmd.AdditionalParameter = deArrayifyWebLayoutParameterPairs(root.AdditionalParameter);
        cmd.DisableIfSelectionEmpty = getter(root, "DisableIfSelectionEmpty", "boolean");
    }
    //InvokeScript
    if (typeof (root.Script) != 'undefined') {
        cmd.Script = getter(root, "Script");
    }
    return cmd;
}
function deArrayifyWebLayoutCommandSet(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected CommandSet element");
    }
    var set = {
        Command: []
    };
    if (root[0].Command) {
        for (var _i = 0, _a = root[0].Command; _i < _a.length; _i++) {
            var cmd = _a[_i];
            set.Command.push(deArrayifyCommand(cmd));
        }
    }
    return set;
}
function deArrayifyWebLayout(json) {
    var root = json;
    var getter = buildPropertyGetter();
    var resp = {
        Title: getter(root, "Title"),
        Map: deArrayifyWebLayoutMap(root.Map),
        EnablePingServer: getter(root, "EnablePingServer", "boolean"),
        SelectionColor: getter(root, "SelectionColor"),
        PointSelectionBuffer: getter(root, "PointSelectionBuffer", "int"),
        MapImageFormat: getter(root, "MapImageFormat"),
        SelectionImageFormat: getter(root, "SelectionImageFormat"),
        StartupScript: getter(root, "StartupScript"),
        ToolBar: deArrayifyItemContainer(root.ToolBar, "Button"),
        InformationPane: deArrayifyWebLayoutInfoPane(root.InformationPane),
        ContextMenu: deArrayifyItemContainer(root.ContextMenu, "MenuItem"),
        TaskPane: deArrayifyWebLayoutTaskPane(root.TaskPane),
        StatusBar: deArrayifyWebLayoutControl(root.StatusBar),
        ZoomControl: deArrayifyWebLayoutControl(root.ZoomControl),
        CommandSet: deArrayifyWebLayoutCommandSet(root.CommandSet)
    };
    return resp;
}
function deArrayifyMapGroup(json) {
    var root = json;
    if (root == null) {
        throw new error_1.MgError("Malformed input. Expected MapGroup element");
    }
    var getter = buildPropertyGetter();
    var mapGroup = {
        "@id": getter(root, "@id", "string"),
        InitialView: undefined,
        Map: []
    };
    if (root.InitialView) {
        var iview = root.InitialView[0];
        mapGroup.InitialView = {
            CenterX: getter(iview, "CenterX", "float"),
            CenterY: getter(iview, "CenterY", "float"),
            Scale: getter(iview, "Scale", "float")
        };
    }
    if (root.Map) {
        for (var _i = 0, _a = root.Map; _i < _a.length; _i++) {
            var m = _a[_i];
            mapGroup.Map.push({
                Type: getter(m, "Type", "string"),
                //SingleTile: getter(m, "SingleTile", "boolean"),
                Extension: deArrayifyExtension(m.Extension)
            });
        }
    }
    return mapGroup;
}
function deArrayifyMapSet(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected MapSet element");
    }
    var set = {
        MapGroup: []
    };
    if (root[0].MapGroup) {
        for (var _i = 0, _a = root[0].MapGroup; _i < _a.length; _i++) {
            var map = _a[_i];
            set.MapGroup.push(deArrayifyMapGroup(map));
        }
    }
    return set;
}
function deArrayifyContainerItems(json) {
    var items = [];
    var getter = buildPropertyGetter();
    if (json && json.length) {
        for (var _i = 0, json_1 = json; _i < json_1.length; _i++) {
            var i = json_1[_i];
            var func = getter(i, "Function", "string");
            switch (func) {
                case "Separator":
                    items.push({
                        Function: "Separator"
                    });
                    break;
                case "Widget":
                    items.push({
                        Function: "Widget",
                        Widget: getter(i, "Widget", "string")
                    });
                    break;
                case "Flyout":
                    items.push({
                        Function: "Flyout",
                        Label: getter(i, "Label", "string"),
                        Tooltip: getter(i, "Tooltip", "string"),
                        ImageUrl: getter(i, "ImageUrl", "string"),
                        ImageClass: getter(i, "ImageClass", "string"),
                        Item: deArrayifyContainerItems(i.Item || [])
                    });
                    break;
            }
        }
    }
    return items;
}
function deArrayifyContainer(json) {
    var containers = [];
    var getter = buildPropertyGetter();
    for (var _i = 0, json_2 = json; _i < json_2.length; _i++) {
        var c = json_2[_i];
        containers.push({
            Name: getter(c, "Name", "string"),
            Type: getter(c, "Type", "string"),
            //Position: getter(c, "Position", "string"),
            Extension: deArrayifyExtension(c.Extension),
            Item: deArrayifyContainerItems(c.Item)
        });
    }
    return containers;
}
function deArrayifyWidgets(json) {
    var widgets = [];
    for (var _i = 0, json_3 = json; _i < json_3.length; _i++) {
        var w = json_3[_i];
        if (w["@xsi:type"] == "UiWidgetType") {
            var uiw = deArrayifyUiWidget(w);
            widgets.push(uiw);
        }
        else {
            widgets.push(deArrayifyWidget(w));
        }
    }
    return widgets;
}
function deArrayifyWidget(json) {
    var root = json;
    if (root == null) {
        throw new error_1.MgError("Malformed input. Expected Widget element");
    }
    var getter = buildPropertyGetter();
    var w = {
        WidgetType: getter(root, "@xsi:type", "string"),
        Name: getter(root, "Name", "string"),
        Type: getter(root, "Type", "string"),
        //Location: getter(root, "Location", "string"),
        Extension: deArrayifyExtension(root.Extension)
    };
    return w;
}
function deArrayifyExtension(json, arrayCheck) {
    if (arrayCheck === void 0) { arrayCheck = true; }
    var root = json;
    if (root == null) {
        return null;
    }
    if (arrayCheck && root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected Extension element");
    }
    var getter = buildPropertyGetter();
    var ext = {};
    for (var key in root[0]) {
        if (Array.isArray(root[0][key])) {
            //Special case handling
            switch (key) {
                case "AdditionalParameter":
                    {
                        var params = [];
                        for (var _i = 0, _a = root[0][key]; _i < _a.length; _i++) {
                            var p = _a[_i];
                            params.push({
                                Key: getter(p, "Key", "string"),
                                Value: getter(p, "Value", "string")
                            });
                        }
                        ext[key] = params;
                    }
                    break;
                case "Projection":
                    {
                        ext[key] = root[0][key];
                    }
                    break;
                default:
                    ext[key] = getter(root[0], key, "string");
                    break;
            }
        }
        else {
            ext[key] = deArrayifyExtension(root[0][key], false);
        }
    }
    return ext;
}
function deArrayifyUiWidget(json) {
    var root = json;
    if (root == null) {
        throw new error_1.MgError("Malformed input. Expected Widget element");
    }
    var getter = buildPropertyGetter();
    var w = {
        WidgetType: getter(root, "@xsi:type", "string"),
        ImageUrl: getter(root, "ImageUrl", "string"),
        ImageClass: getter(root, "ImageClass", "string"),
        Label: getter(root, "Label", "string"),
        Tooltip: getter(root, "Tooltip", "string"),
        StatusText: getter(root, "StatusText", "string"),
        Disabled: getter(root, "Disabled", "boolean"),
        Name: getter(root, "Name", "string"),
        Type: getter(root, "Type", "string"),
        //Location: getter(root, "Location", "string"),
        Extension: deArrayifyExtension(root.Extension)
    };
    return w;
}
function deArrayifyMapWidget(json) {
    var root = json;
    if (root == null || root.length != 1) {
        throw new error_1.MgError("Malformed input. Expected MapWidget element");
    }
    var getter = buildPropertyGetter();
    var mw = {
        WidgetType: getter(root, "@xsi:type", "string"),
        MapId: getter(root, "MapId", "string"),
        Name: getter(root, "Name", "string"),
        Type: getter(root, "Type", "string"),
        //Location: getter(root, "Location", "string"),
        Extension: deArrayifyExtension(root.Extension)
    };
    return mw;
}
function deArrayifyWidgetSet(json) {
    var widgetSet = [];
    for (var _i = 0, json_4 = json; _i < json_4.length; _i++) {
        var ws = json_4[_i];
        widgetSet.push({
            Container: deArrayifyContainer(ws.Container),
            MapWidget: deArrayifyMapWidget(ws.MapWidget),
            Widget: deArrayifyWidgets(ws.Widget)
        });
    }
    return widgetSet;
}
function deArrayifyFlexibleLayout(json) {
    var root = json;
    var getter = buildPropertyGetter();
    var resp = {
        Title: getter(root, "Title"),
        TemplateUrl: getter(root, "TemplateUrl"),
        MapSet: deArrayifyMapSet(root.MapSet),
        WidgetSet: deArrayifyWidgetSet(root.WidgetSet),
        Extension: deArrayifyExtension(root.Extension)
    };
    return resp;
}
function deArrayifyMapDefinitionGroups(json) {
    var groups = [];
    var getter = buildPropertyGetter();
    for (var _i = 0, json_5 = json; _i < json_5.length; _i++) {
        var g = json_5[_i];
        groups.push({
            Name: getter(g, "Name"),
            ExpandInLegend: getter(g, "ExpandInLegend", "boolean"),
            ShowInLegend: getter(g, "ShowInLegend", "boolean"),
            Visible: getter(g, "Visible", "boolean"),
            LegendLabel: getter(g, "LegendLabel"),
            Group: getter(g, "Group")
        });
    }
    return groups;
}
function deArrayifyMapDefinitionLayers(json) {
    var layers = [];
    var getter = buildPropertyGetter();
    for (var _i = 0, json_6 = json; _i < json_6.length; _i++) {
        var g = json_6[_i];
        layers.push({
            Name: getter(g, "Name"),
            ResourceId: getter(g, "ResourceId"),
            ExpandInLegend: getter(g, "ExpandInLegend", "boolean"),
            ShowInLegend: getter(g, "ShowInLegend", "boolean"),
            Selectable: getter(g, "Selectable", "boolean"),
            Visible: getter(g, "Visible", "boolean"),
            LegendLabel: getter(g, "LegendLabel"),
            Group: getter(g, "Group"),
        });
    }
    return layers;
}
function deArrayifyMapDefinition(json) {
    var _a, _b;
    var root = json;
    var getter = buildPropertyGetter();
    var eGetter = buildPropertyGetter();
    var resp = {
        BackgroundColor: getter(root, "BackgroundColor"),
        CoordinateSystem: getter(root, "CoordinateSystem"),
        Extents: {
            MinX: eGetter(root.Extents[0], "MinX", "float"),
            MinY: eGetter(root.Extents[0], "MinY", "float"),
            MaxX: eGetter(root.Extents[0], "MaxX", "float"),
            MaxY: eGetter(root.Extents[0], "MaxY", "float")
        },
        MapLayer: deArrayifyMapDefinitionLayers((_a = root.MapLayer) !== null && _a !== void 0 ? _a : []),
        MapLayerGroup: deArrayifyMapDefinitionGroups((_b = root.MapLayerGroup) !== null && _b !== void 0 ? _b : [])
    };
    if (root.TileSetSource) {
        var tGetter = buildPropertyGetter();
        resp.TileSetSource = {
            ResourceId: tGetter(root.TileSetSource, "ResourceId")
        };
    }
    return resp;
}
function deArrayifyTileSetDefinitionLayers(json) {
    var getter = buildPropertyGetter();
    var layers = [];
    for (var _i = 0, json_7 = json; _i < json_7.length; _i++) {
        var l = json_7[_i];
        layers.push({
            Name: getter(l, "Name"),
            ResourceId: getter(l, "ResourceId"),
            Selectable: getter(l, "Selectable", "boolean"),
            ShowInLegend: getter(l, "ShowInLegend", "boolean"),
            LegendLabel: getter(l, "LegendLabel"),
            ExpandInLegend: getter(l, "ExpandInLegend", "boolean")
        });
    }
    return layers;
}
function deArrayifyTileSetDefinitionGroups(json) {
    var getter = buildPropertyGetter();
    var groups = [];
    for (var _i = 0, json_8 = json; _i < json_8.length; _i++) {
        var g = json_8[_i];
        groups.push({
            Name: getter(g, "Name"),
            Visible: getter(g, "Visible", "boolean"),
            ShowInLegend: getter(g, "ShowInLegend", "boolean"),
            ExpandInLegend: getter(g, "ExpandInLegend", "boolean"),
            LegendLabel: getter(g, "LegendLabel"),
            BaseMapLayer: deArrayifyTileSetDefinitionLayers(g.BaseMapLayer)
        });
    }
    return groups;
}
function deArrayifyTileSetDefinitionParamList(root) {
    var getter = buildPropertyGetter();
    var params = [];
    for (var _i = 0, root_2 = root; _i < root_2.length; _i++) {
        var p = root_2[_i];
        params.push({
            Name: getter(p, "Name"),
            Value: getter(p, "Value")
        });
    }
    return params;
}
function deArrayifyTileSetDefinitionParams(root) {
    var getter = buildPropertyGetter();
    var tsp = {
        TileProvider: getter(root, "TileProvider"),
        Parameter: deArrayifyTileSetDefinitionParamList(root[0].Parameter)
    };
    return tsp;
}
function deArrayifyTileSetDefinition(json) {
    var root = json;
    var eGetter = buildPropertyGetter();
    var resp = {
        Extents: {
            MinX: eGetter(root.Extents[0], "MinX", "float"),
            MinY: eGetter(root.Extents[0], "MinY", "float"),
            MaxX: eGetter(root.Extents[0], "MaxX", "float"),
            MaxY: eGetter(root.Extents[0], "MaxY", "float")
        },
        TileStoreParameters: deArrayifyTileSetDefinitionParams(json.TileStoreParameters),
        BaseMapLayerGroup: deArrayifyTileSetDefinitionGroups(json.BaseMapLayerGroup)
    };
    return resp;
}
/**
 * Indicates if the de-arrayified result is a {@link WebLayout}
 *
 * @since 0.14
 */
function isWebLayout(arg) {
    return arg.CommandSet != null
        && arg.ContextMenu != null
        && arg.Map != null;
}
exports.isWebLayout = isWebLayout;
/**
 * Indicates if the de-arrayified result is an {@link ApplicationDefinition}
 *
 * @since 0.14
 */
function isAppDef(arg) {
    return arg.WidgetSet != null;
}
exports.isAppDef = isAppDef;
/**
 * Indicates if the de-arrayified result is a {@link MapDefinition}
 *
 * @since 0.14
 */
function isMapDef(arg) {
    return arg.Extents != null
        && arg.BackgroundColor != null
        && arg.CoordinateSystem != null
        && arg.MapLayer != null
        && arg.MapLayerGroup != null;
}
exports.isMapDef = isMapDef;
/**
 * Indicates if the de-arrayified result is a {@link TileSetDefinition}
 *
 * @since 0.14
 */
function isTileSet(arg) {
    return arg.Extents != null
        && arg.TileStoreParameters != null
        && arg.BaseMapLayerGroup != null;
}
exports.isTileSet = isTileSet;
/**
 * Indicates if the de-arrayified result is a {@link SiteVersionResponse}
 *
 * @since 0.14
 */
function isSiteVersion(arg) {
    return arg.Version != null;
}
exports.isSiteVersion = isSiteVersion;
/**
 * Indicates if the de-arrayified result is a {@link QueryMapFeaturesResponse}
 *
 * @since 0.14
 */
function isQueryMapFeaturesResponse(arg) {
    return arg.FeatureSet != null
        || arg.Hyperlink != null
        || arg.InlineSelectionImage != null
        || arg.SelectedFeatures != null
        || arg.Tooltip != null;
}
exports.isQueryMapFeaturesResponse = isQueryMapFeaturesResponse;
/**
 * Normalizes the given JSON object to match the content model of its original XML form
 *
 * @export
 * @param {*} json The JSON object to normalize
 * @returns {*} The normalized JSON object
 */
function deArrayify(json) {
    if (json["RuntimeMap"]) {
        return deArrayifyRuntimeMap(json.RuntimeMap);
    }
    if (json["FeatureInformation"]) {
        return deArrayifyFeatureInformation(json.FeatureInformation);
    }
    if (json["WebLayout"]) {
        return deArrayifyWebLayout(json.WebLayout);
    }
    if (json["ApplicationDefinition"]) {
        return deArrayifyFlexibleLayout(json.ApplicationDefinition);
    }
    if (json["MapDefinition"]) {
        return deArrayifyMapDefinition(json.MapDefinition);
    }
    if (json["TileSetDefinition"]) {
        return deArrayifyTileSetDefinition(json.TileSetDefinition);
    }
    if (json["SiteVersion"]) {
        return {
            Version: json.SiteVersion.Version[0]
        };
    }
    var keys = [];
    for (var k in json) {
        keys.push(k);
    }
    throw new error_1.MgError("Unsure how to process JSON response. Root elements are: (".concat(keys.join(", "), ")"));
}
exports.deArrayify = deArrayify;
/**
 * Builds an XML selection string from the given selection set.
 *
 * @export
 * @param {(FeatureSet | undefined)} selection The selection set
 * @param {string[]} [layerIds] If specified, the selection XML will only include selections from the specified layers
 * @returns {string} The selection XML string
 */
function buildSelectionXml(selection, layerIds) {
    var idCount = 0;
    var xml = '<?xml version="1.0" encoding="utf-8"?>';
    xml += '<FeatureSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FeatureSet-1.0.0.xsd">';
    if (selection) {
        var selLayers = selection.Layer;
        for (var _i = 0, selLayers_1 = selLayers; _i < selLayers_1.length; _i++) {
            var layer = selLayers_1[_i];
            var layerId = layer["@id"];
            if (layerIds != null && layerIds.indexOf(layerId) < 0) {
                continue;
            }
            var cls = layer.Class;
            if (cls.ID.length === 0) { // Don't bother writing out empty Layer/Class elements
                continue;
            }
            xml += "<Layer id=\"".concat(layerId, "\">");
            xml += "<Class id=\"".concat(cls["@id"], "\">");
            for (var _a = 0, _b = cls.ID; _a < _b.length; _a++) {
                var id = _b[_a];
                xml += "<ID>".concat(id, "</ID>");
                idCount++;
            }
            xml += '</Class>';
            xml += '</Layer>';
        }
    }
    xml += '</FeatureSet>';
    // If we didn't write any ids, just return an empty string instead
    return idCount > 0 ? xml : '';
}
exports.buildSelectionXml = buildSelectionXml;
/**
 * Can only be used for a v4.0.0 or higher QUERYMAPFEATURES request
 *
 * @param selection Current selection set
 * @param feat The active selected feature
 */
function getActiveSelectedFeatureXml(selection, feat) {
    for (var _i = 0, _a = selection.Layer; _i < _a.length; _i++) {
        var layer = _a[_i];
        var layerId = layer["@id"];
        if (layerId == feat.layerId) {
            var key = feat.selectionKey;
            var xml = '<?xml version="1.0" encoding="utf-8"?>';
            xml += '<FeatureSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FeatureSet-1.0.0.xsd">';
            xml += "<Layer id=\"".concat(layerId, "\">");
            xml += "<Class id=\"".concat(layer.Class["@id"], "\">");
            xml += "<ID>".concat(key, "</ID>");
            xml += '</Class>';
            xml += '</Layer>';
            xml += '</FeatureSet>';
            return xml;
        }
    }
}
exports.getActiveSelectedFeatureXml = getActiveSelectedFeatureXml;
//# sourceMappingURL=deArrayify.js.map