context: using System;
  using System.Collections.Generic;
  using System.Drawing;
  using System.Globalization;
  using System.Text;
  using System.Windows.Forms;
  using Fomm.Properties;
  
  namespace Fomm.Games.Fallout3.Tools.TESsnip
  {
    internal partial class MediumLevelRecordEditor : Form
    {
      private SubRecord sr;
      private SubrecordStructure ss;
      private List<TextBox> boxes;
      private List<ElementValueType> valueTypes;
      private List<Panel> elements;
      private dFormIDLookupS formIDLookup;
      private dFormIDScan formIDScan;
  
      private Dictionary<int, string> removedStrings = new Dictionary<int, string>();
  
      private int repeatcount;
  
      private Dictionary<string, string[]> cachedFormIDs = new Dictionary<string, string[]>();
  
      private class cbTag
      {
        public readonly int group;
        public readonly TextBox textBox;
  
        public cbTag(int group, TextBox textBox)
        {
          this.group = group;
          this.textBox = textBox;
        }
      }
  
      private class bTag
      {
        public readonly TextBox formID;
        public readonly TextBox edid;
  
        public bTag(TextBox form, TextBox edid)
        {
          formID = form;
          this.edid = edid;
        }
      }
  
      private class comboBoxItem
      {
        public readonly string name;
        public readonly string value;
  
        public comboBoxItem(string name, string value)
        {
          this.name = name;
          this.value = value;
        }
  
        public override string ToString()
        {
          return name;
        }
      }
  
      private class repeatCbTag
      {
        public readonly TextBox tb;
        public readonly int panel;
  
        public repeatCbTag(TextBox tb, int panel)
        {
          this.tb = tb;
          this.panel = panel;
        }
      }
  
      private void AddElement(ElementStructure es)
      {
        int a = -1, b = 0, c = 0;
        AddElement(es, ref a, null, ref b, ref c);
      }
  
      private void AddElement(ElementStructure es, ref int offset, byte[] data, ref int groupOffset, ref int CurrentGroup)
      {
        var panel1 = new Panel();
        panel1.AutoSize = true;
        panel1.Width = fpanel1.Width;
        panel1.Height = 1;
        var ypos = 0;
  
        var tb = new TextBox();
        boxes.Add(tb);
        if (es.group != 0)
        {
          var cb = new CheckBox();
          cb.Text = "Use this value?";
          panel1.Controls.Add(cb);
          cb.Location = new Point(10, ypos);
          ypos += 24;
          cb.Tag = new cbTag(es.group, tb);
          if (CurrentGroup != es.group)
          {
            cb.Checked = true;
          }
          else
          {
            tb.Enabled = false;
          }
          cb.CheckedChanged += CheckBox_CheckedChanged;
        }
        if (es.optional || es.repeat && repeatcount > 0)
        {
          var cb = new CheckBox();
          cb.Text = "Use this value?";
          panel1.Controls.Add(cb);
          cb.Location = new Point(10, ypos);
          ypos += 24;
          cb.Tag = new repeatCbTag(tb, elements.Count);
          if (data == null)
          {
            tb.Enabled = false;
          }
          else
          {
            cb.Checked = true;
          }
          cb.CheckedChanged += RepeatCheckBox_CheckedChanged;
        }
        if ((CurrentGroup == 0 && es.group != 0) || (CurrentGroup != 0 && es.group != 0 && CurrentGroup != es.group))
        {
          CurrentGroup = es.group;
          groupOffset = offset;
        }
        else if (CurrentGroup != 0 && es.group == 0)
        {
          CurrentGroup = 0;
        }
        else if (CurrentGroup != 0 && CurrentGroup == es.group)
        {
          offset = groupOffset;
        }
        valueTypes.Add(es.type);
        if (data != null)
        {
          switch (es.type)
          {
            case ElementValueType.Int:
              tb.Text = TypeConverter.h2si(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]).ToString();
              offset += 4;
              break;
            case ElementValueType.FormID:
              tb.Text =
                TypeConverter.h2i(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]).ToString("X8");
              offset += 4;
              break;
            case ElementValueType.Float:
              tb.Text = TypeConverter.h2f(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]).ToString();
              offset += 4;
              break;
            case ElementValueType.Short:
              tb.Text = TypeConverter.h2ss(data[offset], data[offset + 1]).ToString();
              offset += 2;
              break;
            case ElementValueType.Byte:
              tb.Text = data[offset].ToString();
              offset++;
              break;
            case ElementValueType.String:
              var s = "";
              while (data[offset] != 0)
              {
                s += (char) data[offset++];
              }
              offset++;
              tb.Text = s;
              tb.Width += 200;
              break;
            case ElementValueType.fstring:
              tb.Text = sr.GetStrData();
              tb.Width += 200;
              break;
            default:
              throw new ApplicationException();
          }
        }
        else
        {
          if (es.type == ElementValueType.String || es.type == ElementValueType.fstring)
          {
            tb.Width += 200;
          }
          if (removedStrings.ContainsKey(boxes.Count - 1))
          {
            tb.Text = removedStrings[boxes.Count - 1];
          }
        }
        var l = new Label();
        l.AutoSize = true;
        var tmp = es.type.ToString();
        l.Text = tmp + ": " + es.name + (es.desc != null ? (" (" + es.desc + ")") : "");
        panel1.Controls.Add(tb);
        tb.Location = new Point(10, ypos);
        if (es.multiline)
        {
          tb.Multiline = true;
          ypos += tb.Height*5;
          tb.Height *= 6;
        }
        panel1.Controls.Add(l);
        l.Location = new Point(tb.Right + 10, ypos + 3);
        string[] options = null;
        if (es.type == ElementValueType.FormID)
        {
          ypos += 28;
          var b = new Button();
          b.Text = "FormID lookup";
          b.Click += LookupFormID_Click;
          panel1.Controls.Add(b);
          b.Location = new Point(20, ypos);
          var tb2 = new TextBox();
          tb2.Width += 200;
          tb2.ReadOnly = true;
          panel1.Controls.Add(tb2);
          tb2.Location = new Point(b.Right + 10, ypos);
          b.Tag = new bTag(tb, tb2);
          if (es.FormIDType != null)
          {
            if (cachedFormIDs.ContainsKey(es.FormIDType))
            {
              options = cachedFormIDs[es.FormIDType];
            }
            else
            {
  
gt:             options = formIDScan(es.FormIDType);