private TreeNode CreateLayerNode(MgLayerBase layer)
        {
            var node = new TreeNode();
            node.Name = layer.GetObjectId();
            node.Text = layer.GetLegendLabel();
            node.Checked = layer.GetVisible();
            //node.ContextMenuStrip = _legend.LayerContextMenu;
            var lt = layer.GetLayerType();
            var fsId = layer.GetFeatureSourceId();

            LayerNodeMetadata layerMeta = null;
            if (fsId.EndsWith("DrawingSource")) //NOXLATE
            {
                node.SelectedImageKey = node.ImageKey = IMG_DWF;
                bool bInitiallySelectable = layer.Selectable;
                if (_layers.ContainsKey(layer.GetObjectId()))
                {
                    layerMeta = _layers[layer.GetObjectId()];
                    bInitiallySelectable = layerMeta.WasInitiallySelectable;
                }
                else //If not in the dictionary, assume it is a dynamically added layer
                {
                    layerMeta = new LayerNodeMetadata(layer, bInitiallySelectable);
                    _layers[layer.GetObjectId()] = layerMeta;
                }
                node.Tag = layerMeta;
                node.ToolTipText = string.Format(Strings.DrawingLayerTooltip, Environment.NewLine, layer.Name, layer.FeatureSourceId);
            }
            else //Vector or Grid layer
            {
                var ldfId = layer.LayerDefinition;
                if (_layers.ContainsKey(layer.GetObjectId()))
                {
                    layerMeta = _layers[layer.GetObjectId()];
                }
                else
                {
                    layerMeta = new LayerNodeMetadata(layer, layer.Selectable);
                    _layers[layer.GetObjectId()] = layerMeta;
                }
                if (string.IsNullOrEmpty(layerMeta.LayerDefinitionContent))
                    return null;

                node.Tag = layerMeta;

                const int LAYER_VECTOR = 0;
                const int LAYER_RASTER = 1;
                const int LAYER_DWF = 2;

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(layerMeta.LayerDefinitionContent);
                int type = LAYER_VECTOR;
                XmlNodeList scaleRanges = doc.GetElementsByTagName("VectorScaleRange"); //NOXLATE
                if (scaleRanges.Count == 0)
                {
                    scaleRanges = doc.GetElementsByTagName("GridScaleRange"); //NOXLATE
                    if (scaleRanges.Count == 0)
                    {
                        scaleRanges = doc.GetElementsByTagName("DrawingLayerDefinition"); //NOXLATE
                        if (scaleRanges.Count == 0)
                            return null;
                        type = LAYER_DWF;
                    }
                    else
                        type = LAYER_RASTER;
                }

                String[] typeStyles = new String[] { "PointTypeStyle", "LineTypeStyle", "AreaTypeStyle", "CompositeTypeStyle" }; //NOXLATE
                String[] ruleNames = new String[] { "PointRule", "LineRule", "AreaRule", "CompositeRule" }; //NOXLATE

                node.ToolTipText = string.Format(Strings.DefaultLayerTooltip, Environment.NewLine, layer.Name, layer.FeatureSourceId, layer.FeatureClassName);
                //Do this if not cached already from a previous run
                if (!layerMeta.HasTheme() || !layerMeta.HasDefaultIcons())
                {
                    for (int sc = 0; sc < scaleRanges.Count; sc++)
                    {
                        XmlElement scaleRange = (XmlElement)scaleRanges[sc];
                        XmlNodeList minElt = scaleRange.GetElementsByTagName("MinScale"); //NOXLATE
                        XmlNodeList maxElt = scaleRange.GetElementsByTagName("MaxScale"); //NOXLATE
                        String minScale, maxScale;
                        minScale = "0"; //NOXLATE
                        maxScale = "1000000000000.0";  //NOXLATE  // as MDF's VectorScaleRange::MAX_MAP_SCALE
                        if (minElt.Count > 0)
                            minScale = minElt[0].ChildNodes[0].Value;
                        if (maxElt.Count > 0)
                            maxScale = maxElt[0].ChildNodes[0].Value;

                        if (type != LAYER_VECTOR)
                            break;

                        if (!LayerNodeMetadata.ScaleIsApplicable(_map.ViewScale, minScale, maxScale))
                            continue;

                        bool bComposite = false;

                        //Check TS count. Give precedence to composite type styles
                        List<XmlNode> typeStyleCol = new List<XmlNode>();
                        XmlNodeList styleNodes = scaleRange.GetElementsByTagName(typeStyles[3]);
                        List<RuleData> rules = new List<RuleData>();
                        if (styleNodes.Count > 0)
                        {
                            foreach (XmlNode n in styleNodes)
                            {
                                // We will check if this typestyle is going to be shown in the legend
                                XmlNodeList showInLegend = ((XmlElement)n).GetElementsByTagName("ShowInLegend"); //NOXLATE
                                if (showInLegend.Count > 0)
                                    if (!bool.Parse(showInLegend[0].ChildNodes[0].Value))
                                        continue;   // This typestyle does not need to be shown in the legend

                                typeStyleCol.Add(n);

                                var ruleData = new RuleData();
                                ruleData.GeomType = 3;
                                ruleData.RuleNodes = ((XmlElement)n).GetElementsByTagName(ruleNames[3]);
                                if (ruleData.RuleNodes.Count > 0)
                                    rules.Add(ruleData);
                            }

                            bComposite = true;
                        }
                        else
                        {
                            for (int t = 0; t < 3; t++)
                            {
                                styleNodes = scaleRange.GetElementsByTagName(typeStyles[t]);
                                foreach (XmlNode n in styleNodes)
                                {
                                    // We will check if this typestyle is going to be shown in the legend
                                    XmlNodeList showInLegend = ((XmlElement)n).GetElementsByTagName("ShowInLegend"); //NOXLATE
                                    if (showInLegend.Count > 0)
                                        if (!bool.Parse(showInLegend[0].ChildNodes[0].Value))
                                            continue;   // This typestyle does not need to be shown in the legend

                                    typeStyleCol.Add(n);

                                    var ruleData = new RuleData();
                                    ruleData.GeomType = t;
                                    ruleData.RuleNodes = ((XmlElement)n).GetElementsByTagName(ruleNames[t]);
                                    if (ruleData.RuleNodes.Count > 0)
                                        rules.Add(ruleData);
                                }
                            }
                        }

                        //No type styles. Skip
                        if (typeStyleCol.Count == 0)
                            continue;

                        //Determine if this is themed or not
                        int nTotalRules = 0;
                        foreach(RuleData r in rules)
                        {
                            nTotalRules += r.RuleNodes.Count;
                        }
                        bool bThemed = nTotalRules > 1;
                        if (bThemed)
                        {
                            int catIndex = 0;
                            for (int i = 0; i < rules.Count; i++)
                            {
                                RuleData theRule = rules[i];
                                ThemeCategory themeCat = new ThemeCategory()
                                {
                                    MinScale = minScale,
                                    MaxScale = maxScale,
                                    GeometryType = theRule.GeomType
                                };

                                //Non-composite styles must be processed once
                                if (layerMeta.CategoryExists(themeCat) && theRule.GeomType != 3)
                                    continue;

                                layerMeta.SetDefaultIcon(themeCat, Properties.Resources.lc_theme);
                                node.ToolTipText = string.Format(Strings.ThemedLayerTooltip, Environment.NewLine, layer.Name, layer.FeatureSourceId, layer.FeatureClassName, nTotalRules);

                                if (_legend.ThemeCompressionLimit > 0 && theRule.RuleNodes.Count > _legend.ThemeCompressionLimit)
                                {
                                    AddThemeRuleNode(layerMeta, themeCat, node, theRule.GeomType, catIndex, theRule.RuleNodes, 0);
                                    node.Nodes.Add(CreateCompressedThemeNode(layerMeta, themeCat, theRule.RuleNodes.Count - 2));
                                    AddThemeRuleNode(layerMeta, themeCat, node, theRule.GeomType, (catIndex + (theRule.RuleNodes.Count - 1)), theRule.RuleNodes, theRule.RuleNodes.Count - 1);
                                }
                                else
                                {
                                    for (int r = 0; r < theRule.RuleNodes.Count; r++)
                                    {
                                        AddThemeRuleNode(layerMeta, themeCat, node, theRule.GeomType, (catIndex + r), theRule.RuleNodes, r);
                                    }
                                }
                                //Only bump catIndex if composite, as category indexes for composite styles are handled differently
                                if (bComposite)
                                    catIndex += theRule.RuleNodes.Count;
                            }
                        }
                        else
                        {
                            Trace.Assert(rules.Count == 1);
                            Trace.Assert(rules[0].RuleNodes.Count == 1);
                            RuleData theRule = rules[0];

                            ThemeCategory themeCat = new ThemeCategory()
                            {
                                MinScale = minScale,
                                MaxScale = maxScale,
                                GeometryType = theRule.GeomType
                            };

                            if (layerMeta.CategoryExists(themeCat))
                                continue;

                            if (LayerNodeMetadata.ScaleIsApplicable(_map.ViewScale, themeCat))
                            {
                                if (!layerMeta.HasDefaultIconsAt(_map.ViewScale))
                                {
                                    try
                                    {
                                        MgByteReader layerIcon = _provider.GenerateLegendImage(layer.LayerDefinition,
                                                                                               _map.ViewScale,
                                                                                               16,
                                                                                               16,
                                                                                               "PNG", //NOXLATE
                                                                                               (theRule.GeomType+1),
                                                                                               -1);
                                        legendCallCount++;
                                        if (layerIcon != null)
                                        {
                                            try
                                            {
                                                byte[] b = new byte[layerIcon.GetLength()];
                                                layerIcon.Read(b, b.Length);
                                                using (var ms = new MemoryStream(b))
                                                {
                                                    layerMeta.SetDefaultIcon(themeCat, Image.FromStream(ms));
                                                    node.ToolTipText = string.Format(Strings.DefaultLayerTooltip, Environment.NewLine, layer.Name, layer.FeatureSourceId, layer.FeatureClassName);
                                                }
                                            }
                                            finally
                                            {
                                                layerIcon.Dispose();
                                            }
                                        }
                                        else
                                        {
                                            layerMeta.SetDefaultIcon(themeCat, Properties.Resources.lc_broken);
                                        }
                                    }
                                    catch
                                    {
                                        layerMeta.SetDefaultIcon(themeCat, Properties.Resources.lc_broken);
                                    }
                                }
                            }
                        }
                    }
                }
                else //Already cached
                {
                    Trace.TraceInformation("Icons already cached for: " + layer.Name); //NOXLATE
                    node.Nodes.AddRange(layerMeta.CreateThemeNodesFromCachedMetadata(_map.ViewScale));
                }
            }

            return node;
        }
 private TreeNode CreateCompressedThemeNode(LayerNodeMetadata layer, ThemeCategory cat, int count)
 {
     TreeNode node = new TreeNode();
     node.Text = string.Format(Strings.CountOtherStyles, count);
     node.ImageKey = node.SelectedImageKey = IMG_OTHER;
     var meta = new LayerThemeNodeMetadata(true, Properties.Resources.icon_etc, node.Text);
     node.Tag = meta;
     layer.AddThemeNode(cat, meta);
     return node;
 }
        private TreeNode CreateThemeRuleNode(LayerNodeMetadata layer, ThemeCategory themeCat, double viewScale, string labelText, int geomType, int categoryIndex)
        {
            MgLayerBase lyr = layer.Layer;
            MgByteReader icon = _provider.GenerateLegendImage(lyr.LayerDefinition,
                                                              viewScale,
                                                              16,
                                                              16,
                                                              "PNG", //NOXLATE
                                                              geomType,
                                                              categoryIndex);
            legendCallCount++;
            TreeNode node = new TreeNode();
            node.Text = labelText;
            if (icon != null)
            {
                try
                {

                    byte[] b = new byte[icon.GetLength()];
                    icon.Read(b, b.Length);
                    using (var ms = new MemoryStream(b))
                    {
                        var tag = new LayerThemeNodeMetadata(false, Image.FromStream(ms), labelText);
                        layer.AddThemeNode(themeCat, tag);
                        node.Tag = tag;
                    }
                }
                finally
                {
                    icon.Dispose();
                }
            }
            return node;
        }
        private void AddThemeRuleNode(LayerNodeMetadata layerMeta, ThemeCategory themeCat, TreeNode node, int geomType, int catIndex, XmlNodeList rules, int ruleOffset)
        {
            XmlElement rule = (XmlElement)rules[ruleOffset];
            XmlNodeList label = rule.GetElementsByTagName("LegendLabel"); //NOXLATE
            XmlNodeList filter = rule.GetElementsByTagName("Filter"); //NOXLATE

            String labelText = string.Empty;
            if (label != null && label.Count > 0 && label[0].ChildNodes.Count > 0)
                labelText = label[0].ChildNodes[0].Value;
            //String filterText = "";
            //if (filter != null && filter.Count > 0 && filter[0].ChildNodes.Count > 0)
            //    filterText = filter[0].ChildNodes[0].Value;

            var child = CreateThemeRuleNode(layerMeta, themeCat, _map.ViewScale, labelText, (geomType + 1), catIndex);
            node.Nodes.Add(child);
        }