public void SaveFields(Chunk chunk)
        {
            foreach (ElementProperty prop in chunk.Fields)
            {
                var control = ControlBase.Controls.Find(prop.Name, false);

                switch (prop.Type)
                {
                    case FieldType.Byte:
                        NumericUpDown byteControl = (NumericUpDown)control[0];
                        prop.Data = (byte)byteControl.Value;
                        break;
                    case FieldType.Short:
                        NumericUpDown shortControl = (NumericUpDown)control[0];
                        prop.Data = (short)shortControl.Value;
                        break;
                    case FieldType.Integer:
                        NumericUpDown intControl = (NumericUpDown)control[0];
                        prop.Data = (int)intControl.Value;
                        break;
                    case FieldType.Float:
                        NumericUpDown floatControl = (NumericUpDown)control[0];
                        prop.Data = Convert.ToSingle(floatControl.Value);
                        break;
                    case FieldType.Vector2:
                        //prop.Data = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                        break;
                    case FieldType.Vector3:
                        SavePosition(prop);
                        chunk.Position = (Vector3)prop.Data;
                        break;
                    case FieldType.String:
                        TextBox box = (TextBox)control[0];
                        prop.Data = (string)box.Text;
                        break;
                    case FieldType.ListByte:
                        break;
                }
            }
        }
        public void FillGeneral(Chunk chunk)
        {
            foreach (ElementProperty prop in chunk.Fields)
            {
                if (prop.Name == "Position")
                {
                    FillVec3(prop);
                }

                var control = ControlBase.Controls.Find(prop.Name, false);

                switch (prop.Type)
                {
                    case FieldType.Byte:
                        NumericUpDown byteControl = (NumericUpDown)control[0];
                        byteControl.Value = (byte)prop.Data;
                        break;
                    case FieldType.Short:
                        NumericUpDown shortControl = (NumericUpDown)control[0];
                        shortControl.Value = (short)prop.Data;
                        break;
                    case FieldType.Integer:
                        NumericUpDown intControl = (NumericUpDown)control[0];
                        intControl.Value = (int)prop.Data;
                        break;
                    case FieldType.Float:
                        NumericUpDown floatControl = (NumericUpDown)control[0];
                        floatControl.Value = Convert.ToDecimal(prop.Data);
                        break;
                    case FieldType.Vector2:
                        //prop.Data = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                        break;
                    case FieldType.Vector3:
                        //prop.Data = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        break;
                    case FieldType.String:
                        TextBox box = (TextBox)control[0];
                        box.Text = (string)prop.Data;
                        break;
                    case FieldType.ListByte:
                        break;
                }
            }
        }
        public void Load(Chunk chunk)
        {
            ChunkID = chunk.ChunkType;

            ControlBase = new Panel();

            ControlBase.Dock = DockStyle.Right;

            ControlBase.Width = 225;

            int controlYPos = 13;

            foreach (ElementProperty prop in chunk.Fields)
            {
                switch (prop.Type)
                {
                    case FieldType.Byte:
                        NumericUpDown ByteNumeric = new NumericUpDown();
                        ByteNumeric.Name = prop.Name;
                        ByteNumeric.Minimum = 0;
                        ByteNumeric.Maximum = 255;
                        ByteNumeric.Location = new Point(ControlBase.Width - ByteNumeric.Width, controlYPos);
                        ControlBase.Controls.Add(ByteNumeric);
                        break;
                    case FieldType.Short:
                        NumericUpDown ShortNumeric = new NumericUpDown();
                        ShortNumeric.Name = prop.Name;
                        ShortNumeric.Minimum = short.MinValue;
                        ShortNumeric.Maximum = short.MaxValue;
                        ShortNumeric.Location = new Point(ControlBase.Width - ShortNumeric.Width, controlYPos);
                        ControlBase.Controls.Add(ShortNumeric);
                        break;
                    case FieldType.Integer:
                        NumericUpDown IntNumeric = new NumericUpDown();
                        IntNumeric.Name = prop.Name;
                        IntNumeric.Minimum = int.MinValue;
                        IntNumeric.Maximum = int.MaxValue;
                        IntNumeric.Location = new Point(ControlBase.Width - IntNumeric.Width, controlYPos);
                        ControlBase.Controls.Add(IntNumeric);
                        break;
                    case FieldType.Float:
                        NumericUpDown FloatNumeric = new NumericUpDown();
                        FloatNumeric.Name = prop.Name;
                        FloatNumeric.Minimum = decimal.MinValue;
                        FloatNumeric.Maximum = decimal.MaxValue;
                        FloatNumeric.DecimalPlaces = 3;
                        FloatNumeric.Location = new Point(ControlBase.Width - FloatNumeric.Width, controlYPos);
                        ControlBase.Controls.Add(FloatNumeric);
                        break;
                    case FieldType.Vector2:
                        controlYPos = LoadVec2Controls(controlYPos, prop);
                        continue;
                    case FieldType.Vector3:
                        controlYPos = LoadVec3Controls(controlYPos, prop);
                        continue;
                    case FieldType.String:
                        TextBox StringBox = new TextBox();
                        StringBox.Name = prop.Name;
                        StringBox.Width = 120;
                        StringBox.Location = new Point(ControlBase.Width - StringBox.Width, controlYPos);
                        ControlBase.Controls.Add(StringBox);
                        break;
                    case FieldType.ListByte:
                        break;
                }

                Label propLable = new Label();

                propLable.Name = prop.Name + "Label";
                propLable.Text = prop.Name + ": ";

                propLable.Location = new Point(7, controlYPos);

                ControlBase.Controls.Add(propLable);

                controlYPos += 26;
            }
        }
        void AddToChunkNode(TreeNode parent, Chunk chunk)
        {
            TreeNode node = new TreeNode(chunk.DisplayName);

            node.Tag = chunk.ChunkType;

            parent.Nodes.Add(node);
        }
        void Read(EndianBinaryReader reader)
        {
            if (CurrentControl != null)
            {
                CurrentControl.Hide();

                CurrentControl.RemoveFromMainForm(MainForm);

                CurrentControl = null;
            }

            Cam = new Camera();

            ChunkTemplates = LoadTemplates();

            Chunks.Clear();

            int numChunkHeaders = reader.ReadInt32();

            int readerOffsetStorage = 4;

            for (int i = 0; i < numChunkHeaders; i++)
            {
                string chunkName = reader.ReadStringUntil('\0');

                reader.BaseStream.Position -= 1;

                int numChunks = reader.ReadInt32();

                int chunksOffset = reader.ReadInt32();

                readerOffsetStorage = (int)reader.BaseStream.Position;

                reader.BaseStream.Position = chunksOffset;

                if (chunkName == "RTBL")
                {
                    //Skip offset bank, which is a table of integers
                    reader.BaseStream.Position += 4 * numChunks;
                }

                for (int j = 0; j < numChunks; j++)
                {
                    Chunk newChunk = new Chunk();

                    newChunk.Read(reader, chunkName, ChunkTemplates);

                    Chunks.Add(newChunk);
                }

                reader.BaseStream.Position = readerOffsetStorage;
            }

            foreach (Chunk chunk in Chunks)
            {
                string chunkSearchString = chunk.ChunkType.Remove(chunk.ChunkType.Length - 1);

                EntityTemplate template = ChunkTemplates.Find(x => x.ChunkID.Contains(chunkSearchString));

                template.ReadSpecialProcess(chunk.Fields, Chunks);
            }

            UpdateTreeView();

            MainForm.ElementView.SelectedNode = MainForm.ElementView.Nodes[0];

            SelectedChunk = Chunks[0];

            Controls = LoadControls();

            IsListLoaded = true;
        }
        public void ChangeSelectionFromTreeNode(TreeNode node)
        {
            CurSelectedNode = node;

            if (CurrentControl != null)
            {
                //CurrentControl.Hide();

                //CurrentControl.RemoveFromMainForm(MainForm);
            }

            if (node.Parent != null)
            {
                IEnumerable<IGrouping<string, Chunk>> query = GroupChunksByFourCc();

                foreach (IGrouping<string, Chunk> group in query)
                {
                    if (group.Key == (string)node.Tag)
                    {
                        List<Chunk> chunkList = group.ToList();

                        ResetChunkColor();

                        SelectedChunk = chunkList[node.Index];

                        SelectedChunk.DisplayColor = Color.Red;

                        UpdateControls();
                    }
                }
            }
        }
        public Chunk Copy()
        {
            Chunk copiedChunk = new Chunk();

            foreach (ElementProperty prop in Fields)
            {
                ElementProperty copiedProp = prop.Copy();

                copiedChunk.Fields.Add(copiedProp);
            }

            return copiedChunk;
        }
        public void ChangeSelectionFromChunkElement(Chunk chun)
        {
            ResetChunkColor();

            SelectedChunk = chun;

            SelectedChunk.DisplayColor = Color.Red;

            IEnumerable<IGrouping<string, Chunk>> query = GroupChunksByFourCc();

            int parentNodeIndex = 0;

            List<Chunk> chunkList = new List<Chunk>();

            foreach (IGrouping<string, Chunk> group in query)
            {
                if (group.Key == SelectedChunk.ChunkType)
                {
                    chunkList = group.ToList();
                    break;
                }

                else
                    parentNodeIndex += 1;
            }

            int elementNodeIndex = chunkList.IndexOf(chun);

            TreeNode elementNode = MainForm.ElementView.Nodes[parentNodeIndex].Nodes[elementNodeIndex];

            MainForm.ElementView.SelectedNode = elementNode;

            UpdateControls();
        }
        public void AddChunkElement()
        {
            string chunkType = (string)CurSelectedNode.Tag;

            string templateSearchString = chunkType.Remove(chunkType.Length - 1);

            EntityTemplate template = ChunkTemplates.Find(x => x.ChunkID.Contains(templateSearchString));

            Chunk newChunk = new Chunk();

            newChunk.MakeEmptyChunkFromTemplate(template);

            Chunks.Add(newChunk);

            TreeNode parentNode;

            if (CurSelectedNode.Parent == null)
                parentNode = CurSelectedNode;

            else
                parentNode = CurSelectedNode.Parent;

            AddToChunkNode(parentNode, newChunk);
        }
        public void AddChunk(string chunkType)
        {
            var query = GroupChunksByFourCc();

            foreach (var group in query)
            {
                if (group.Key == chunkType)
                {
                    MessageBox.Show("The chunk type you selected already exists.", "Chunk Type Already Exists");

                    return;
                }
            }

            Chunk newChunk = new Chunk();

            string searchString = chunkType.Remove(chunkType.Length - 1);

            newChunk.MakeEmptyChunkFromTemplate(ChunkTemplates.Find(x => x.ChunkID.Contains(searchString)));

            newChunk.ChunkType = chunkType;

            Chunks.Add(newChunk);

            ControlObject newControl = new ControlObject();

            newControl.Load(newChunk);

            Controls.Add(newControl);

            UpdateTreeView();
        }