using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HaloPlugins.H2.Xbox;

namespace HaloPlugins.Xbox
{
    public class sbsp : TagDefinition
    {
       public sbsp() : base("sbsp", "scenario_structure_bsp", 588, new BspDefinition())
       {
           Fields.AddRange(new IMetaNode[] {
           new Value("BSP Meta Size", typeof(int)),
           new Value("BSP Meta Offset", typeof(int)),
           new Value("Lightmap Raw Meta Offset", typeof(int)),
           new TagReference("sbsp", "sbsp"),
           new Value("Unknown", typeof(int)),
           new Value("Unknown", typeof(int)),
           new TagBlock("Collision Materials", 20, 512, new IMetaNode[] { 
               new TagReference("Unused", "shad"),
               new Padding(4),
               new TagReference("Shader", "shad"),
           }),
           new TagBlock("Collision Bsp", 68, 1, new IMetaNode[] { 
               new TagBlock("3D Nodes", 8, 131072, new IMetaNode[] { //8
                   new Value("Plane", typeof(short)),
                   new Value("Back child", typeof(short)),
                   new Value("Flag/padding/Unknown", typeof(byte)),
                   new Value("Front Child", typeof(short)),
                   new Value("Flag/padding/Unknown2", typeof(byte)),
               }),
               new TagBlock("Planes", 16, 65536, 16, new IMetaNode[] { 
                   new Value("Plane i", typeof(float)),
                   new Value("Plane j", typeof(float)),
                   new Value("Plane k", typeof(float)),
                   new Value("Plane d", typeof(float)),
               }),
               new TagBlock("Leaves", 4, 65536, new IMetaNode[] { 
                   new Flags("Flags", new string[] { "Contains_Double-Sided_Surfaces" }, 8),
                   new Value("BSP 2D Reference Count", typeof(byte)),
                   new Value("First BSP 2D Reference", typeof(short)),
               }),
               new TagBlock("BSP 2D Refrences", 4, 131072, new IMetaNode[] { 
                   new Value("Plane", typeof(short)),
                   new Value("BSP 2D Node", typeof(short)),
               }),
               new TagBlock("BSP2D Nodes", 16, 131072, 16, new IMetaNode[] { 
                   new Value("Plane i", typeof(float)),
                   new Value("Plane j", typeof(float)),
                   new Value("Plane d", typeof(float)),
                   new Value("Left Child", typeof(short)),
                   new Value("Right Child", typeof(short)),
               }),
               new TagBlock("Surfaces", 8, 131072, new IMetaNode[] { 
                   new Value("Plane", typeof(short)),
                   new Value("First Edge", typeof(short)),
                   new Flags("Flags", new string[] { "Two-Sided", "Invisible", "Climable", "Breakable", "Invaild", "Conveyor" }, 8),
                   new Value("Breakable Surface #", typeof(byte)),
                   new Value("Material #", typeof(short)),
               }),
               new TagBlock("Edges", 12, 262144, new IMetaNode[] { 
                   new Value("Start Vertex", typeof(short)),
                   new Value("End Vertex", typeof(short)),
                   new Value("Forward Edge", typeof(short)),
                   new Value("Backward Edge", typeof(short)),
                   new Value("Left Surface", typeof(short)),
                   new Value("Right Surface", typeof(short)),
               }),
               new TagBlock("Collsion Model", 16, 131072, 16, new IMetaNode[] { 
                   new Value("Point X", typeof(float)),
                   new Value("Point Y", typeof(float)),
                   new Value("Point Z", typeof(float)),
                   new Value("First Edge", typeof(short)),
                   new Padding(2),
               }),
               new Value("Unknown", typeof(float)),
           }),
           new Value("Vehicle Floor", typeof(float)),
           new Value("Vehicle Ceiling", typeof(float)),
           new Padding(8),
           new TagBlock("Leaves", 8, 65536, new IMetaNode[] { 
               new Value("Cluster", typeof(short)),
               new Value("Surface Count", typeof(short)),
               new Value("Surface refrence", typeof(int)),
           }),
           new Value("World Bounds X", typeof(float)),
           new Value("...To", typeof(float)),
           new Value("World Bounds Y", typeof(float)),
           new Value("...To", typeof(float)),
           new Value("World Bounds Z", typeof(float)),
           new Value("...To", typeof(float)),
           new TagBlock("Surface References", 8, 262144, new IMetaNode[] { 
               new Value("Strip Index", typeof(short)),
               new Value("Lightmap Triangle Index", typeof(short)),
               new Value("BSP Node Index", typeof(int)),
           }),
           new TagBlock("Cluster Data", 1, -1, new IMetaNode[] { 
               new Value("Data", typeof(byte)),
           }),
           new TagBlock("Cluster Portals", 36, 512, 16, new IMetaNode[] { //16
               new Value("Back Cluster", typeof(short)),
               new Value("Front Cluster", typeof(short)),
               new Value("Plane Index", typeof(int)),
               new Value("Centroid X", typeof(float)),
               new Value("Centroid Y", typeof(float)),
               new Value("Centroid Z", typeof(float)),
               new Value("Bounding Radius", typeof(float)),
               new Flags("Flags", new string[] { "AI_Cannot_Hear_Through_This", "One-Way", "Door", "No-Way", "One-Way_Reversed", "No_One_Can_Hear_Through_This" }, 32),
               new TagBlock("Vertices", 12, 16, new IMetaNode[] { 
                   new Value("X", typeof(float)),
                   new Value("Y", typeof(float)),
                   new Value("Z", typeof(float)),
               }),
           }),
           new TagBlock("Fog Planes", 24, 127, 16, new IMetaNode[] { //16
               new Value("Scenario Planar Fog Index", typeof(short)),
               new Value("Plane i", typeof(float)),
               new Value("Plane j", typeof(float)),
               new Value("Plane k", typeof(float)),
               new Value("Plane d", typeof(float)),
               new Flags("Flags", new string[] { "Extend_Infinitely_While_Visible", "Do_Not_Floodfill", "Aggressive_Floodfill" }, 32),
               new Value("Priority", typeof(short)),
           }),
           new Padding(24),
           new TagBlock("Weather Pallete", 120, 32, 16, new IMetaNode[] { //16
               new ShortString("Name", StringType.Asci),
               new TagReference("Weather_System", "weat"),
               new Padding(36),
               new TagReference("Wind", "wind"),
               new Value("Wind Direction i", typeof(float)),
               new Value("Wind Direction j", typeof(float)),
               new Value("Wind Direction k", typeof(float)),
               new Value("Wind Magnitude", typeof(float)),
               new StringId("Wind Scale Function"),
               new Padding(16),
           }),
           new TagBlock("Weather Polyhedral", 24, 32, 16, new IMetaNode[] { //16
               new Value("Bounding Sphere Center X", typeof(float)),
               new Value("Bounding Sphere Center Y", typeof(float)),
               new Value("Bounding Sphere Center Z", typeof(float)),
               new Value("Bounding Sphere Radius", typeof(float)),
               new TagBlock("Planes", 16, 16, 16, new IMetaNode[] { //16
                   new Value("i", typeof(float)),
                   new Value("j", typeof(float)),
                   new Value("k", typeof(float)),
                   new Value("d", typeof(float)),
               }),
           }),
           new TagBlock("Sound Data", 36, -1, new IMetaNode[] { 
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
           }),
           new TagBlock("Detail Objects", 176, -1, 16, new IMetaNode[] { 
               new Value("Vertice Count", typeof(short)),
               new Value("Face Count", typeof(short)),
               new Value("Total Part Count", typeof(short)),
               new Value("Shadow-Casting Triangle Cour", typeof(short)),
               new Value("Shadow-Casting Part Cour", typeof(short)),
               new Value("Opaque Point Count", typeof(short)),
               new Value("Opaque Vertex Count", typeof(short)),
               new Value("Opaque Part Count", typeof(short)),
               new Value("Opaque Max Nodes/Vertex", typeof(short)),
               new Value("Transparent Mox Nodes/Vertex", typeof(short)),
               new Value("Shadow-Casting Rigid Triangle", typeof(short)),
               new Value("Geometry Classification", typeof(short)),
               new Value("Geometry Compression Flags", typeof(int)),
               new Value("Hardware Node Count", typeof(short)),
               new Value("Node Map Size", typeof(short)),
               new Value("", typeof(short)),
               new Value("Software Plane Count", typeof(short)),
               new Value("Total Subpart Cont", typeof(short)),
               new Flags("Section Lighting Flags", new string[] { "Has_Im_Texcoords", "Has_Im_Inc._Rad.", "Has_Im_Colors", "Has_Im_prt" }, 16),
               new Value("Raw Offset", typeof(int)),
               new Value("Raw Size", typeof(int)),
               new Value("Raw Header Size", typeof(int)),
               new Value("Raw Data Size", typeof(int)),
               new TagBlock("Resources", 16, -1, new IMetaNode[] { 
                   new Value("Unknown", typeof(int)),
                   new Value("Unknown", typeof(int)),
                   new Value("Size", typeof(int)),
                   new Value("Offset", typeof(int)),
               }),
               new TagIndex("Owner_Tag_Section_Offset", "sbsp"),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Max X", typeof(float)),
               new Value("Min X", typeof(float)),
               new Value("Max Y", typeof(float)),
               new Value("Min Y", typeof(float)),
               new Value("Max Z", typeof(float)),
               new Value("Max Z", typeof(float)),
               new Value("Scenario Sky Index", typeof(short)),
               new Value("Media Index", typeof(short)),
               new Value("Scenario Visible Sky Index", typeof(short)),
               new Value("Scenario Atmospheric Fog Index", typeof(short)),
               new Value("Planar Fog Designator", typeof(short)),
               new Value("Visible Fog Plane Index", typeof(short)),
               new Value("Background Sound Index", typeof(short)),
               new Value("Sound Environment Index", typeof(short)),
               new Value("Weather Index", typeof(short)),
               new Value("Transition Structure BSP", typeof(short)),
               new Flags("Flags", new string[] { "One-Way_Portal", "Door_Portal", "Postprocessed_Geometry", "Is_the_Sky" }, 32),
               new TagBlock("Predicted Resources", 8, -1, 16, new IMetaNode[] { //16
                   new Value("Type Enum", typeof(short)),
                   new Value("", typeof(short)),
                   new TagIndex("Resource", "****"),
               }),
               new TagBlock("Portals", 2, -1, 16, new IMetaNode[] { //16
                   new Value("Index", typeof(short)),
               }),
               new Value("Checksum From Structure", typeof(int)),
               new TagBlock("Instanced Geometry References", 2, -1, 16, new IMetaNode[] { //16
                   new Value("Instanced Geometry Index", typeof(short)),
               }),
               new Padding(8),
               new TagBlock("Index Reorder Table", 1, 16, 16, new IMetaNode[] {
                   new Value("Index", typeof(byte)),
               }),
           }),
           new TagBlock("Materials", 32, 1024, new IMetaNode[] { 
               new TagReference("Old_Shader", "shad"),
               new TagReference("Shader", "shad"),
               new TagBlock("Properties", 8, 16, new IMetaNode[] { 
                   new HaloPlugins.Enum("Type", new string[] {  }, 16),
                   new Value("Real Value", typeof(float)),
                   new Padding(2),
               }),
               new Value("Breakable Surface Index", typeof(short)),
               new Padding(6),
           }),
           new TagBlock("Sky Owner Cluster", 2, 32, new IMetaNode[] { 
               new Value("Cluster Owner", typeof(short)),
           }),
           new TagBlock("Conveyor Surfaces", 24, 512, 16, new IMetaNode[] { //16
               new Value("U i", typeof(float)),
               new Value("U j", typeof(float)),
               new Value("U k", typeof(float)),
               new Value("V i", typeof(float)),
               new Value("V j", typeof(float)),
               new Value("V j", typeof(float)),
           }),
           new TagBlock("Breakable Surfaces", 24, 8448, 16, new IMetaNode[] { //16
               new Value("Instanced Geometry Instance", typeof(short)),
               new Value("Breakable Surface Index", typeof(short)),
               new Value("Centroid X", typeof(float)),
               new Value("Centroid Y", typeof(float)),
               new Value("Centroid Z", typeof(float)),
               new Value("Radius", typeof(float)),
               new Value("Collision Surface Index", typeof(int)),
           }),
           new TagBlock("Pathfinding Data", 116, 16, new IMetaNode[] { 
               new TagBlock("Sectors", 8, 65534, new IMetaNode[] { 
                   new Flags("Path-Finding Sector Flags", new string[] { "Sector_Walkable", "Sector_Breakable", "Sector_Mobile", "Sector_BSP_Source", "Floor", "Ceiling", "Wall_North", "Wall_South", "Wall_East", "Wall_West", "Crouchable", "Aligned", "Sector_Step", "Sector_Interior" }, 16),
                   new Value("Hint Index", typeof(short)),
                   new Value("First Link (Do Not Set Manually)", typeof(int)),
               }),
               new TagBlock("Links", 16, 262144, new IMetaNode[] { 
                   new Value("Vertex 1", typeof(short)),
                   new Value("Vertex 2", typeof(short)),
                   new Flags("Link Flags", new string[] { "Sector_Link_from_Collision", "Sector_Intersection_Link", "Sector_Link_BSP_2D_Creation_Error", "Sector_Link_Topology_Error", "Sector_Link_Chain_Error", "Sector_Link_Both_Sectors_Walkable", "Sector_Link_Magic_Hanging_Link", "Sector_Link_Threshold", "Sector_Link_Crouchable", "Sector_Link_Wall_Base", "Sector_Link_Ledge", "Sector_Link_Leanable", "Sector_Link_Start_Corner", "Sector_Link_End_Corner" }, 16),
                   new Value("Hint Index", typeof(short)),
                   new Value("Foward Link", typeof(short)),
                   new Value("Reverse Link", typeof(short)),
                   new Value("Left Sector", typeof(short)),
                   new Value("Right Sector", typeof(short)),
               }),
               new TagBlock("Refs", 4, 131072, new IMetaNode[] { 
                   new Value("Node Ref/Sector Ref", typeof(int)),
               }),
               new TagBlock("BSP 2D Nodes", 20, 131072, 16, new IMetaNode[] { //16
                   new Value("Plane I", typeof(float)),
                   new Value("Plane J", typeof(float)),
                   new Value("Plane D", typeof(float)),
                   new Value("Left Child", typeof(int)),
                   new Value("Right Child", typeof(int)),
               }),
               new Padding(8),
               new TagBlock("Verticies", 12, 65535, 16, new IMetaNode[] { //16
                   new Value("X", typeof(float)),
                   new Value("Y", typeof(float)),
                   new Value("Z", typeof(float)),
               }),
               new TagBlock("Object Refs", 28, 2000, new IMetaNode[] { 
                   new Flags("Flags", new string[] { "Mobile" }, 32),
                   new Value("First Sector", typeof(int)),
                   new Value("Last Sector", typeof(int)),
                   new TagBlock("Bsps", 16, 1024, new IMetaNode[] { 
                       new Value("Bsp Reference", typeof(int)),
                       new Value("First Sector", typeof(int)),
                       new Value("Last Sector", typeof(int)),
                       new Value("Node Index", typeof(int)),
                   }),
                   new TagBlock("Nodes", 4, 255, new IMetaNode[] {
                       new Value("Reference Frame Index", typeof(byte)),
                       new Value("Projection Axis", typeof(byte)),
                       new Flags("Projection Sign", new string[] { "Projection Sign" }, 16),
                   }),
               }),
               new TagBlock("Pathfinding Hints", 20, 32767, new IMetaNode[] { 
                   new HaloPlugins.Enum("Hint Type", new string[] {  }, 16),
                   new Value("Hint Data 0", typeof(short)),
                   new Value("Hint Data 1", typeof(short)),
                   new Value("Hint Data 2", typeof(short)),
                   new Value("Hint Data 3", typeof(short)),
                   new Value("Hint Data 4", typeof(short)),
                   new Value("Hint Data 5", typeof(short)),
                   new Value("Hint Data 6", typeof(short)),
                   new Value("Hint Data 7", typeof(short)),
                   new Padding(2),
               }),
               new TagBlock("Instanced Geometry Refs", 4, 1024, new IMetaNode[] { 
                   new Value("Pathfinding Object Index", typeof(short)),
                   new Value("Unknown", typeof(short)),
               }),
               new Value("Structure Checksum", typeof(int)),
               new Padding(32),
               new TagBlock("User Placed Hints", 72, 1, new IMetaNode[] { 
                   new Padding(16),
                   new TagBlock("Line Segment Geometry", 34, 200, 16,  new IMetaNode[] { //36
                       new Flags("Flags", new string[] { "Bidirectional", "Closed" }, 16),
                       new Value("Part 0 X", typeof(float)),
                       new Value("Part 0 Y", typeof(float)),
                       new Value("Part 0 Z", typeof(float)),
                       new Value("Reference Frame", typeof(int)),
                       new Value("Part 1 X", typeof(float)),
                       new Value("Part 1 Y", typeof(float)),
                       new Value("Part 1 Z", typeof(float)),
                       new Value("Reference Frame", typeof(int)),
                   }),
                   new TagBlock("Parallelogram Geometry", 66, 200, 16, new IMetaNode[] { //68
                       new Flags("Flags", new string[] { "Bidirectional", "Closed" }, 16),
                       new Value("Part 0 X", typeof(float)),
                       new Value("Part 0 Y", typeof(float)),
                       new Value("Part 0 Z", typeof(float)),
                       new Value("Reference Frame", typeof(int)),
                       new Value("Part 1 X", typeof(float)),
                       new Value("Part 1 Y", typeof(float)),
                       new Value("Part 1 Z", typeof(float)),
                       new Value("Reference Frame", typeof(int)),
                       new Value("Part 2 X", typeof(float)),
                       new Value("Part 2 Y", typeof(float)),
                       new Value("Part 2 Z", typeof(float)),
                       new Value("Reference Frame", typeof(int)),
                       new Value("Part 3 X", typeof(float)),
                       new Value("Part 3 Y", typeof(float)),
                       new Value("Part 3 Z", typeof(float)),
                       new Value("Reference Frame", typeof(int)),
                   }),
                   new Padding(8), // Polygon Geometry?
                   new TagBlock("Jump Hints", 8, 200, new IMetaNode[] { 
                       new Flags("Flags", new string[] { "Bidirectional", "Closed" }, 16),
                       new Value("Geometry Index", typeof(short)),
                       new Value("Force Jump Height Enum", typeof(short)),
                       new Flags("Control Flags", new string[] { "Magic_Lift" }, 16),
                   }),
                   new TagBlock("Climb Hints", 4, 200, new IMetaNode[] { 
                       new Flags("Flags", new string[] { "Bidirectional", "Closed" }, 16),
                       new Value("Geometry Index", typeof(short)),
                   }),
                   new Padding(8), // Well Hints
                   new TagBlock("Flight Hints", 8, 50, new IMetaNode[] { 
                       new TagBlock("Points", 12, 10, 16, new IMetaNode[] { //16
                           new Value("i", typeof(float)),
                           new Value("j", typeof(float)),
                           new Value("k", typeof(float)),
                       }),
                   }),
               }),
           }),
           new Padding(8),
           new TagBlock("Background Sound Palette", 100, 64, new IMetaNode[] { 
               new ShortString("Name", StringType.Asci),
               new TagReference("Background_Sound", "lsnd"),
               new TagReference("Inside_Cluster_Sound", "lsnd"),
               new Value("Cutoff Distance", typeof(float)),
               new Flags("Scale Flags", new string[] { "Override_Default_Scale", "Use_Adjacent_Cluster_As_Portal_Scale", "Use_Adjacent_Cluster_As_Exterior_Scale", "Scale_With_Weather_Intensity" }, 32),
               new Value("Interior Scale", typeof(float)),
               new Value("Portal Scale", typeof(float)),
               new Value("Exterior Scale", typeof(float)),
               new Value("Interpolation Speed", typeof(float)),
               new Value("unused?", typeof(int)),
               new Value("unused?", typeof(int)),
               new Value("unused?", typeof(int)),
               new Value("unused?", typeof(int)),
               new Value("unused?", typeof(float)),
               new Value("unused?", typeof(int)),
               new Value("unused?", typeof(int)),
           }),
           new TagBlock("Sound Environment Palette", 72, 64, new IMetaNode[] { 
               new ShortString("Name", StringType.Asci),
               new TagReference("Sound_Environment", "snde"),
               new Value("Cutoff Distance", typeof(float)),
               new Value("Interpolation Speed", typeof(float)),
               new Padding(24),
           }),
           new TagBlock("Sound PAS Data", 1, -1, new IMetaNode[] { 
               new Value("Data", typeof(byte)),
           }),
           new TagBlock("Markers", 60, 1024, 16, new IMetaNode[] { //16
               new ShortString("Name", StringType.Asci),
               new Value("Rotation i", typeof(float)),
               new Value("Rotation j", typeof(float)),
               new Value("Rotation k", typeof(float)),
               new Value("Rotation w", typeof(float)),
               new Value("Position X", typeof(float)),
               new Value("Position Y", typeof(float)),
               new Value("Position Z", typeof(float)),
           }),
           new TagBlock("Runtime Decals", 16, 6144, new IMetaNode[] { 
               new Value("Unknown", typeof(float)),
               new Value("Unknown", typeof(float)),
               new Value("Unknown", typeof(float)),
               new Value("Unknown", typeof(int)),
           }),
           new TagBlock("Environment Object Palette", 20, 100, new IMetaNode[] { 
               new TagReference("Definition", "scen"),
               new TagReference("Model", "mode"),
               new Padding(4),
           }),
           new TagBlock("Environment Objects", 104, 16384, 16, new IMetaNode[] { //16
               new ShortString("Name", StringType.Asci),
               new Value("Rotation i", typeof(float)),
               new Value("Rotation j", typeof(float)),
               new Value("Rotation k", typeof(float)),
               new Value("Rotation w", typeof(float)),
               new Value("X", typeof(float)),
               new Value("Y", typeof(float)),
               new Value("Z", typeof(float)),
               new Value("Palette Index", typeof(short)),
               new Value("Unique ID", typeof(int)),
               new Value("Exported Object Type", typeof(short)),
               new ShortString("Scenario Object Name", StringType.Asci),
               new Padding(4),
           }),
           new Padding(44),
           new TagBlock("Bsp Permutations", 200, 512, new IMetaNode[] { 
               new Value("Total Vertex Count", typeof(short)),
               new Value("Total Triangle count", typeof(short)),
               new Value("Total Part Count", typeof(short)),
               new Value("Shadow-Casting Triangle Count", typeof(short)),
               new Value("Shadow-Casting Part Count", typeof(short)),
               new Value("Opaque Point Count", typeof(short)),
               new Value("Opaque Vertex Count", typeof(short)),
               new Value("Opaque Part Count", typeof(short)),
               new Value("Opaque Max Nodes/Vertex", typeof(short)),
               new Value("Transparent Max Nodes/Vertex", typeof(short)),
               new Value("Shadow-Casting Rigid Triangle", typeof(short)),
               new HaloPlugins.Enum("Geometry Classification", new string[] {  }, 16),
               new TagBlock("Bounding Box", 40, -1, 16, new IMetaNode[] {//16
                   new Value("Min X", typeof(float)),
                   new Value("Max X", typeof(float)),
                   new Value("Min Y", typeof(float)),
                   new Value("Max Y", typeof(float)),
                   new Value("Min Z", typeof(float)),
                   new Value("Max Z", typeof(float)),
                   new Value("Min U", typeof(float)),
                   new Value("Max U", typeof(float)),
                   new Value("Min V", typeof(float)),
                   new Value("Max V", typeof(float)),
           }),
           new Flags("Geometry Compression Flags", new string[] { "Compressed_Postion", "Compressed_Texcoord", "Compressed_Secondary_Texcoord" }, 16),
           new Value("Hardware Node Count", typeof(byte)),
           new Value("Node Map Size", typeof(byte)),
           new Value("Software Plane Count", typeof(byte)),
           new Value("Total Subpart Count", typeof(byte)),
           new Flags("Section Lighting Flags", new string[] { "Has_Im_Texcoords", "Has_Im_Inc._Rad.", "Has_Im_Colors", "Has_Im_Prt" }, 16),
           new Value("Raw Offset", typeof(int)),
           new Value("Raw Size", typeof(int)),
           new Value("Header Size", typeof(int)),
           new Value("Size - Header Size", typeof(int)),
           new TagBlock("Resources", 16, -1, new IMetaNode[] { 
               new HaloPlugins.Enum("Type", new string[] {  }, 32),
               new Value("Primary Locator", typeof(short)),
               new Value("Secondary Locator", typeof(short)),
               new Value("Resource Data Size", typeof(int)),
               new Value("Resource Data Offset", typeof(int)),
           }),
           new TagIndex("Owner Tag Section Offset", "sbsp"),
           new Value("Unknown", typeof(int)),
           new Value("Unknown", typeof(int)),
           new TagBlock("Render Data", 64, -1, new IMetaNode[] { 
               new TagBlock("Parts", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Subparts", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Visibility Bounds", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Raw Vertices", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Strip Indices", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Visibility MOPP Code", 1, -1, new IMetaNode[] { 
                   new Value("Data", typeof(byte)),
               }),
               new TagBlock("MOPP Reorder Table", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Vertex Buffers", 0, -1, new IMetaNode[] { 
               }),
           }),
           new TagBlock("Index Reorder Table", 4, -1, new IMetaNode[] { 
               new Value("Index", typeof(short)),
               new Padding(2),
           }),
           new Value("Checksum", typeof(int)),
           new Value("Bounding Sphere X", typeof(float)),
           new Value("Bounding Sphere Y", typeof(float)),
           new Value("Bounding Sphere Z", typeof(float)),
           new Value("Bounding Sphere Radius", typeof(float)),
           new TagBlock("3D Nodes", 8, -1, 8, new IMetaNode[] { 
               new Value("Plane", typeof(short)),
               new Value("Back child", typeof(short)),
               new Value("Flag/padding/Unknown", typeof(byte)),
               new Value("Front Child", typeof(short)),
               new Value("Flag/padding/Unknown2", typeof(byte)),
           }),
           new TagBlock("Planes", 16, -1, 16, new IMetaNode[] { //16
               new Value("Plane i", typeof(float)),
               new Value("Plane j", typeof(float)),
               new Value("Plane k", typeof(float)),
               new Value("Plane d", typeof(float)),
           }),
           new TagBlock("Leaves", 4, -1, new IMetaNode[] { 
               new Flags("Flags", new string[] { "Contains_Double-Sided_Surfaces" }, 8),
               new Value("BSP 2D Reference Count", typeof(byte)),
               new Value("First BSP 2D Reference", typeof(short)),
           }),
           new TagBlock("BSP 2D References", 4, -1, new IMetaNode[] { //16
               new Value("Plane", typeof(short)),
               new Value("BSP 2D Node", typeof(short)),
           }),
           new TagBlock("BSP 2D Nodes", 16, -1, 16, new IMetaNode[] { //16
               new Value("Plane i", typeof(float)),
               new Value("Plane j", typeof(float)),
               new Value("Plane d", typeof(float)),
               new Value("Left Child", typeof(short)),
               new Value("Right Child", typeof(short)),
           }),
           new TagBlock("Surfaces", 8, -1, 8, new IMetaNode[] { 
               new Value("Plane", typeof(short)),
               new Value("First Edge", typeof(short)),
               new Flags("Flags", new string[] { "Two-Sided", "Invisible", "Climable", "Breakable", "Invaild", "Conveyor" }, 8),
               new Value("Breakable Surface #", typeof(byte)),
               new Value("Material #", typeof(short)),
           }),
           new TagBlock("Edges", 12, -1, new IMetaNode[] { 
               new Value("Start Vertex", typeof(short)),
               new Value("End Vertex", typeof(short)),
               new Value("Forward Edge", typeof(short)),
               new Value("Backward Edge", typeof(short)),
               new Value("Left Surface", typeof(short)),
               new Value("Right Surface", typeof(short)),
           }),
           new TagBlock("Vertices", 16, -1, 16, new IMetaNode[] { //16
               new Value("Point X", typeof(float)),
               new Value("Point Y", typeof(float)),
               new Value("Point Z", typeof(float)),
               new Value("First Edge", typeof(short)),
               new Padding(2),
           }),
           new TagBlock("BSP Physics", 112, 1024, new IMetaNode[] { 
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(float)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(float)),
               new Value("Unknown", typeof(float)),
               new Value("Unknown", typeof(float)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Padding(12),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new TagBlock("MOPP Code Data", 1, -1, 16, new IMetaNode[] { 
                   new Value("Data", typeof(byte)),
               }),
               new Value("Unknown", typeof(int)),
           }),
           new TagBlock("Render Leaves", 8, 65536, new IMetaNode[] { 
               new Value("Cluster", typeof(short)),
               new Value("Surface Reference Count", typeof(short)),
               new Value("First Surface Reference Index", typeof(int)),
           }),
           new TagBlock("Surface References", 8, 262144, new IMetaNode[] { 
               new Value("Strip Index", typeof(short)),
               new Value("Lightmap Triangle", typeof(short)),
               new Value("BSP Node Index", typeof(int)),
           }),
       }),
       new TagBlock("Instanced Geometry Instances", 88, 1024, 16, new IMetaNode[] { //16
           new Value("Scale", typeof(float)),
           new Value("Forward i", typeof(float)),
           new Value("Forward j", typeof(float)),
           new Value("Forward k", typeof(float)),
           new Value("Left i", typeof(float)),
           new Value("Left j", typeof(float)),
           new Value("Left k", typeof(float)),
           new Value("Up i", typeof(float)),
           new Value("Up j", typeof(float)),
           new Value("Up k", typeof(float)),
           new Value("Position X", typeof(float)),
           new Value("Position Y", typeof(float)),
           new Value("Position Z", typeof(float)),
           new Value("Instance Definition #", typeof(short)),
           new Flags("Flags", new string[] { "Not_In_Lightprobes" }, 16),
           new Value("Checksum", typeof(int)),
           new Padding(20),
           new StringId("Name"),
           new HaloPlugins.Enum("Pathfinding Policy", new string[] {  }, 32),//16
       }),
       new TagBlock("Ambience Sound Clusters", 20, 512, new IMetaNode[] { 
           new Padding(4),
           new TagBlock("Enclosing Portal Designators", 4, 512, new IMetaNode[] { 
               new Value("Portal Designator", typeof(short)),
               new Padding(2),
           }),
           new TagBlock("Interior Cluster Indices", 4, 512, new IMetaNode[] { 
               new Value("Interior Cluster Index", typeof(short)),
               new Padding(2),
           }),
       }),
       new TagBlock("Reverb Sound Clusters", 20, 512, new IMetaNode[] { 
           new Padding(4),
           new TagBlock("Enclosing Portal Designators", 4, 512, new IMetaNode[] { 
               new Value("Portal Designator", typeof(short)),
               new Padding(2),
           }),
           new TagBlock("Interior Cluster Indices", 4, 512, new IMetaNode[] { 
               new Value("Interior Cluster Index", typeof(short)),
               new Padding(2),
           }),
       }),
       new TagBlock("Transparent Planes", 20, 32768, 16, new IMetaNode[] { //16
           new Value("Section Index", typeof(short)),
           new Value("Part Index", typeof(short)),
           new Value("Plane i", typeof(float)),
           new Value("Plane j", typeof(float)),
           new Value("Plane k", typeof(float)),
           new Value("Plane d", typeof(float)),
       }),
       new Value("Vehicle Sperical Limit Radius", typeof(float)),
       new Value("Vehicle Sperical Limit X", typeof(float)),
       new Value("Vehicle Sperical Limit Y", typeof(float)),
       new Value("Vehicle Sperical Limit Z", typeof(float)),
       new Padding(96),
       new TagBlock("Debug Info", 88, 1, new IMetaNode[] { 
           new Padding(64),
           new TagBlock("Unknown", 72, 512, new IMetaNode[] { 
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               new Padding(40),
               new TagBlock("Unknown", 4, 32767, new IMetaNode[] {
                   new Padding(4),
               }),
               new TagBlock("Unknown", 4, 32767, new IMetaNode[] {
                   new Padding(4),
               }),
               new Padding(8),
               new TagBlock("Unknown", 4, 32767, new IMetaNode[] {
                   new Padding(4),
               }),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
               //new Value("Unknown", typeof(int)),
           }),
           //new Unused(16),
           new TagBlock("Unknown", 56, 127, new IMetaNode[] {
               new Padding(32),
               new TagBlock("Unknown", 32, 32767, new IMetaNode[] {
                   new Padding(32),
               }),
               new TagBlock("Unknown", 4, 32767, new IMetaNode[] {
                   new Padding(4),
               }),
               new TagBlock("Unknown", 4, 32767, new IMetaNode[] {
                   new Padding(4),
               }),
           }),
           new TagBlock("Unknown", 64, 127, new IMetaNode[] {
               new Padding(32),
               new TagBlock("Unknown", 32, 32767, new IMetaNode[] {
                   new Padding(32),
               }),
               new Padding(8),
               new TagBlock("Unknown", 4, 32767, new IMetaNode[] {
                   new Padding(4),
               }),
               new Padding(8),
           }),
       }),
       new TagReference("Decorators", "DECP"),
       new TagBlock("MOPP Code", 1, -1, 16, new IMetaNode[] { 
           new Value("Data", typeof(byte)),
       }),
       new Padding(4),
       new Value("MOPP Bounds Min X", typeof(float)),
       new Value("MOPP Bounds Min Y", typeof(float)),
       new Value("MOPP Bounds Min Z", typeof(float)),
       new Value("MOPP Bounds Max X", typeof(float)),
       new Value("MOPP Bounds Max Y", typeof(float)),
       new Value("MOPP Bounds Max Z", typeof(float)),
       new TagBlock("MOPP Code", 1, -1, 16, new IMetaNode[] { 
           new Value("Data", typeof(byte)),
       }),
       new TagBlock("Breakable Surface Key Table", 32, -1, 16, new IMetaNode[] { 
           new Value("Instance Geometry Index", typeof(short)),
           new Value("Breakable Surface Index", typeof(short)),
           new Value("Seed Surface Index", typeof(int)),
           new Value("X0", typeof(float)),
           new Value("X1", typeof(float)),
           new Value("Y0", typeof(float)),
           new Value("Y1", typeof(float)),
           new Value("Z0", typeof(float)),
           new Value("Z1", typeof(float)),
       }),
       new TagBlock("Water Definitions", 172, 1, 16, new IMetaNode[] { 
           new TagReference("Shader", "shad"),
           new TagBlock("Section", 64, 1, new IMetaNode[] { 
               new TagBlock("Parts", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Subparts", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Visibility Bounds", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Raw Vertices", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Strip Indices", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Visibility MOPP Code", 1, -1, new IMetaNode[] { 
                   new Value("Data", typeof(byte)),
               }),
               new TagBlock("MOPP Reorder Table", 0, -1, new IMetaNode[] { 
               }),
               new TagBlock("Vertex Buffers", 0, -1, new IMetaNode[] { 
               }),
           }),
           new Value("Block Offset", typeof(int)),
           new Value("Block Size", typeof(int)),
           new Value("Section Data Size", typeof(int)),
           new Value("Resource Data Size", typeof(int)),
           new TagBlock("Resources", 16, -1, new IMetaNode[] { 
               new HaloPlugins.Enum("Type", new string[] {  }, 16),
               new Value("Primary Locator", typeof(short)),
               new Value("Secondary Locator", typeof(short)),
               new Value("Resource Size", typeof(short)),
               new Value("Resource Data Size", typeof(int)),
               new Value("Resource Data Offset", typeof(int)),
           }),
           new Value("Unknown", typeof(int)),
           new Value("Unknown", typeof(int)),
           new TagIndex("Owner Tag Section Offset", "sbsp"),
           //new Value("Unknown", typeof(short)),
           new Value("Sun Spot Color R", typeof(float)),
           new Value("Sun Spot Color G", typeof(float)),
           new Value("Sun Spot Color B", typeof(float)),
           new Value("Reflection Tint R", typeof(float)),
           new Value("Reflection Tint G", typeof(float)),
           new Value("Reflection Tint B", typeof(float)),
           new Value("Refraction Tint R", typeof(float)),
           new Value("Refraction Tint G", typeof(float)),
           new Value("Refraction Tint B", typeof(float)),
           new Value("Horizion Color R", typeof(float)),
           new Value("Horizion Color G", typeof(float)),
           new Value("Horizion Color B", typeof(float)),
           new Value("Sun Specular Power", typeof(float)),
           new Value("Reflection Bump Scale", typeof(float)),
           new Value("Refraction Bump Scale", typeof(float)),
           new Value("Fresnel Scale", typeof(float)),
           new Value("Sun Dir Heading", typeof(float)),
           new Value("Sun Dir Pitch", typeof(float)),
           new Value("FOV", typeof(float)),
           new Value("Aspect", typeof(float)),
           new Value("Height", typeof(float)),
           new Value("Farz", typeof(float)),
           new Value("Rotate Offset", typeof(float)),
           new Value("Center i", typeof(float)),
           new Value("Center j", typeof(float)),
           new Value("Extents i", typeof(float)),
           new Value("Extents j", typeof(float)),
           new Value("Fog Near", typeof(float)),
           new Value("Fog Far", typeof(float)),
           new Value("Dynamic Height Bias", typeof(float)),
       }),
       new TagBlock("Portal - Device Mapping", 16, 1, new IMetaNode[] { 
           new TagBlock("Device Portal Association", 14, 128, new IMetaNode[] { 
               new Value("Unique ID", typeof(int)),
               new Value("Origin BSP Index", typeof(short)),
               new HaloPlugins.Enum("Type", new string[] {  }, 16),
               new Value("First Game Potal Index", typeof(short)),
               new Value("Game Portal Count", typeof(short)),
               new Padding(2),
           }),
           new TagBlock("Game Portal To Portal Map", 4, 128, new IMetaNode[] { 
               new Value("Portal Index", typeof(short)),
               new Padding(2),
           }),
       }),
       new TagBlock("Audibility", 52, 1, new IMetaNode[] { 
           new Value("Door Portal Count", typeof(int)),
           new Value("Cluster Distance Bounds", typeof(float)),
           new Value("...To", typeof(float)),
           new TagBlock("Encoded Door Pas", 4, 4096, new IMetaNode[] { 
               new Value("Unknown", typeof(int)),
           }),
           new TagBlock("Cluster Door Portal Encoded Pas", 4, 2048, new IMetaNode[] { 
               new Value("Unknown", typeof(int)),
           }),
           new TagBlock("AI Deafening Pas", 4, 4088, new IMetaNode[] {
               new Value("Unknown", typeof(int)),
           }),
           // Was 4
           new TagBlock("Cluster Distances", 1, 130816, new IMetaNode[] {
               new Value("Unknown", typeof(byte)),
           }),
           // Was 4
           new TagBlock("Machine Door Mapping", 1, 128, new IMetaNode[] { 
               new Value("Unknown", typeof(byte)),
               //new Value("Machine Door Index", typeof(short)),
               //new Unused(2),
           }),
       }),
       new TagBlock("Object Fake Lightprobes", 92, 2048, 16, new IMetaNode[] { 
           new Value("Unique ID", typeof(int)),
           new Value("Origin BSP Index", typeof(short)),
           new HaloPlugins.Enum("Type", new string[] {  }, 16),
           new HaloPlugins.Enum("Source", new string[] { }, 16),
           new Value("Unknown", typeof(short)),
           new Value("Ambient R", typeof(float)),
           new Value("Ambient G", typeof(float)),
           new Value("Ambient B", typeof(float)),
           new Value("Shadow Direction i", typeof(float)),
           new Value("Shadow Direction j", typeof(float)),
           new Value("Shadow Direction k", typeof(float)),
           new Value("Lighting Accuracy", typeof(float)),
           new Value("Shadow Opacity", typeof(float)),
           new Value("Primary Direction Color R", typeof(float)),
           new Value("Primary Direction Color G", typeof(float)),
           new Value("Primary Direction Color B", typeof(float)),
           new Value("Primary Direction i", typeof(float)),
           new Value("Primary Direction j", typeof(float)),
           new Value("Primary Direction k", typeof(float)),
           new Value("Secondary Direction Color R", typeof(float)),
           new Value("Secondary Direction Color G", typeof(float)),
           new Value("Secondary Direction Color B", typeof(float)),
           new Value("Secondary Direction i", typeof(float)),
           new Value("Secondary Direction j", typeof(float)),
           new Value("Secondary Direction k", typeof(float)),
       }),
       new TagBlock("Decorators", 48, 1, 16, new IMetaNode[] { 
           new Value("Grid Origin X", typeof(float)),
           new Value("Grid Origin Y", typeof(float)),
           new Value("Grid Origin Z", typeof(float)),
           new Value("Cell Count Per Dimension", typeof(float)),
           new TagBlock("Cache Blocks", 44, 4096, new IMetaNode[] { 
               new Value("Block Offset", typeof(int)), // uint
               new Value("Block Size", typeof(int)), // uint
               new Value("Section Data Size", typeof(uint)),
               new Value("Resource Data Size", typeof(uint)),
               new TagBlock("Resources", 16, -1, new IMetaNode[] { 
                   new HaloPlugins.Enum("Type", new string[] {  }, 32),
                   new Value("Primary Locator", typeof(short)),
                   new Value("Secondary Locator", typeof(short)),
                   new Value("Resource Data Size", typeof(uint)),
                   new Value("Resource Data Offset", typeof(uint)),
               }),
               new TagIndex("Owner Tag Section Offset", "sbsp"),
               new Value("Unknown", typeof(int)),
               new Value("Unknown", typeof(int)),
               new TagBlock("Cache Block Data", 40, 1, new IMetaNode[] { 
                   new TagBlock("Placements", 0, 32768, new IMetaNode[] { 
                   }),
                   new TagBlock("Decal Vertices", 0, -1, new IMetaNode[] { 
                   }),
                   new TagBlock("Decal Indices", 0, -1, new IMetaNode[] { 
                   }),
                   new TagBlock("Sprite Vertices", 0, -1, new IMetaNode[] { 
                   }),
                   new TagBlock("Sprite Indices", 0, -1, new IMetaNode[] { 
                   }),
               }),
           }),
           new TagBlock("Groups", 24, 131072, new IMetaNode[] { 
               new Value("Decorator Set", typeof(short)),
               new HaloPlugins.Enum("Decorator Type", new string[] { "Model", "Floating_Decal", "Projected_Decal", "Screen_Facing_Quad", "Axis_Rotating_Quad", "Cross_Quad" }, 32),
               new Value("Shader Index", typeof(short)),
               new Value("Compressed Radius", typeof(short)),
               new Value("Cluster", typeof(short)),
               new Value("Cache Block #", typeof(short)),
               new Value("Decorator Start Index", typeof(byte)),
               new Value("Decorator Count", typeof(byte)),
               new Value("Vertex Start Offset", typeof(byte)),
               new Value("Vertex Count", typeof(byte)),
               new Value("Index Start Offset", typeof(byte)),
               new Value("Index Count", typeof(byte)),
               new Value("Compressed Bounding Center", typeof(float)),
           }),
           new TagBlock("Cells", 24, 65535, new IMetaNode[] { 
               new Value("Child Index", typeof(short)),
               new Value("Child Index", typeof(short)),
               new Value("Child Index", typeof(short)),
               new Value("Child Index", typeof(short)),
               new Value("Child Index", typeof(short)),
               new Value("Child Index", typeof(short)),
               new Value("Child Index", typeof(short)),
               new Value("Child Index", typeof(short)),
               new Value("Cache Block Index", typeof(short)),
               new Value("Group Count", typeof(short)),
               new Value("Group Start Index", typeof(int)),
           }),
           new TagBlock("Decals", 68, 32768, 16, new IMetaNode[] { 
               new Value("Decorator Set", typeof(short)),
               new Value("Decorator Class", typeof(short)),
               new Value("Decorator Permutation", typeof(short)),
               new Value("Sprite Index", typeof(short)),
               new Value("Position X", typeof(float)),
               new Value("Position Y", typeof(float)),
               new Value("Position Z", typeof(float)),
               new Value("Left i", typeof(float)),
               new Value("Left j", typeof(float)),
               new Value("Left k", typeof(float)),
               new Value("Up i", typeof(float)),
               new Value("Up j", typeof(float)),
               new Value("Up k", typeof(float)),
               new Value("Extents i", typeof(float)),
               new Value("Extents j", typeof(float)),
               new Value("Extents k", typeof(float)),
               new Value("Previous Position X", typeof(float)),
               new Value("Previous Position Y", typeof(float)),
               new Value("Previous Position Z", typeof(float)),
           }),
       }),
       });
   }
    }
}
