//------------------------------------------------------------------------------
// <copyright file=”*.cs” company=”EhLib Team”>
//     Copyright (c) 2017 Dmitry V. Bolshakov   
// </copyright>
//------------------------------------------------------------------------------

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
//using System.Windows.Forms; 
using System.Diagnostics;
using System.Globalization;
using System.Windows.Forms.Design;
using System.Collections.ObjectModel;

namespace EhLib.Design
{
  internal class DataGridAddColumnDialog : System.Windows.Forms.Form
  {
    private System.Windows.Forms.RadioButton dataBoundColumnRadioButton;
    private System.Windows.Forms.Label columnInDataSourceLabel;

    private System.Windows.Forms.ListBox dataColumns;

    private System.Windows.Forms.RadioButton unboundColumnRadioButton;
    private System.Windows.Forms.TextBox nameTextBox;

    private System.Windows.Forms.ComboBox columnTypesCombo;

    private System.Windows.Forms.TextBox headerTextBox;
    private System.Windows.Forms.Label nameLabel;

    private System.Windows.Forms.Label typeLabel;

    private System.Windows.Forms.Label headerTextLabel;
    private System.Windows.Forms.CheckBox visibleCheckBox;

    private System.Windows.Forms.CheckBox readOnlyCheckBox;

    private System.Windows.Forms.CheckBox frozenCheckBox;
    private System.Windows.Forms.Button addButton;

    private System.Windows.Forms.Button cancelButton;

    private readonly Collection<DataGridColumn> dataGridViewColumns;
    private readonly DataGridEh liveDataGridView;

    private int insertAtPosition = -1;
    private int initialDataGridViewColumnsCount = -1;
    private bool persistChangesToDesigner;

    private static readonly Type DataGridViewColumnType = typeof(System.Windows.Forms.DataGridViewColumn);
    private static readonly Type DesignerType = typeof(System.ComponentModel.Design.IDesigner);
    //private static Type iTypeResolutionServiceType = typeof(System.ComponentModel.Design.ITypeResolutionService);
    private static readonly Type TypeDiscoveryServiceType = typeof(System.ComponentModel.Design.ITypeDiscoveryService);
    private static readonly Type ComponentChangeServiceType = typeof(System.ComponentModel.Design.IComponentChangeService);
    private static readonly Type HelpServiceType = typeof(System.ComponentModel.Design.IHelpService);
    private static readonly Type UIServiceType = typeof(System.Windows.Forms.Design.IUIService);
    private static readonly Type DesignerHostType = typeof(System.ComponentModel.Design.IDesignerHost);
    private static readonly Type NameCreationServiceType = typeof(System.ComponentModel.Design.Serialization.INameCreationService);
    //        private static Type dataGridViewColumnDesignTimeVisibleAttributeType = typeof(DataGridViewColumnDesignTimeVisibleAttribute);

//    private static Type[] columnTypes = new Type[] {
//            typeof(DataGridButtonColumn),
//            typeof(DataGridCheckBoxColumn), 
////            typeof(DataGridComboBoxColumn),
//            typeof(DataGridImageColumn),
////            typeof(DataGridLinkColumn),
//            typeof(DataGridTextColumn)
//        };

    private System.Windows.Forms.TableLayoutPanel okCancelTableLayoutPanel;
    private System.Windows.Forms.TableLayoutPanel checkBoxesTableLayoutPanel;
    private System.Windows.Forms.TableLayoutPanel overarchingTableLayoutPanel;

    private readonly System.ComponentModel.IContainer components = null;

    public DataGridAddColumnDialog(Collection<DataGridColumn> dataGridViewColumns, DataGridEh liveDataGridView)
    {
      this.dataGridViewColumns = dataGridViewColumns;
      this.liveDataGridView = liveDataGridView;

      // Required for Windows Form Designer support
      InitializeComponent();

      EnableDataBoundSection();

      InitData();
    }

    private void InitData()
    {
      // PERF: set the Dialog Font before InitializeComponent.
      //
      Font uiFont = DefaultFont;
      IUIService uiService = (IUIService)this.liveDataGridView.Site.GetService(UIServiceType);
      if (uiService != null)
      {
        uiFont = (Font)uiService.Styles["DialogFont"];
      }
      this.Font = uiFont;
    }

