using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
using System.Collections;

using Softelvdm.SftTreeNET;
using Softelvdm.Controls;

namespace WindowsApplication1 {
    public partial class MergeSample1 : Form {
        public MergeSample1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            // This sample demonstrates cell merging. In this sample, vertical merging
            // is based on empty subordinate cells (MergeStyle = MergeStyleEnum.EmptyCells).
            // To prepare for this sample, create a new project with a blank form and add
            // a SftTree/NET control named sftTree1.
            // In addition, adjust the following FromFile method to use a (small) bitmap
            // that is located on your system.
            Image img = Bitmap.FromFile("..\\..\\test.gif");
            CellClass cell;

            // Most of this initialization code could be eliminated by designing the control.
            // Here, all header area, footer area and item area cells are simply populated 
            // with text. The actual cell merging portion happens later on
            sftTree1.Initializing = true;
            sftTree1.Columns.Count = 5;
            sftTree1.Headers.Rows = 3;
            sftTree1.Footers.Rows = 3;
            for (int r = 0 ; r < sftTree1.Headers.Rows ; ++r) {
                for (int c = 0; c < sftTree1.Columns.Count; ++c) {
                    cell = sftTree1.Headers[r, c]; // access each header cell
                    cell.Text = "Column " + c.ToString(); // set the title
                }
            }
            for (int r = 0; r < sftTree1.Footers.Rows; ++r) {
                for (int c = 0; c < sftTree1.Columns.Count; ++c) {
                    cell = sftTree1.Footers[r, c]; // access each header cell
                    cell.Text = "Column " + c.ToString(); // set the title
                }
            }
            ItemClass item;
            for (int i = 0; i < 10; ++i) {
                item = sftTree1.ItemCollection.Add(new string[] { "Text 0", "Text 1", "Text 2", "Text 3" });
                item.RowHeader.Text = "Row " + i.ToString();
            }
            // End of initialization (not relevant for this sample)

            // In this sample, vertical merging is based on empty subordinate cells.
            sftTree1.MergeStyle = MergeStyleEnum.EmptyCells;

            // Merge all cells in the column header vertically (in the second column)
            // clear the text in all subordinate cells except for the first, main cell
            sftTree1.Headers.MaxLines = 4; // allow up to 4 text lines 
            for (int r = 0; r < sftTree1.Headers.Rows; ++r) {
                cell = sftTree1.Headers[r, 1];
                cell.MergeWithLower = BoolOptionalEnum.True;
                cell.AllowMergeFromUpper = BoolOptionalEnum.True;
                cell.Parts.Clear();
            }
            TextPartClass tp = new TextPartClass("Vertical");
            tp.Format |= StringFormatFlags.DirectionVertical;
            sftTree1.Headers[0, 1].Parts.Add(tp);
            sftTree1.Headers[0, 1].Parts.Add(new ImagePartClass(img));
            tp = new TextPartClass("Cell merging in\na column header");
            sftTree1.Headers[0, 1].Parts.Add(tp);

            // Horizontally merge column header cells in row 1, columns 3 + 4
            sftTree1.Headers[1, 3].MergeWithNext = BoolOptionalEnum.True;
            sftTree1.Headers[1, 4].AllowMergeFromPrevious = BoolOptionalEnum.True;
            sftTree1.Headers[1, 3].Text = "Horizontally merged cells";
            sftTree1.Headers[1, 3].Image = img;
            sftTree1.Headers[1, 4].Parts.Clear();

            // Vertically merge some cells in the column footer (in the last column)
            sftTree1.Footers.MaxLines = 4; // allow up to 4 text lines 
            for (int r = 1; r < sftTree1.Footers.Rows; ++r) {
                cell = sftTree1.Footers[r, 4];
                cell.MergeWithLower = BoolOptionalEnum.True;
                cell.AllowMergeFromUpper = BoolOptionalEnum.True;
                cell.Parts.Clear();
            }
            sftTree1.Footers[1, 4].Parts.Add(new ImagePartClass(img));
            sftTree1.Footers[1, 4].Text = "Vertical cell merging\n(only two cells)";

            // Horizontally merge cells in the second item (column 1 through last)
            item = sftTree1.ItemCollection[1];
            for (cell = item.Cells[1]; cell != null; cell = cell.NextDisplayed) {
                cell.AllowMergeFromPrevious = BoolOptionalEnum.True;
                cell.MergeWithNext = BoolOptionalEnum.True;
                cell.Parts.Clear();
            }
            item.Cells[1].Parts.Add(new ImagePartClass(img));
            item.Cells[1].Text = "Horizontally merged cells";

            // Vertically merge a few cells (in the third column) starting with the fifth item.
            for (item = sftTree1.ItemCollection[4] ; item != null; item = item.NextSibling) {
                cell = item.Cells[2];
                cell.AllowMergeFromUpper = BoolOptionalEnum.True;
                cell.MergeWithLower = BoolOptionalEnum.True;
                cell.Parts.Clear();
            }
            cell = sftTree1.ItemCollection[4].Cells[2];
            cell.Text = "Vertically\nmerged\ncells";
            cell.Image = img;

            // Merge 3 row headers, starting at the second item
            int count = 3;
            for (item = sftTree1.ItemCollection[1]; item != null && count > 0; count--, item = item.NextSibling) {
                RowHeaderClass rhd = item.RowHeader;
                rhd.AllowMergeFromUpper = BoolOptionalEnum.True;
                rhd.MergeWithLower = BoolOptionalEnum.True;
                rhd.Parts.Clear();
            }
            item = sftTree1.ItemCollection[1];
            item.RowHeader.Text = "Vertical";
            Font f = new Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Point);
            item.RowHeader.TextPart.Font = f;
            item.RowHeader.TextPart.Format |= StringFormatFlags.DirectionVertical;
            item.RowHeader.Parts.Add(new ImagePartClass(img));

            // Make column widths and row header area width optimal
            sftTree1.Columns.MakeOptimal(0, false);
            sftTree1.RowHeaders.MakeOptimal(0, false);
            // Activate the horizontal scrollbar
            sftTree1.RecalcHorizontalExtent();
            sftTree1.Initializing = false;
        }

        // ItemClick event
        private void sftTree1_ItemClick(object sender, ItemClickEventArgs e) {
            Debug.Write("** ItemClick");
            int itemIndex = -1;
            if (e.Item != null) 
                itemIndex = e.Item.VisibleIndex;
            if (itemIndex >= 0)
                Debug.Write(" Row " + itemIndex.ToString());
            int colIndex = -1;
            if (e.Cell != null)
                colIndex = e.Cell.ColumnIndex;
            if (colIndex >= 0)
                Debug.Write(" Column " + colIndex.ToString());
            DumpValues(e);
        }

        private void sftTree1_ItemDoubleClick(object sender, ItemClickEventArgs e) {
            Debug.Write("** ItemDoubleClick");
            DumpValues(e);
        }

        // This is a small helper routine to show all properties and fields of an object
        private void DumpValues(object o) {
            PropertyInfo[] api = o.GetType().GetProperties();
            foreach (PropertyInfo pi in api)
                Debug.Write(" " + pi.Name + " " + pi.GetValue(o, new object[] { }));
            FieldInfo[] afi = o.GetType().GetFields();
            foreach (FieldInfo fi in afi)
                Debug.Write(" " + fi.Name + " " + fi.GetValue(o));
            Debug.WriteLine("");
        }

    }
}