larsbloch
10/5/2017 - 6:00 PM

ASPComp_ThreeLayerData

using System;
using System.Linq;
using System.Collections.Generic;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;

public class ComponentThreeLayerData
{
    Helper_SQLServerData dbCallHelper;
    DataTable table;
    string selectSQL = "";
    Table mainTable = new Table();
    System.Web.UI.Page resetter;
    string uniqueControlIDValue = "";
    int standardWidth = 150;
    int standardHeight = 18;
    int headerHeight = 24;
    List<int> level1Columns = new List<int>();
    List<int> level2Columns = new List<int>();
    List<int> level3Columns = new List<int>();
    List<ObjIntColumnName> newColumnNames = new List<ObjIntColumnName>();
    List<ObjIntInput> inputFields = new List<ObjIntInput>();
    bool showColumnHeader = true;
    int headLineLastWritten = 0;

    public delegate void MyEventHandler(object source, ButPressEvent e);
    public event MyEventHandler OnButClick;
    #region constructor and settings
    public ComponentThreeLayerData(string serverName, string database, string selectSQL, System.Web.UI.Page resetter)
    {
        dbCallHelper = new Helper_SQLServerData(serverName, database);
        this.resetter = resetter;
        this.selectSQL = selectSQL;
    }
    #region settings
    public void SetGroups(int level, int columnNumberFrom, int columnNumberTo, int extraNumber1, int extraNumber2, int extraNumber3)
    {
        for (int i = columnNumberFrom; i <= columnNumberTo; i++)
        {
            if (level == 1)
                level1Columns.Add(i);
            else if (level == 2)
                level2Columns.Add(i);
            else if (level == 3)
                level3Columns.Add(i);
            else
                throw new Exception("Level has to be between 1 and 3");
        }
        if (extraNumber1 > -1)
        {
            if (level == 1)
                level1Columns.Add(extraNumber1);
            else if (level == 2)
                level2Columns.Add(extraNumber1);
            else if (level == 3)
                level3Columns.Add(extraNumber1);
            else
                throw new Exception("Level has to be between 1 and 3");
        }
        if (extraNumber2 > -1)
        {
            if (level == 1)
                level1Columns.Add(extraNumber2);
            else if (level == 2)
                level2Columns.Add(extraNumber2);
            else if (level == 3)
                level3Columns.Add(extraNumber2);
            else
                throw new Exception("Level has to be between 1 and 3");
        }
        if (extraNumber3 > -1)
        {
            if (level == 1)
                level1Columns.Add(extraNumber3);
            else if (level == 2)
                level2Columns.Add(extraNumber3);
            else if (level == 3)
                level3Columns.Add(extraNumber3);
            else
                throw new Exception("Level has to be between 1 and 3");
        }
    }
    public void SetAddInput(int groupNumber, string headerNameForInput, Com3LayerInputType inputType, int columnSpan, int height, string text)
    {
        if ( inputType == Com3LayerInputType.Text)
        {

        }
        else
            throw new Exception("This addinput method can only be used with text fields");
    }
    public void SetAddInput(int groupNumber, string headerNameForInput, Com3LayerInputType inputType, int columnSpan, int height, List<ObjCom3LayerKeyValue> keyValues)
    {
        if (keyValues.Count < 1 && inputType == Com3LayerInputType.List)
            throw new Exception("input list has to have at least one entry");
        ObjIntInput input = new ObjIntInput();
        input.HeaderNameForInput = headerNameForInput;
        input.GroupNumber = groupNumber;
        input.InputType = inputType;
        input.KeyValueList = keyValues;
        input.ColSpan = columnSpan;
        input.Height = height;
        inputFields.Add(input);
    }
    public void SetNewColumnName(string oldColumnName, string newColumnName)
    {
        ObjIntColumnName columnName = new ObjIntColumnName();
        columnName.ColumnName = oldColumnName;
        columnName.NewColumnName = newColumnName;
        newColumnNames.Add(columnName);
    }
    public void SetShowColumnHeader(bool value)
    {
        showColumnHeader = value;
    }
    /// <summary>
    /// "User ID=username; Password=password;"
    /// </summary>
    public void SetUserNameAndPasswordForDB(string value)
    {
        dbCallHelper.SettingUsernamePassword(value);

    }
    public void SetAddUniqueControls(string uniqueStringValue)
    {
        uniqueControlIDValue = uniqueStringValue;
    }
    #endregion
    #endregion
    #region Main logic
    public void CreateComponent(Panel control)
    {
        table = dbCallHelper.GetDataFromSQL(selectSQL);
        mainTable = new Table();
        mainTable.CssClass = "Com3LayerTable";
        mainTable.ID = "MainTable" + uniqueControlIDValue;

        string group1 = string.Empty;
        string group2 = string.Empty;
        string group3 = string.Empty;
        for (int i = 0; i < table.Rows.Count; i++)
        {
            //
            // Check which level to create the row
            //
            DataRow r = table.Rows[i];

            if (group1 != GetLevelString(1, r))
            {
                if (group1 != string.Empty)
                    CreateDataInput(r, i);
                CreateGroup1(r);
                group1 = GetLevelString(1, r);
                group2 = string.Empty;
                group3 = string.Empty;
            }
            if (group2 != GetLevelString(2, r))
            {
                CreateGroup2(r);
                group2 = GetLevelString(2, r);
                group3 = string.Empty;
            }
            if (group3 != GetLevelString(3, r))
            {
                CreateGroup3(r);
                group3 = GetLevelString(3, r);
            }
            //If it is the last row. Create the last data inputs
            if (i == table.Rows.Count-1)
                CreateDataInput(r, table.Rows.Count);
        }

        control.Controls.Add(mainTable);
    }
    private void CreateGroup1(DataRow r)
    {
        TableRow tableRow = new TableRow();
        tableRow.Height = standardHeight;

        tableRow.CssClass = "Com3LayerTableRowGroup1";
        string text = string.Empty;
        foreach (int columnIndex in level1Columns)
        {
            if (text == string.Empty)
                text += CorrectSQLString(r, columnIndex);
            else
                text += "   -   " + CorrectSQLString(r, columnIndex);
        }
        TableCell tableCell = new TableCell();
        tableCell.CssClass = "Com3LayerTableCellGroup1";
        tableCell.ColumnSpan = 100;

        TextBox t = new TextBox();
        t.Text = text;
        t.Width = new Unit("95%");
        t.CssClass = "Com3LayerTableTextBoxGroup1";
        t.ReadOnly = true;
        tableCell.Controls.Add(t);
        tableRow.Controls.Add(tableCell);
        mainTable.Controls.Add(tableRow);
    }
    private void CreateGroup2(DataRow r)
    {
        //create headers if true
        if (showColumnHeader == true && headLineLastWritten != 2)
        {
            headLineLastWritten = 2;

            TableRow tableRowH = new TableRow();
            tableRowH.Height = headerHeight;
            tableRowH.CssClass = "Com3LayerTableRowGroup2H";


            foreach (int columnIndex in level2Columns)
            {
                TableCell tableCellH = new TableCell();
                tableCellH.CssClass = "Com3LayerTableCellGroup2";
                tableCellH.Height = headerHeight;
                tableCellH.Width = standardWidth;


                TextBox t = new TextBox();
                t.Text = GetColumnName(table.Columns[columnIndex].ColumnName);
                t.Height = headerHeight;
                t.Width = new Unit("95%");
                t.CssClass = "Com3LayerTableTextBoxGroup2H";
                t.ReadOnly = true;

                if (level2Columns.LastOrDefault().Equals(columnIndex) && inputFields.Count == 0)
                    tableCellH.ColumnSpan = 100;


                tableCellH.Controls.Add(t);
                tableRowH.Controls.Add(tableCellH);
            }

            mainTable.Controls.Add(tableRowH);
        }
        //Create data
        TableRow tableRow = new TableRow();
        tableRow.Height = standardHeight;
        //tableRow.Width = standardWidth;
        tableRow.CssClass = "Com3LayerTableRowGroup2";

        foreach (int columnIndex in level2Columns)
        {
            TableCell tableCell = new TableCell();
            tableCell.CssClass = "Com3LayerTableCellGroup2";
            tableCell.Height = headerHeight;
            tableCell.Width = standardWidth;

            TextBox t = new TextBox();
            t.Text = CorrectSQLString(r, columnIndex);
            t.Height = standardHeight;
            t.Width = new Unit("95%");
            t.CssClass = "Com3LayerTableTextBoxGroup2";
            t.ReadOnly = true;

            if (level2Columns.LastOrDefault().Equals(columnIndex) && inputFields.Count == 0)
                tableCell.ColumnSpan = 100;

            tableCell.Controls.Add(t);
            tableRow.Controls.Add(tableCell);
        }

        mainTable.Controls.Add(tableRow);
    }
    private void CreateGroup3(DataRow r)
    {
        //create headers if true
        if (showColumnHeader == true && headLineLastWritten != 3)
        {
            headLineLastWritten = 3;
            InsertEmptyRow(standardHeight);
            TableRow tableRowH = new TableRow();
            tableRowH.Height = headerHeight;
            tableRowH.CssClass = "Com3LayerTableRowGroup3";


            foreach (int columnIndex in level3Columns)
            {
                TableCell tableCellH = new TableCell();
                tableCellH.CssClass = "Com3LayerTableCellGroup3";
                tableCellH.Height = headerHeight;
                tableCellH.Width = standardWidth;

                TextBox t = new TextBox();
                t.Text = GetColumnName(table.Columns[columnIndex].ColumnName);
                t.Height = headerHeight;
                t.Width = new Unit("95%");
                t.CssClass = "Com3LayerTableTextBoxGroup3H";
                t.ReadOnly = true;

                //if (level3Columns.LastOrDefault().Equals(columnIndex))
                //    tableCellH.ColumnSpan = 5;

                tableCellH.Controls.Add(t);
                tableRowH.Controls.Add(tableCellH);
            }
            mainTable.Controls.Add(tableRowH);
        }
        TableRow tableRow = new TableRow();
        tableRow.Height = standardHeight;
        //tableRow.Width = standardWidth;
        tableRow.CssClass = "Com3LayerTableRowGroup3";

        foreach (int columnIndex in level3Columns)
        {
            TableCell tableCell = new TableCell();
            tableCell.CssClass = "Com3LayerTableCellGroup3";
            tableCell.Height = standardHeight;
            tableCell.Width = standardWidth;

            TextBox t = new TextBox();

            t.Text = CorrectSQLString(r, columnIndex);
            t.Height = standardHeight;
            t.Width = new Unit("95%");
            t.CssClass = "Com3LayerTableTextBoxGroup3";
            t.ReadOnly = true;

            //if (level3Columns.LastOrDefault().Equals(columnIndex))
            //    tableCell.ColumnSpan = 5;

            tableCell.Controls.Add(t);
            tableRow.Controls.Add(tableCell);
        }
        mainTable.Controls.Add(tableRow);
    }
    private void CreateDataInput(DataRow r, int rowNumber)
    {
        if (inputFields.Count > 0)
        {
            InsertEmptyRow(standardHeight);

            //Add headers for the inputs
            if (showColumnHeader == true)
            {
                TableRow tableRowH = CreateTableRow("Com3LayerTableRowInput", -1, headerHeight);
                foreach (ObjIntInput inpField in inputFields)
                {
                    TableCell tableCellH = CreateTableCell("Com3LayerTableCellInput", standardWidth, headerHeight);

                    TextBox t = CreateTextBox(inpField.HeaderNameForInput, "Com3LayerTableTextBoxInputH", TextBoxMode.SingleLine, null, true);

                    tableCellH.Controls.Add(t);
                    tableRowH.Controls.Add(tableCellH);
                }
                mainTable.Controls.Add(tableRowH);
            }
            //Add the specific inputs
            TableRow tableRow = CreateTableRow("Com3LayerTableRowInput", -1, headerHeight);
            foreach (ObjIntInput inpField in inputFields)
            {
                TableCell tableCell = CreateTableCell("Com3LayerTableCellInput", standardWidth, standardHeight);

                if (inpField.InputType == Com3LayerInputType.List)
                {
                    DropDownList ddl = new DropDownList();
                    foreach (ObjCom3LayerKeyValue value in inpField.KeyValueList)
                        ddl.Items.Add(value.Value);
                    ddl.Width = new Unit("95%");
                    ddl.BorderWidth = 1;
                    ddl.TextChanged += T_TextChanged;
                    ddl.AutoPostBack = true;
                    ddl.BorderColor = System.Drawing.Color.LightGray;
                    ddl.CssClass = "Com3LayerTableTextBoxInput";
                    ddl.ID = "INPDDL00000" + rowNumber;


                    tableCell.Controls.Add(ddl);

                    tableRow.Controls.Add(tableCell);
                }
                if (inpField.InputType == Com3LayerInputType.Text)
                {
                    TextBox t = CreateTextBox(inpField.HeaderNameForInput, "Com3LayerTableTextBoxInput", TextBoxMode.MultiLine, "INPTEXT0000" + rowNumber, false);
                    t.BorderWidth = 1;
                    t.BorderColor = System.Drawing.Color.LightGray;
                    t.TextChanged += T_TextChanged;
                    t.AutoPostBack = true;

                    if (inpField.Height > -1)
                        tableCell.Height = inpField.Height;

                    tableCell.Controls.Add(t);
                    tableCell.ColumnSpan = inpField.ColSpan;
                    tableRow.Controls.Add(tableCell);
                }
            }
            //Create Save button
            TableCell tableCellSB = CreateTableCell("Com3LayerTableCellInput", standardWidth, standardHeight);


            Button b = new Button();
            b.Text = "Gem";
            b.ID = "SAVE000000" + rowNumber;
            b.Click += B_Click;
            tableCellSB.Controls.Add(b);
            tableRow.Controls.Add(tableCellSB);

            mainTable.Controls.Add(tableRow);
        }
    }
    #endregion
    #region events
    private void T_TextChanged(object sender, EventArgs e)
    {

        Control t = (Control)sender;
        int textBoxRowNumber = GetRowNumberFromID(t.ID);
        foreach (Control c in TableControls(false))
        {
            if (c.ID.StartsWith("SAVE") && GetRowNumberFromID(c.ID) == textBoxRowNumber)
            {
                Button b = (Button)c;
                b.Text = "Gem";
                break;
            }
        }
    }