    private void AddColumn()
    {
      Type columnType = ((ComboBoxItem)this.columnTypesCombo.SelectedItem).ColumnType;

      DataGridColumn column = (DataGridColumn)System.Activator.CreateInstance(columnType);

      //            bool forceColumnFrozen = this.dataGridViewColumns.Count > this.insertAtPosition && this.dataGridViewColumns[this.insertAtPosition].Frozen;

      //            column.Frozen = forceColumnFrozen;

      if (!persistChangesToDesigner)
      {
        column.Title.Text = this.headerTextBox.Text;
        column.Name = this.nameTextBox.Text;
        column.DisplayIndex = -1;
        this.dataGridViewColumns.Insert(this.insertAtPosition, column);
        insertAtPosition++;
      }

      // 1. set the property values in the column 
      //
      column.Title.Text = this.headerTextBox.Text;
      column.Name = this.nameTextBox.Text;
      //            column.Visible = this.visibleCheckBox.Checked;
      //            column.Frozen = this.frozenCheckBox.Checked || forceColumnFrozen;
      ////column.ReadOnly = this.readOnlyCheckBox.Checked;

      if (this.dataBoundColumnRadioButton.Checked && dataColumns.SelectedIndex > -1)
      {
        column.DataPropertyName = ((ListBoxItem)dataColumns.SelectedItem).PropertyName;
      }

      if (this.persistChangesToDesigner)
      {
        try
        {
          // insert the column before siting the column. 
          // if DataGridView throws an exception then the designer does not end up w/ a column that is not in any data grid view. 
          column.DisplayIndex = -1;
          this.dataGridViewColumns.Insert(insertAtPosition, column);
          insertAtPosition++;
          // site the column
          Debug.Assert(this.liveDataGridView.Site.Container != null, @"this.liveDataGridView.Site.Container != null");
          this.liveDataGridView.Site.Container.Add(column, column.Name);
        }
        catch (System.InvalidOperationException ex)
        {
          IUIService uiService = (IUIService)this.liveDataGridView.Site.GetService(typeof(IUIService));
          DataGridDesigner.ShowErrorDialog(uiService, ex, this.liveDataGridView);
          return;
        }
      }

      // Set the UserAddedColumn property to true. 
      PropertyDescriptorCollection props = TypeDescriptor.GetProperties(column);
      PropertyDescriptor pd = props["UserAddedColumn"];
      if (pd != null)
      {
        pd.SetValue(column, true);
      }

      this.nameTextBox.Text = this.headerTextBox.Text = this.AssignName();
      this.nameTextBox.Focus();
    }

    private string AssignName()
    {
      int colId = 1;
      // string columnName = SR.GetString(SR.DataGridView_ColumnName, colId.ToString());
      string columnName = "Column" + colId.ToString(CultureInfo.InvariantCulture);

      IDesignerHost host;
      IContainer container = null;

      host = this.liveDataGridView.Site.GetService(DesignerHostType) as IDesignerHost;
      if (host != null)
      {
        container = host.Container;
      }

      while (!ValidName(columnName,
                        this.dataGridViewColumns,
                        container,
                        null /*nameCreationService*/,
                        this.liveDataGridView.Columns,
                        !this.persistChangesToDesigner))
      {
        colId++;
        // columnName = SR.GetString(SR.DataGridView_ColumnName, colId.ToString());
        columnName = "Column" + colId.ToString(CultureInfo.InvariantCulture);
      }

      return columnName;
    }

    protected override void Dispose(bool disposing)
    {
      if (disposing)
      {
        if (components != null)
        {
          components.Dispose();
        }
      }
      base.Dispose(disposing);
    }

    private void EnableDataBoundSection()
    {
      bool dataGridViewIsDataBound = this.dataColumns.Items.Count > 0;
      if (dataGridViewIsDataBound)
      {
        this.dataBoundColumnRadioButton.Enabled = true;
        this.dataBoundColumnRadioButton.Checked = true;
        this.dataBoundColumnRadioButton.Focus();
        this.headerTextBox.Text = this.nameTextBox.Text = this.AssignName();
      }
      else
      {
        this.dataBoundColumnRadioButton.Enabled = false;
        this.unboundColumnRadioButton.Checked = true;
        this.nameTextBox.Focus();
        this.headerTextBox.Text = this.nameTextBox.Text = this.AssignName();
      }
    }

    public static ComponentDesigner GetComponentDesignerForType(ITypeResolutionService tr, Type type)
    {
      ComponentDesigner compDesigner = null;
      DesignerAttribute designerAttr = null;
      AttributeCollection attributes = TypeDescriptor.GetAttributes(type);
      for (int i = 0; i < attributes.Count; i++)
      {
        DesignerAttribute da = attributes[i] as DesignerAttribute;
        if (da != null)
        {
          Type daType = Type.GetType(da.DesignerBaseTypeName);
          if (daType != null && daType == DesignerType)
          {
            designerAttr = da;
            break;
          }
        }
      }

      if (designerAttr != null)
      {
        Type designerType;
        if (tr != null)
        {
          designerType = tr.GetType(designerAttr.DesignerTypeName);
        }
        else
        {
          designerType = Type.GetType(designerAttr.DesignerTypeName);
        }

        if (designerType != null && typeof(System.ComponentModel.Design.ComponentDesigner).IsAssignableFrom(designerType))
        {
          compDesigner = (ComponentDesigner)System.Activator.CreateInstance(designerType);
        }
      }

      return compDesigner;
    }

