private void AddModelDirectory(VirtualFolderVM parent,
                                       IXQueryable element,
                                       string directoryName,
                                       string xpath,
                                       LocalGameClientPackageIndexer indexer,
                                       bool addVisualNode = true)
        {
            var localPath = element[xpath];

            if (!string.IsNullOrWhiteSpace(localPath))
            {
                var node = new VirtualFolderVM(parent, directoryName);
                parent.AddChild(node);
                TankNodeVM.AddModelNode(node, localPath, indexer, addVisualNode);
            }
        }
        private void AddChassisModelNodes(VirtualFolderVM parent, IXQueryable element)
        {
            var packageIndexer = this.GameClientRoot.Model.PackageIndexer;

            this.AddModelNodes(parent, element);
            var splineDescElement = element.Query("splineDesc");

            if (splineDescElement != null)
            {
                var splineNode = new VirtualFolderVM(parent,
                                                     this.L("game_client_explorer", "spline"));
                parent.AddChild(splineNode);

                TankNodeVM.AddFileNode(splineNode,
                                       splineDescElement,
                                       this.L("game_client_explorer", "left_track"),
                                       "left",
                                       packageIndexer);
                TankNodeVM.AddFileNode(splineNode,
                                       splineDescElement,
                                       this.L("game_client_explorer", "right_track"),
                                       "right",
                                       packageIndexer);
                this.AddModelDirectory(splineNode,
                                       splineDescElement,
                                       this.L("game_client_explorer", "left_segment"),
                                       "segmentModelLeft",
                                       packageIndexer);
                this.AddModelDirectory(splineNode,
                                       splineDescElement,
                                       this.L("game_client_explorer", "right_segment"),
                                       "segmentModelRight",
                                       packageIndexer);
                this.AddModelDirectory(splineNode,
                                       splineDescElement,
                                       this.L("game_client_explorer", "left_segment2"),
                                       "segment2ModelLeft",
                                       packageIndexer);
                this.AddModelDirectory(splineNode,
                                       splineDescElement,
                                       this.L("game_client_explorer", "right_segment2"),
                                       "segment2ModelRight",
                                       packageIndexer);
            }
        }
        private static void AddModelNode(VirtualFolderVM parent, string localPath, LocalGameClientPackageIndexer indexer, bool addVisualNode = true)
        {
            var modelNode = new RemotePackageFileVM(parent,
                                                    indexer.GetPackagePath(localPath),
                                                    localPath,
                                                    Localization.Instance.L("game_client_explorer", "model"));

            parent.AddChild(modelNode);

            if (addVisualNode)
            {
                var    model      = TankNodeVM.LoadXmlFile(indexer.GetUnifiedPath(localPath));
                string visualFile = (model.Query("nodefullVisual") ?? model.Query("nodelessVisual")).Value + ".visual";
                if (!string.IsNullOrEmpty(visualFile))
                {
                    TankNodeVM.AddVisualNode(parent, visualFile, indexer);
                }
            }
        }
        private static void AddVisualNode(VirtualFolderVM parent, string localPath, LocalGameClientPackageIndexer indexer)
        {
            var visualNode = new RemotePackageFileVM(parent,
                                                     indexer.GetPackagePath(localPath),
                                                     localPath,
                                                     Localization.Instance.L("game_client_explorer", "visual"));

            parent.AddChild(visualNode);


            var visual = TankNodeVM.LoadXmlFile(indexer.GetUnifiedPath(localPath));

            foreach (var primitiveGroup in visual.QueryMany("renderSet/geometry/primitiveGroup"))
            {
                var material = primitiveGroup.Query("material");

                var identifier = material["identifier"];
                var groupNode  = new VirtualFolderVM(parent, identifier);
                parent.AddChild(groupNode);

                foreach (var property in material.QueryMany("property"))
                {
                    var    propertyName = (property.ToElement().FirstNode as XText).Value;
                    string displayName;
                    switch (propertyName.Trim())
                    {
                    case "specularMap":
                        displayName = Localization.Instance.L("game_client_explorer", "specular_map");
                        break;

                    case "normalMap":
                        displayName = Localization.Instance.L("game_client_explorer", "normal_map");
                        break;

                    case "diffuseMap":
                        displayName = Localization.Instance.L("game_client_explorer", "diffuse_map");
                        break;

                    case "metallicDetailMap":
                        displayName = Localization.Instance.L("game_client_explorer", "metallic_detail_map");
                        break;

                    case "metallicGlossMap":
                        displayName = Localization.Instance.L("game_client_explorer", "metallic_gloss_map");
                        break;

                    case "excludeMaskMap":
                        displayName = Localization.Instance.L("game_client_explorer", "exclude_mask_map");
                        break;

                    default:
                        if (property.Query("Texture") != null)
                        {
                        }
                        continue;
                    }

                    var textureFile = property["Texture"];
                    if (string.IsNullOrEmpty(textureFile))
                    {
                        continue;
                    }

                    var fileNode = new RemotePackageFileVM(groupNode, indexer.GetPackagePath(textureFile), textureFile, displayName);
                    groupNode.AddChild(fileNode);
                }
            }
        }