    private void B_Click(object sender, EventArgs e)
    {
        Button b = (Button)sender;
        int buttonRowNumber = GetRowNumberFromID(b.ID);
        b.Text = "Gemt !";
        List<string> inputs = new List<string>();

        foreach (Control c in TableControls(false))
        {
            //Only return the  corresponding INP fieds which matches the button
            if (c.ID.StartsWith("INP") && GetRowNumberFromID(c.ID) == buttonRowNumber)
            {
                if (c is TextBox)
                {
                    TextBox t = (TextBox)c;
                    inputs.Add(t.Text);
                }
                else if (c is DropDownList)
                {
                    DropDownList t = (DropDownList)c;
                    inputs.Add(t.Text);
                }
            }
        }

        OnButClick(this, new ButPressEvent(table.Rows[buttonRowNumber], inputs));
    }
    #endregion
    #region helperMethods
    private int GetRowNumberFromID(string id)
    {
        string rowNumber = id.Substring(10, id.Length - 10);
        return Convert.ToInt32(rowNumber);
    }
    private List<Control> TableControls(bool includeNulls)
    {
        List<Control> returnValue = new List<Control>();
        foreach (TableRow r in mainTable.Controls)
        {
            foreach (TableCell c in r.Controls)
            {
                foreach (Control control in c.Controls)
                {
                    if (includeNulls)
                        returnValue.Add(control);
                    else
                    {
                        if (control.ID != null)
                            returnValue.Add(control);
                    }
                }
            }

        }

        return returnValue;
    }
    private void InsertEmptyRow(int height)
    {
        TableRow tableRowEmpty = new TableRow();
        tableRowEmpty.Height = height;
        tableRowEmpty.CssClass = "Com3LayerTableRowEmpty";
        mainTable.Controls.Add(tableRowEmpty);
    }
    private string CorrectSQLString(DataRow r, int columnIndex)
    {
        string returnValue = "";
        DataColumn d = table.Columns[columnIndex];
        if (d.DataType.Name == "DateTime")
        {
            if (r.Field<object>(d.ColumnName) != null)
            {
                DateTime dt = r.Field<DateTime>(d.ColumnName);

                returnValue = dt.ToString("yyyy-MM-dd hh:mm:ss");
            }
        }
        else
            returnValue = r[columnIndex].ToString();
        return returnValue;
    }
    private string GetColumnName(string columnName)
    {
        string returnValue = columnName;
        ObjIntColumnName objColumnName = newColumnNames.Find(c => c.ColumnName.ToUpper() == columnName.ToUpper());
        if (objColumnName != null)
            returnValue = objColumnName.NewColumnName;

        return returnValue;
    }
    private string GetLevelString(int level, DataRow r)
    {
        string returnValue = "";
        if (level == 1)
        {
            foreach (int i in level1Columns)
                returnValue += r[i].ToString();
        }
        else if (level == 2)
        {
            foreach (int i in level2Columns)
                returnValue += r[i].ToString();
        }
        else if (level == 3)
        {
            foreach (int i in level3Columns)
                returnValue += r[i].ToString();
        }

        return returnValue;
    }

