#region Using directives

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.SqlServer.Management.Smo;
using System.Collections;

#endregion

namespace SMODemo
{

struct ColumnStruct : IComparable
{
  public string Table;
  public string Column;
  public string Type;
  public int Width;
  public string Nullable;
  public string Default;
  public string Tables;

  int IComparable.CompareTo(object obj)
  {
    int result = this.Column.CompareTo(((ColumnStruct)obj).Column);
    if (result == 0)
    {
      result = this.Type.CompareTo(((ColumnStruct)obj).Type);
    }
    return result;
  }
}

partial class Form1 : Form
{

  private System.Text.StringBuilder SB = new System.Text.StringBuilder();
  // private ArrayList Tables = new ArrayList();
  private ArrayList AllColumns = new ArrayList();
  private ArrayList Concordance = new ArrayList();

  public Form1()
  {
    InitializeComponent();
  }
  
  public void Log(string Msg)
  {
    SB.Append(Msg);
  }

  private void btnGo_Click(object sender, EventArgs e)
  {
    ColumnStruct CS, ITM;
    int FoundIndex;

    // Screen cursor

    this.Cursor = Cursors.WaitCursor;

    // Connect to server

    Server SRV = new Server("(local)");

    // Load all Tables and Columns

    foreach (Table TBL in SRV.Databases["Northwind"].Tables)
    {
      this.Text = TBL.Name;
      foreach (Column COL in TBL.Columns)
      {
        CS = new ColumnStruct();
        CS.Table = TBL.Name;
        CS.Column = COL.Name;
        CS.Type = COL.DataType.Name;
        CS.Width = COL.DataType.MaximumLength;
        if (COL.Nullable == true)
          CS.Nullable = "NULL";
        else
          CS.Nullable = "NOT NULL";
        CS.Default = COL.Default;
        AllColumns.Add(CS);
      }
    }

    // Sort

    AllColumns.Sort();

    // Consolidate

    foreach (ColumnStruct COL in AllColumns)
    {

      // Look for match

      FoundIndex = -1;
      foreach (ColumnStruct ConCol in Concordance)
      {
        if (COL.Column == ConCol.Column &&
            COL.Type == ConCol.Type &&
            COL.Width == ConCol.Width &&
            COL.Default == ConCol.Default)
        {
            FoundIndex = Concordance.IndexOf(ConCol);
            break;
        }
      }

      // Add or Update?

        if (FoundIndex == -1)
        {
          ITM = new ColumnStruct();
          ITM.Column = COL.Column;
          ITM.Type = COL.Type;
          ITM.Width = COL.Width;
          ITM.Default = COL.Default;
          ITM.Nullable = COL.Nullable;
          ITM.Tables = COL.Table;
          Concordance.Add(ITM);
        }
        else
        {
          ITM = (ColumnStruct)Concordance[FoundIndex];
          ITM.Tables += ", " + COL.Table;
          Concordance[FoundIndex] = ITM;
        }
      }

    // Display

    ColumnStruct LastCol = new ColumnStruct();
    string Format;

    foreach (ColumnStruct COL in Concordance)
    {
      if (LastCol.Column == COL.Column)
        Format = "<font color = 'red' size='3'>";
          else
        Format = "<font color = 'black' size='2'>";
      LastCol = COL;
      Log("<TR><TD>" + Format + COL.Column + "</font></TD>" +
          "<TD>" + COL.Type + "</TD>" +
          "<TD>" + COL.Width + "</TD>" +
          "<TD>" + COL.Nullable + "</TD>" +
          "<TD>" + COL.Tables + "</TD></TR>");
    }

    // Done

    webBrowser.DocumentText = 
      "<html><style>BODY {Font-Family: Verdana; Font-Size: 1}</style>" +
      "<table border='1' cellspacing='3' cellpadding='3'>" + SB.ToString() + "</table></html>";

    // Screen cursor

    this.Cursor = Cursors.Default;
  }

  private void btnCancel_Click(object sender, EventArgs e)
  {
    Application.Exit();
  }
 }
}