    #region Windows Form Designer generated code
    /// <summary> 
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.dataBoundColumnRadioButton = new System.Windows.Forms.RadioButton();
      this.overarchingTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
      this.checkBoxesTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
      this.frozenCheckBox = new System.Windows.Forms.CheckBox();
      this.visibleCheckBox = new System.Windows.Forms.CheckBox();
      this.readOnlyCheckBox = new System.Windows.Forms.CheckBox();
      this.okCancelTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
      this.addButton = new System.Windows.Forms.Button();
      this.cancelButton = new System.Windows.Forms.Button();
      this.columnInDataSourceLabel = new System.Windows.Forms.Label();
      this.dataColumns = new System.Windows.Forms.ListBox();
      this.unboundColumnRadioButton = new System.Windows.Forms.RadioButton();
      this.nameLabel = new System.Windows.Forms.Label();
      this.nameTextBox = new System.Windows.Forms.TextBox();
      this.typeLabel = new System.Windows.Forms.Label();
      this.columnTypesCombo = new System.Windows.Forms.ComboBox();
      this.headerTextLabel = new System.Windows.Forms.Label();
      this.headerTextBox = new System.Windows.Forms.TextBox();
      this.overarchingTableLayoutPanel.SuspendLayout();
      this.checkBoxesTableLayoutPanel.SuspendLayout();
      this.okCancelTableLayoutPanel.SuspendLayout();
      this.SuspendLayout();
      // 
      // dataBoundColumnRadioButton
      // 
      this.dataBoundColumnRadioButton.Checked = true;
      this.overarchingTableLayoutPanel.SetColumnSpan(this.dataBoundColumnRadioButton, 2);
      this.dataBoundColumnRadioButton.Location = new System.Drawing.Point(0, 0);
      this.dataBoundColumnRadioButton.Margin = new System.Windows.Forms.Padding(0, 0, 0, 3);
      this.dataBoundColumnRadioButton.Name = "dataBoundColumnRadioButton";
      this.dataBoundColumnRadioButton.Size = new System.Drawing.Size(104, 24);
      this.dataBoundColumnRadioButton.TabIndex = 2;
      this.dataBoundColumnRadioButton.TabStop = true;
      this.dataBoundColumnRadioButton.CheckedChanged += new System.EventHandler(this.DataBoundColumnRadioButton_CheckedChanged);
      // 
      // overarchingTableLayoutPanel
      // 
      this.overarchingTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
      this.overarchingTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
      this.overarchingTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F));
      this.overarchingTableLayoutPanel.Controls.Add(this.checkBoxesTableLayoutPanel, 0, 10);
      this.overarchingTableLayoutPanel.Controls.Add(this.okCancelTableLayoutPanel, 1, 11);
      this.overarchingTableLayoutPanel.Controls.Add(this.dataBoundColumnRadioButton, 0, 0);
      this.overarchingTableLayoutPanel.Controls.Add(this.columnInDataSourceLabel, 0, 1);
      this.overarchingTableLayoutPanel.Controls.Add(this.dataColumns, 0, 2);
      this.overarchingTableLayoutPanel.Controls.Add(this.unboundColumnRadioButton, 0, 3);
      this.overarchingTableLayoutPanel.Controls.Add(this.nameLabel, 0, 4);
      this.overarchingTableLayoutPanel.Controls.Add(this.nameTextBox, 1, 4);
      this.overarchingTableLayoutPanel.Controls.Add(this.typeLabel, 0, 6);
      this.overarchingTableLayoutPanel.Controls.Add(this.columnTypesCombo, 1, 6);
      this.overarchingTableLayoutPanel.Controls.Add(this.headerTextLabel, 0, 8);
      this.overarchingTableLayoutPanel.Controls.Add(this.headerTextBox, 1, 8);
      this.overarchingTableLayoutPanel.Location = new System.Drawing.Point(0, 0);
      this.overarchingTableLayoutPanel.Margin = new System.Windows.Forms.Padding(12);
      this.overarchingTableLayoutPanel.Name = "overarchingTableLayoutPanel";
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.overarchingTableLayoutPanel.Size = new System.Drawing.Size(200, 100);
      this.overarchingTableLayoutPanel.TabIndex = 0;
      // 
      // checkBoxesTableLayoutPanel
      // 
      this.overarchingTableLayoutPanel.SetColumnSpan(this.checkBoxesTableLayoutPanel, 2);
      this.checkBoxesTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
      this.checkBoxesTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
      this.checkBoxesTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
      this.checkBoxesTableLayoutPanel.Controls.Add(this.frozenCheckBox, 2, 0);
      this.checkBoxesTableLayoutPanel.Controls.Add(this.visibleCheckBox, 0, 0);
      this.checkBoxesTableLayoutPanel.Controls.Add(this.readOnlyCheckBox, 1, 0);
      this.checkBoxesTableLayoutPanel.Location = new System.Drawing.Point(0, -112);
      this.checkBoxesTableLayoutPanel.Margin = new System.Windows.Forms.Padding(0, 3, 0, 6);
      this.checkBoxesTableLayoutPanel.Name = "checkBoxesTableLayoutPanel";
      this.checkBoxesTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
      this.checkBoxesTableLayoutPanel.Size = new System.Drawing.Size(200, 100);
      this.checkBoxesTableLayoutPanel.TabIndex = 0;
      // 
      // frozenCheckBox
      // 
      this.frozenCheckBox.Location = new System.Drawing.Point(220, 0);
      this.frozenCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
      this.frozenCheckBox.Name = "frozenCheckBox";
      this.frozenCheckBox.Size = new System.Drawing.Size(104, 24);
      this.frozenCheckBox.TabIndex = 0;
      // 
      // visibleCheckBox
      // 
      this.visibleCheckBox.Checked = true;
      this.visibleCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
      this.visibleCheckBox.Location = new System.Drawing.Point(0, 0);
      this.visibleCheckBox.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
      this.visibleCheckBox.Name = "visibleCheckBox";
      this.visibleCheckBox.Size = new System.Drawing.Size(104, 24);
      this.visibleCheckBox.TabIndex = 1;
      // 
      // readOnlyCheckBox
      // 
      this.readOnlyCheckBox.Location = new System.Drawing.Point(110, 0);
      this.readOnlyCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
      this.readOnlyCheckBox.Name = "readOnlyCheckBox";
      this.readOnlyCheckBox.Size = new System.Drawing.Size(104, 24);
      this.readOnlyCheckBox.TabIndex = 2;
      // 
      // okCancelTableLayoutPanel
      // 
      this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
      this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
      this.okCancelTableLayoutPanel.Controls.Add(this.addButton, 0, 0);
      this.okCancelTableLayoutPanel.Controls.Add(this.cancelButton, 1, 0);
      this.okCancelTableLayoutPanel.Location = new System.Drawing.Point(116, 0);
      this.okCancelTableLayoutPanel.Margin = new System.Windows.Forms.Padding(0, 6, 0, 0);
      this.okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel";
      this.okCancelTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
      this.okCancelTableLayoutPanel.Size = new System.Drawing.Size(200, 100);
      this.okCancelTableLayoutPanel.TabIndex = 1;
      // 
      // addButton
      // 
      this.addButton.Location = new System.Drawing.Point(0, 0);
      this.addButton.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
      this.addButton.Name = "addButton";
      this.addButton.Size = new System.Drawing.Size(75, 23);
      this.addButton.TabIndex = 0;
      this.addButton.Click += new System.EventHandler(this.AddButton_Click);
      // 
      // cancelButton
      // 
      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
      this.cancelButton.Location = new System.Drawing.Point(103, 0);
      this.cancelButton.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
      this.cancelButton.Name = "cancelButton";
      this.cancelButton.Size = new System.Drawing.Size(75, 23);
      this.cancelButton.TabIndex = 1;
      this.cancelButton.Click += new System.EventHandler(this.CancelButton_Click);
      // 
      // columnInDataSourceLabel
      // 
      this.overarchingTableLayoutPanel.SetColumnSpan(this.columnInDataSourceLabel, 2);
      this.columnInDataSourceLabel.Location = new System.Drawing.Point(14, 30);
      this.columnInDataSourceLabel.Margin = new System.Windows.Forms.Padding(14, 3, 0, 0);
      this.columnInDataSourceLabel.Name = "columnInDataSourceLabel";
      this.columnInDataSourceLabel.Size = new System.Drawing.Size(100, 23);
      this.columnInDataSourceLabel.TabIndex = 3;
      // 
      // dataColumns
      // 
      this.overarchingTableLayoutPanel.SetColumnSpan(this.dataColumns, 2);
      this.dataColumns.FormattingEnabled = true;
      this.dataColumns.Location = new System.Drawing.Point(14, 55);
      this.dataColumns.Margin = new System.Windows.Forms.Padding(14, 2, 0, 3);
      this.dataColumns.Name = "dataColumns";
      this.dataColumns.Size = new System.Drawing.Size(120, 4);
      this.dataColumns.TabIndex = 4;
      this.dataColumns.SelectedIndexChanged += new System.EventHandler(this.DataColumns_SelectedIndexChanged);
      // 
      // unboundColumnRadioButton
      // 
      this.overarchingTableLayoutPanel.SetColumnSpan(this.unboundColumnRadioButton, 2);
      this.unboundColumnRadioButton.Location = new System.Drawing.Point(0, -229);
      this.unboundColumnRadioButton.Margin = new System.Windows.Forms.Padding(0, 6, 0, 3);
      this.unboundColumnRadioButton.Name = "unboundColumnRadioButton";
      this.unboundColumnRadioButton.Size = new System.Drawing.Size(104, 24);
      this.unboundColumnRadioButton.TabIndex = 5;
      this.unboundColumnRadioButton.CheckedChanged += new System.EventHandler(this.UnboundColumnRadioButton_CheckedChanged);
      // 
      // nameLabel
      // 
      this.nameLabel.Location = new System.Drawing.Point(14, -199);
      this.nameLabel.Margin = new System.Windows.Forms.Padding(14, 3, 2, 3);
      this.nameLabel.Name = "nameLabel";
      this.nameLabel.Size = new System.Drawing.Size(100, 23);
      this.nameLabel.TabIndex = 6;
      // 
      // nameTextBox
      // 
      this.nameTextBox.Location = new System.Drawing.Point(119, -199);
      this.nameTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
      this.nameTextBox.Name = "nameTextBox";
      this.nameTextBox.Size = new System.Drawing.Size(100, 20);
      this.nameTextBox.TabIndex = 7;
      this.nameTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.NameTextBox_Validating);
      // 
      // typeLabel
      // 
      this.typeLabel.Location = new System.Drawing.Point(14, -170);
      this.typeLabel.Margin = new System.Windows.Forms.Padding(14, 3, 2, 3);
      this.typeLabel.Name = "typeLabel";
      this.typeLabel.Size = new System.Drawing.Size(100, 23);
      this.typeLabel.TabIndex = 8;
      // 
      // columnTypesCombo
      // 
      this.columnTypesCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
      this.columnTypesCombo.FormattingEnabled = true;
      this.columnTypesCombo.Location = new System.Drawing.Point(119, -170);
      this.columnTypesCombo.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
      this.columnTypesCombo.Name = "columnTypesCombo";
      this.columnTypesCombo.Size = new System.Drawing.Size(121, 21);
      this.columnTypesCombo.Sorted = true;
      this.columnTypesCombo.TabIndex = 9;
      // 
      // headerTextLabel
      // 
      this.headerTextLabel.Location = new System.Drawing.Point(14, -141);
      this.headerTextLabel.Margin = new System.Windows.Forms.Padding(14, 3, 2, 3);
      this.headerTextLabel.Name = "headerTextLabel";
      this.headerTextLabel.Size = new System.Drawing.Size(100, 23);
      this.headerTextLabel.TabIndex = 10;
      // 
      // headerTextBox
      // 
      this.headerTextBox.Location = new System.Drawing.Point(119, -141);
      this.headerTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
      this.headerTextBox.Name = "headerTextBox";
      this.headerTextBox.Size = new System.Drawing.Size(100, 20);
      this.headerTextBox.TabIndex = 11;
      // 
      // DataGridAddColumnDialog
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
      this.CancelButton = this.cancelButton;
      this.ClientSize = new System.Drawing.Size(284, 262);
      this.Controls.Add(this.overarchingTableLayoutPanel);
      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
      this.HelpButton = true;
      this.MaximizeBox = false;
      this.MinimizeBox = false;
      this.Name = "DataGridAddColumnDialog";
      this.ShowIcon = false;
      this.ShowInTaskbar = false;
      this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.DataGridViewAddColumnDialog_HelpButtonClicked);
      this.Closed += new System.EventHandler(this.DataGridViewAddColumnDialog_Closed);
      this.Load += new System.EventHandler(this.DataGridViewAddColumnDialog_Load);
      this.VisibleChanged += new System.EventHandler(this.DataGridViewAddColumnDialog_VisibleChanged);
      this.HelpRequested += new System.Windows.Forms.HelpEventHandler(this.DataGridViewAddColumnDialog_HelpRequested);
      this.overarchingTableLayoutPanel.ResumeLayout(false);
      this.overarchingTableLayoutPanel.PerformLayout();
      this.checkBoxesTableLayoutPanel.ResumeLayout(false);
      this.okCancelTableLayoutPanel.ResumeLayout(false);
      this.ResumeLayout(false);

    }
    #endregion

    private void DataBoundColumnRadioButton_CheckedChanged(object sender, System.EventArgs e)
    {
      this.columnInDataSourceLabel.Enabled = this.dataBoundColumnRadioButton.Checked;
      this.dataColumns.Enabled = this.dataBoundColumnRadioButton.Checked;

      // push the property name into the headerTextBox and into the nameTextBox
      DataColumns_SelectedIndexChanged(null, EventArgs.Empty);
    }

    private void DataColumns_SelectedIndexChanged(object sender, System.EventArgs e)
    {
      if (this.dataColumns.SelectedItem == null)
      {
        return;
      }

      this.headerTextBox.Text = this.nameTextBox.Text = ((ListBoxItem)this.dataColumns.SelectedItem).PropertyName;

      // pick a default data grid view column type 
      // NOTE: this will pick one of our data grid view column types
      SetDefaultDataGridViewColumnType(((ListBoxItem)this.dataColumns.SelectedItem).PropertyType);
    }

    private void UnboundColumnRadioButton_CheckedChanged(object sender, System.EventArgs e)
    {
      if (this.unboundColumnRadioButton.Checked)
      {
        this.nameTextBox.Text = this.headerTextBox.Text = this.AssignName();
        this.nameTextBox.Focus();
      }
    }

    private void DataGridViewAddColumnDialog_Closed(object sender, System.EventArgs e)
    {
      if (this.persistChangesToDesigner)
      {
        try
        {
          IComponentChangeService changeService = 
            (IComponentChangeService)this.liveDataGridView.Site.GetService(ComponentChangeServiceType);
          if (changeService == null)
          {
            return;
          }

          DataGridColumn[] cols = new DataGridColumn[this.liveDataGridView.Columns.Count - this.initialDataGridViewColumnsCount];
          for (int i = this.initialDataGridViewColumnsCount; i < this.liveDataGridView.Columns.Count; i++)
          {
            cols[i - this.initialDataGridViewColumnsCount] = this.liveDataGridView.Columns[i];
          }

          for (int i = this.initialDataGridViewColumnsCount; i < this.liveDataGridView.Columns.Count;)
          {
            this.liveDataGridView.StaticColumns.RemoveAt(this.initialDataGridViewColumnsCount);
          }

          PropertyDescriptor prop = TypeDescriptor.GetProperties(this.liveDataGridView)["Columns"];
          changeService.OnComponentChanging(this.liveDataGridView, prop);

          foreach (DataGridColumn col in cols)
          {
            col.DisplayIndex = -1;
          }

          this.liveDataGridView.StaticColumns.AddRange(cols);

          changeService.OnComponentChanged(this.liveDataGridView, prop, null, null);
        }
        catch (System.InvalidOperationException)
        {
        }
      }

      this.DialogResult = System.Windows.Forms.DialogResult.OK;
    }

    private void DataGridViewAddColumnDialog_HelpButtonClicked(object sender, CancelEventArgs e)
    {
      DataGridViewAddColumnDialog_HelpRequestHandled();
      e.Cancel = true;
    }

    private void DataGridViewAddColumnDialog_HelpRequested(object sender, System.Windows.Forms.HelpEventArgs e)
    {
      DataGridViewAddColumnDialog_HelpRequestHandled();
      e.Handled = true;
    }

    private void DataGridViewAddColumnDialog_HelpRequestHandled()
    {
      IHelpService helpService = this.liveDataGridView.Site.GetService(HelpServiceType) as IHelpService;
      if (helpService != null)
      {
        helpService.ShowHelpFromKeyword("vs.DataGridViewAddColumnDialog");
      }
    }

    private void DataGridViewAddColumnDialog_Load(object sender, System.EventArgs e)
    {
      // setup Visible/ReadOnly/Frozen checkboxes
      // localization will change the check boxes text length 
      if (this.dataBoundColumnRadioButton.Checked)
      {
        this.headerTextBox.Text = this.nameTextBox.Text = AssignName();
      }
      else
      {
        Debug.Assert(this.unboundColumnRadioButton.Checked, "we only have 2 radio buttons");
        string columnName = this.AssignName();
        this.headerTextBox.Text = this.nameTextBox.Text = columnName;
      }

      PopulateColumnTypesCombo();

      PopulateDataColumns();

      EnableDataBoundSection();

      this.cancelButton.Text = @"Cancel";// SR.GetString(SR.DataGridView_Cancel); 
    }

    private void DataGridViewAddColumnDialog_VisibleChanged(object sender, System.EventArgs e)
    {
      if (this.Visible && this.IsHandleCreated)
      {
        if (this.dataBoundColumnRadioButton.Checked)
        {
          this.dataColumns.Select();
        }
        else
        {
          this.nameTextBox.Select();
        }
      }
    }

    private void NameTextBox_Validating(object sender, CancelEventArgs e)
    {
      IDesignerHost host;
      INameCreationService nameCreationService;
      IContainer container = null;

      host = this.liveDataGridView.Site.GetService(DesignerHostType) as IDesignerHost;
      if (host != null)
      {
        container = host.Container;
      }

      nameCreationService = this.liveDataGridView.Site.GetService(NameCreationServiceType) as INameCreationService;

      string errorString;
      if (!ValidName(this.nameTextBox.Text,
                     this.dataGridViewColumns,
                     container,
                     nameCreationService,
                     this.liveDataGridView.Columns,
                     !this.persistChangesToDesigner,
                     out errorString))
      {
        IUIService uiService = (IUIService)this.liveDataGridView.Site.GetService(UIServiceType);
        DataGridDesigner.ShowErrorDialog(uiService, errorString, this.liveDataGridView);
        e.Cancel = true;
      }
    }

    // this code will have to change once we figure out how what to-do w/ third party
    // data grid view column types
    private void PopulateColumnTypesCombo()
    {
      this.columnTypesCombo.Items.Clear();

      IDesignerHost host = (IDesignerHost)this.liveDataGridView.Site.GetService(DesignerHostType);
      if (host == null)
      {
        return;
      }

      ITypeDiscoveryService discoveryService = (ITypeDiscoveryService)host.GetService(TypeDiscoveryServiceType);

      if (discoveryService == null)
      {
        return;
      }

      //      ICollection columnTypes = DesignerUtils.FilterGenericTypes(discoveryService.GetTypes(dataGridViewColumnType, false /*excludeGlobalTypes*/));
      ICollection columnTypes = discoveryService.GetTypes(DataGridViewColumnType, false /*excludeGlobalTypes*/);

      foreach (Type t in columnTypes)
      {
        if (t == DataGridViewColumnType)
        {
          continue;
        }

        if (t.IsAbstract)
        {
          continue;
        }

        if (!t.IsPublic && !t.IsNestedPublic)
        {
          continue;
        }

        //DataGridViewColumnDesignTimeVisibleAttribute attr = TypeDescriptor.GetAttributes(t)[dataGridViewColumnDesignTimeVisibleAttributeType] as DataGridViewColumnDesignTimeVisibleAttribute; 
        //if (attr != null && !attr.Visible)
        //{ 
        //    continue; 
        //}

        this.columnTypesCombo.Items.Add(new ComboBoxItem(t));
      }

      // make the textBoxColumn type the selected type 
      this.columnTypesCombo.SelectedIndex = this.TypeToSelectedIndex(typeof(System.Windows.Forms.DataGridViewTextBoxColumn));
    }

    private void PopulateDataColumns()
    {
      int selectedIndex = this.dataColumns.SelectedIndex;

      this.dataColumns.SelectedIndex = -1;
      this.dataColumns.Items.Clear();

      if (this.liveDataGridView.DataSource != null)
      {
        System.Windows.Forms.CurrencyManager cm;
        try
        {
          cm = this.BindingContext[this.liveDataGridView.DataSource, this.liveDataGridView.DataMember] as 
                 System.Windows.Forms.CurrencyManager;
        }
        catch (ArgumentException)
        {
          cm = null;
        }

        PropertyDescriptorCollection props;
        if (cm != null)
          props = cm.GetItemProperties();
        else
          props = null;

        if (props != null)
        {
          for (int i = 0; i < props.Count; i++)
          {
            if (typeof(IList).IsAssignableFrom(props[i].PropertyType))
            {
              // we have an IList. It could be a byte[] in which case we want to generate an Image column
              // 
              TypeConverter imageTypeConverter = TypeDescriptor.GetConverter(typeof(Image));
              if (!imageTypeConverter.CanConvertFrom(props[i].PropertyType))
              {
                continue;
              }
            }

            this.dataColumns.Items.Add(new ListBoxItem(props[i].PropertyType, props[i].Name));
          }
        }
      }

      if (selectedIndex != -1 && selectedIndex < this.dataColumns.Items.Count)
      {
        this.dataColumns.SelectedIndex = selectedIndex;
      }
      else
      {
        this.dataColumns.SelectedIndex = this.dataColumns.Items.Count > 0 ? 0 : -1;
      }
    }

    private void AddButton_Click(object sender, System.EventArgs e)
    {
      this.cancelButton.Text = @"Close"; //SR.GetString(SR.DataGridView_Close); 

      this.AddColumn();
    }

    private void CancelButton_Click(object sender, System.EventArgs e)
    {
      this.Close();
      /*
      if (this.cancelButtonIsCloseButton) 
      {
          this.AddColumn();
      }
      */
    }

    protected override bool ProcessDialogKey(System.Windows.Forms.Keys keyData)
    {
      if ((keyData & System.Windows.Forms.Keys.Modifiers) == 0)
      {
        switch (keyData & System.Windows.Forms.Keys.KeyCode)
        {
          case System.Windows.Forms.Keys.Enter:
            // Validate the name before adding the column.
            IDesignerHost host;
            INameCreationService nameCreationService;
            IContainer container = null;

            host = this.liveDataGridView.Site.GetService(DesignerHostType) as IDesignerHost;
            if (host != null)
            {
              container = host.Container;
            }

            nameCreationService = this.liveDataGridView.Site.GetService(NameCreationServiceType) as INameCreationService;

            string errorString;
            if (ValidName(this.nameTextBox.Text,
                          this.dataGridViewColumns,
                          container,
                          nameCreationService,
                          this.liveDataGridView.Columns,
                          !this.persistChangesToDesigner,
                          out errorString))
            {
              this.AddColumn();
              this.Close();
            }
            else
            {
              IUIService uiService = (IUIService)this.liveDataGridView.Site.GetService(UIServiceType);
              DataGridDesigner.ShowErrorDialog(uiService, errorString, this.liveDataGridView);
            }
            return true;
        }
      }

      return base.ProcessDialogKey(keyData);
    }

    internal void Start(int insertAtPosition, bool persistChangesToDesigner)
    {
      this.insertAtPosition = insertAtPosition;
      this.persistChangesToDesigner = persistChangesToDesigner;

      if (this.persistChangesToDesigner)
      {
        this.initialDataGridViewColumnsCount = this.liveDataGridView.Columns.Count;
      }
      else
      {
        this.initialDataGridViewColumnsCount = -1;
      }
    }

    private void SetDefaultDataGridViewColumnType(Type type)
    {
      TypeConverter imageTypeConverter = TypeDescriptor.GetConverter(typeof(System.Drawing.Image));

      if (type == typeof(bool) || type == typeof(System.Windows.Forms.CheckState))
      {
        this.columnTypesCombo.SelectedIndex = this.TypeToSelectedIndex(typeof(System.Windows.Forms.DataGridViewCheckBoxColumn));
      }
      else if (typeof(System.Drawing.Image).IsAssignableFrom(type) || imageTypeConverter.CanConvertFrom(type))
      {
        this.columnTypesCombo.SelectedIndex = this.TypeToSelectedIndex(typeof(System.Windows.Forms.DataGridViewImageColumn));
      }
      else
      {
        this.columnTypesCombo.SelectedIndex = this.TypeToSelectedIndex(typeof(System.Windows.Forms.DataGridViewTextBoxColumn));
      }
    }

    private int TypeToSelectedIndex(Type type)
    {
      for (int i = 0; i < this.columnTypesCombo.Items.Count; i++)
      {
        if (type == ((ComboBoxItem)this.columnTypesCombo.Items[i]).ColumnType)
        {
          return i;
        }
      }

      Debug.Assert(false, "we should have found a type by now");

      return -1;
    }

    public static bool ValidName(string name,
                                 Collection<DataGridColumn> columns,
                                 IContainer container,
                                 INameCreationService nameCreationService,
                                 DataGridMainColumnCollection liveColumns,
                                 bool allowDuplicateNameInLiveColumnCollection)
    {
      foreach (DataGridColumn col in columns)
      {
        if (col.Name == name)
        {
          return false;
        }
      }

      if (container != null && container.Components[name] != null)
      {
        if (!allowDuplicateNameInLiveColumnCollection || liveColumns == null || !liveColumns.Contains(name))
        {
          return false;
        }
      }

      if (nameCreationService != null && !nameCreationService.IsValidName(name))
      {
        if (!allowDuplicateNameInLiveColumnCollection || liveColumns == null || !liveColumns.Contains(name))
        {
          return false;
        }
      }

      return true;
    }

    public static bool ValidName(string name,
                                 Collection<DataGridColumn> columns,
                                 IContainer container,
                                 INameCreationService nameCreationService,
                                 DataGridMainColumnCollection liveColumns,
                                 bool allowDuplicateNameInLiveColumnCollection,
                                 out string errorString)
    {
      foreach (DataGridColumn col in columns)
      {
        if (col.Name == name)
        {
          errorString = "DataGridViewDuplicateColumnName";// SR.GetString(SR.DataGridViewDuplicateColumnName, name);
          return false;
        }
      }

      if (container != null && container.Components[name] != null)
      {
        if (!allowDuplicateNameInLiveColumnCollection || liveColumns == null || !liveColumns.Contains(name))
        {
          errorString = "DesignerHostDuplicateName";// SR.GetString(SR.DesignerHostDuplicateName, name);
          return false;
        }
      }

      if (nameCreationService != null && !nameCreationService.IsValidName(name))
      {
        if (!allowDuplicateNameInLiveColumnCollection || liveColumns == null || !liveColumns.Contains(name))
        {
          errorString = "CodeDomDesignerLoaderInvalidIdentifier";// SR.GetString(SR.CodeDomDesignerLoaderInvalidIdentifier, name);
          return false;
        }
      }

      errorString = string.Empty;
      return true;
    }

    private class ListBoxItem
    {
      readonly Type propertyType;
      readonly string propertyName;

      public ListBoxItem(Type propertyType, string propertyName)
      {
        this.propertyType = propertyType;
        this.propertyName = propertyName;
      }

      public Type PropertyType
      {
        get
        {
          return this.propertyType;
        }
      }

      public string PropertyName
      {
        get
        {
          return this.propertyName;
        }
      }

      public override string ToString()
      {
        return this.propertyName;
      }
    }

    private class ComboBoxItem
    {
      readonly Type columnType;
      public ComboBoxItem(Type columnType)
      {
        this.columnType = columnType;
      }

      public override string ToString()
      {
        return this.columnType.Name;
      }

      public Type ColumnType
      {
        get
        {
          return this.columnType;
        }
      }
    }
  }
}