    private TableCell CreateTableCell(string cssClass, int width, int height)
    {
        TableCell tableCell = new TableCell();
        tableCell.CssClass = cssClass;
        if (width > -1)
            tableCell.Width = width;
        if (height > -1)
            tableCell.Height = height;
        return tableCell;
    }
    private TableRow CreateTableRow(string cssClass, int width, int height)
    {
        TableRow tableRow = new TableRow();
        tableRow.CssClass = cssClass;
        if (width > -1)
            tableRow.Width = width;
        if (height > -1)
            tableRow.Height = height;
        return tableRow;
    }
    private TextBox CreateTextBox(string text, string cssClass, TextBoxMode textBoxMode, string ID, bool readOnly)
    {
        TextBox t = new TextBox();
        t.CssClass = cssClass;
        t.Text = text;
        t.Width = new Unit("95%");
        t.Height = new Unit("95%");
        t.TextMode = textBoxMode;
        t.CssClass = "Com3LayerTableTextBoxInput";
        t.ID = ID;
        t.ReadOnly = readOnly;

        return t;
    }
    #endregion
}
#region public objects
public class ButPressEvent : EventArgs
{
    private DataRow dataRow;
    private List<string> inputs;
    public ButPressEvent(DataRow r, List<string> inputs)
    {
        dataRow = r;
        this.inputs = inputs;
    }
    public DataRow GetDataRow()
    {
        return dataRow;
    }
    public List<string> GetInputs()
    {
        return inputs;
    }
}
internal class ObjIntColumnName
{
    public string ColumnName;
    public string NewColumnName;
}
internal class ObjIntInput
{
    public string HeaderNameForInput;
    public int GroupNumber;
    public Com3LayerInputType InputType;
    public int ColSpan;
    public int Height;
    public List<ObjCom3LayerKeyValue> KeyValueList = new List<ObjCom3LayerKeyValue>();
}
public class ObjCom3LayerKeyValue
{
    public string Key;
    public string Value;
    public ObjCom3LayerKeyValue(string Key, string Value)
    {
        this.Key = Key;
        this.Value = Value;
    }

}
public enum Com3LayerInputType
{
    List = 1,
    Text = 2
}
#endregion