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

using Softelvdm.Controls;
using Softelvdm.SftTreeNET;
using Microsoft.VisualBasic;

namespace DemoSample {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void Optimize() {
            sftTree1.Initializing = true;
            sftTree1.Columns.MakeOptimal(0, false);
            sftTree1.RowHeaders.MakeOptimal(0, false);
            sftTree1.Splitter.MakeOptimal();
            sftTree1.RecalcHorizontalExtent();
            sftTree1.Initializing = false;
        }

        private void AdjustInfo() {

            Rectangle cr = sftTree1.ClientRectangle;
            int xcenter = cr.Width / 2;
            int ybottom = cr.Height - SystemInformation.HorizontalScrollBarHeight;
            Rectangle r;

            InfoTip.Clear();

            InfoTip.Add(4, new Point(xcenter / 2, ybottom / 4), "", 
                        "This demo will show some of the many features you will find in this product.\n\n" +
                        "To end this demo, please close this window.", ArrowLocationEnum.TopLeft, null, null);

            InfoTip.Add(5, new Point(xcenter / 2, ybottom / 4), "", "From simple tree control...", ArrowLocationEnum.TopLeft, SimpleTree, null);
            InfoTip.Add(5, new Point(xcenter / 2, ybottom / 4), "", "...back to a grid-like hierarchical tree control", ArrowLocationEnum.TopLeft, ComplexTree, null);

            InfoTip.Add(new Point(xcenter, 0 + sftTree1.Headers.Height / 2), "Optional headers with one or multiple rows");
            InfoTip.Add(new Point(xcenter, ybottom - sftTree1.Footers.Height / 2), "Optional footers with one or multiple rows");

            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[5].RowHeader);
            InfoTip.Add(new Point(0 + sftTree1.RowHeaders.Width / 2, r.Y), "", "Optional row headers for items, headers and footers", ArrowLocationEnum.LeftTop, null, RowHeadersOff);
            InfoTip.Add(new Point(0 + sftTree1.RowHeaders.Width / 2, r.Y), "", "Without row headers", ArrowLocationEnum.LeftTop, null, RowHeadersOn);

            Point pt = new Point(sftTree1.Splitter.Area.Location.X + sftTree1.Splitter.Area.Width / 2, ybottom / 2);
            InfoTip.Add(pt, "Optional splitter bar", ArrowLocationEnum.TopLeft);
            InfoTip.Add(pt, "", "Without splitter bar", ArrowLocationEnum.TopLeft, SplitterOff, SplitterOn);

            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[0].Cells[1]);
            InfoTip.Add(CenterOf(r), "Cells can display one or multiple images (and other parts)", ArrowLocationEnum.LeftTop);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[1].Cells[1]);
            InfoTip.Add(CenterOf(r), "Cells can contain clickable buttons (and other parts)", ArrowLocationEnum.LeftTop);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[2].Cells[1]);
            InfoTip.Add(CenterOf(r), "Cells can contain checkboxes (and other parts)", ArrowLocationEnum.LeftTop);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[3].Cells[1]);
            InfoTip.Add(CenterOf(r), "Cells can contain radiobuttons (and other parts)", ArrowLocationEnum.LeftTop);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[4].Cells[1]);
            InfoTip.Add(CenterOf(r), "Cells can contain dropdown buttons (and other parts)", ArrowLocationEnum.BottomLeft);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[5].Cells[1]);
            InfoTip.Add(CenterOf(r), "Cells can contain progress bars (and other parts)", ArrowLocationEnum.LeftTop);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[1].Cells[1]);
            InfoTip.Add(CenterOf(r), "Even many clickable parts within the same cell");
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Cells[0]);
            InfoTip.Add(CenterOf(r), "Any one column can display the hierarchy\nwith tree lines and item images", ArrowLocationEnum.BottomLeft);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Cells[1]);
            InfoTip.Add(CenterOf(r), "", "Any one column can display the hierarchy\nwith tree lines and item images", ArrowLocationEnum.BottomLeft, HierarchyOnColumn1, null);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Cells[2]);
            InfoTip.Add(CenterOf(r), "", "Any one column can display the hierarchy\nwith tree lines and item images", ArrowLocationEnum.BottomLeft, HierarchyOnColumn2, null);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Cells[0]);
            InfoTip.Add(CenterOf(r), "", "Any one column can display the hierarchy\nwith tree lines and item images", ArrowLocationEnum.BottomLeft, HierarchyOnColumn0, null);

            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Cells[0]);
            Point loc = r.Location;
            loc.X = sftTree1.RowHeaders.Width + 5;
            InfoTip.Add(loc, "", "Fully customizable expand/collapse buttons and connecting tree lines", ArrowLocationEnum.BottomLeft, ExpandCollapseButtonsSimple, null);
            InfoTip.Add(loc, "", "Expand/collapse buttons with Windows Vista look (even without Windows Vista)", ArrowLocationEnum.BottomLeft, ExpandCollapseButtonsVista, null);
            InfoTip.Add(loc, "", "Fully customizable expand/collapse buttons and connecting tree lines", ArrowLocationEnum.BottomLeft, ExpandCollapseButtonsXP, ExpandCollapseButtonsNormal);

            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Cells[0]);
            InfoTip.Add(CenterOf(r), "", "Support for single item selection", ArrowLocationEnum.BottomLeft, SelectOneItem, null);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Cells[0]);
            InfoTip.Add(CenterOf(r), "", "Support for multiple item selection", ArrowLocationEnum.BottomLeft, SelectItems, null);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Cells[1]);
            InfoTip.Add(CenterOf(r), "", "Support for single cell selection", ArrowLocationEnum.BottomLeft, SelectOneCell, null);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Cells[1]);
            InfoTip.Add(CenterOf(r), "", "Support for multiple cell selection", ArrowLocationEnum.BottomLeft, SelectCells, SelectOneItem);

            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[3].Cells[0]);
            InfoTip.Add(new Point(r.Location.X - 8, r.Location.Y + r.Height / 5), "Item images can be customized for each item", ArrowLocationEnum.BottomLeft);

            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[0].RowHeader);
            InfoTip.Add(CenterOf(r), "Vertical cell merging to visually combine similar data", ArrowLocationEnum.LeftTop);
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Cells[2]);
            InfoTip.Add(CenterOf(r), "Horizontal cell merging to visually combine similar data");
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[1].Cells[2]);
            InfoTip.Add(6, CenterOf(r), "", "Vertical cell merging to visually combine similar data\nOf course, all parts and color definitions are also applied when cells are merged", ArrowLocationEnum.LeftTop, null, null);

            r = sftTree1.GetDimension(sftTree1.Headers[1, 0]);
            InfoTip.Add(CenterOf(r), "All parts (like dropdown buttons) are also available in headers", ArrowLocationEnum.TopLeft);
            r = sftTree1.GetDimension(sftTree1.Footers[0, 0].OwningItem.RowHeader);
            InfoTip.Add(CenterOf(r), "Parts (like checkboxes) are even available in footers");

            r = sftTree1.GetDimension(sftTree1.Headers[1, 3]);
            InfoTip.Add(CenterOf(r), "Sorting data is easily accomplished (even multi-column sorting)");
            r = sftTree1.GetDimension(sftTree1.Headers[1, 2]);
            InfoTip.Add(CenterOf(r), "Columns can be reordered and resized");

            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Cells[3]);
            InfoTip.Add(CenterOf(r), "Use colors and gradient fills to make important data noticeable");
            r = sftTree1.GetDimension(sftTree1.ItemCollection[0].Children[0].Children[4].Cells[3]);
            InfoTip.Add(CenterOf(r), "Even parts can have their own background color within a cell (with its own background color)");

            r = sftTree1.GetDimension(sftTree1.Headers[1, 0]);
            InfoTip.Add(CenterOf(r), "SftTree/NET 2.0 is available now!");
            r = sftTree1.GetDimension(sftTree1.Footers[0, 2]);
            InfoTip.Add(CenterOf(r), "Click here to order SftTree/NET 2.0\nfor immediate online delivery!");

            InfoTip.Add(15, new Point(cr.Width - 25, 0), "There are many more features to explore in this product.", 
                        "Make sure to try the control that we added to Visual Studio's toolbox\n" +
                        "and review the complete online help and sample source code.\n\n" +
                        "To end this demo, please close this window.", ArrowLocationEnum.RightTop, null, null);
        }

        private void SimpleTree() {
            sftTree1.Initializing = true;
            sftTree1.Splitter.Visible = false;
            sftTree1.RowHeaders.Width = 0;
            sftTree1.Columns[1].Width = 0;
            sftTree1.Columns[2].Width = 0;
            sftTree1.Columns[3].Width = 0;
            sftTree1.Columns[4].Width = 0;
            sftTree1.Columns[5].Width = 0;
            sftTree1.GridLines = GridLinesStyleEnum.None;
            sftTree1.Headers.Visible = false;
            sftTree1.Footers.Visible = false;
            sftTree1.Initializing = false;
        }

        private void ComplexTree() {
            sftTree1.Initializing = true;
            sftTree1.Splitter.Visible = true;
            sftTree1.GridLines = GridLinesStyleEnum.Both;
            sftTree1.Headers.Visible = true;
            sftTree1.Footers.Visible = true;
            Optimize();
            AdjustInfo();
            sftTree1.Initializing = false;
        }

        private void RowHeadersOff() {
            sftTree1.RowHeaders.Width = 0;
        }

        private void RowHeadersOn() {
            Optimize();
            AdjustInfo();
        }

        private void ExpandCollapseButtonsSimple() {
            sftTree1.ButtonLook = ButtonLookEnum.Simple;
            sftTree1.TreeLinesPen = LinesPenStyleEnum.Dots;
        }

        private void ExpandCollapseButtonsVista() {
            sftTree1.ButtonLook = ButtonLookEnum.ThemedAppearanceVista;
            sftTree1.TreeLineStyle = TreeLineStyleEnum.None;
        }

        private void ExpandCollapseButtonsXP() {
            sftTree1.ButtonLook = ButtonLookEnum.ThemedAppearanceXP;
            sftTree1.TreeLineStyle = TreeLineStyleEnum.None;
        }

        private void ExpandCollapseButtonsNormal() {
            sftTree1.ButtonLook = ButtonLookEnum.ThemedSystem;
            sftTree1.TreeLinesPen = LinesPenStyleEnum.Solid;
            sftTree1.TreeLineStyle = TreeLineStyleEnum.AllLevels;
        }

        private void SelectOneItem() {
            sftTree1.SelectionStyle = SelectionStyleEnum.SingleItem;
            sftTree1.ItemCollection[0].Children[0].Selected = true;
        }
        private void SelectItems() {
            sftTree1.SelectionStyle = SelectionStyleEnum.MultipleItems;
            sftTree1.ItemCollection[0].Children[0].Selected = true;
            sftTree1.ItemCollection[0].Children[0].Children[0].Selected = true;
        }
        private void SelectOneCell() {
            sftTree1.SelectionStyle = SelectionStyleEnum.SingleCell;
            sftTree1.ItemCollection[0].Children[0].Cells[1].Selected = true;
        }
        private void SelectCells() {
            sftTree1.SelectionStyle = SelectionStyleEnum.MultipleCells;
            sftTree1.ItemCollection[0].Children[0].Cells[1].Selected = true;
            sftTree1.ItemCollection[0].Children[0].Cells[2].Selected = true;
            sftTree1.ItemCollection[0].Children[0].Children[0].Cells[1].Selected = true;
            sftTree1.ItemCollection[0].Children[0].Children[0].Cells[2].Selected = true;
        }
        private void SplitterOff() {
            sftTree1.Splitter.Visible = false;
        }
        private void SplitterOn() {
            sftTree1.Splitter.Visible = true;
            Update();
            Optimize();
            AdjustInfo();
        }
        private void HierarchyOnColumn0() {
            sftTree1.Columns[0].ShowHierarchy = true;
            Optimize();
            AdjustInfo();
        }
        private void HierarchyOnColumn1() {
            sftTree1.Columns[1].ShowHierarchy = true;
            Optimize();
            AdjustInfo();
        }
        private void HierarchyOnColumn2() {
            sftTree1.Columns[2].ShowHierarchy = true;
            Optimize();
            AdjustInfo();
        }
        private Point CenterOf(Rectangle r) {
            Point pt = r.Location;
            pt.Offset(r.Width / 2, r.Height / 2);
            return pt;
        }

        private int TimerCounter = 0;
        private ToolTipClass ToolTip;

        static InfoTip.FPtr LastFunc = null;

        private void Timer1_Tick(object sender, EventArgs e) {

            if (LastFunc != null) {
                LastFunc();
                LastFunc = null;
            }

            InfoTip Info = null;

            for ( ; ; ) {
                if (TimerCounter >= InfoTip.Count) TimerCounter = 0;
                Info = InfoTip.Info(TimerCounter);
                if (TimerCounter == 0)
                    break;
                if (Info.Location != Point.Empty && sftTree1.ClientRectangle.Contains(Info.Location))
                    break;
                ++TimerCounter;
            }

            ToolTipIcon ttIcon = ToolTipIcon.Info;
            if (Info.Location == Point.Empty || !sftTree1.ClientRectangle.Contains(Info.Location)) {
                Info = new InfoTip(0, new Point(20, 0), "", "The window is too small to\ndisplay the informational balloons.", ArrowLocationEnum.TopLeft, null, null);
                ttIcon = ToolTipIcon.Error;
            }

            ToolTip = null;
            ShowToolTip(Info.Location, ttIcon, Info.Title, Info.Text, Info.ArrowLoc);
            if (Info.Func != null) {
                InfoTip.FPtr f = Info.Func;
                f();
            }
            LastFunc = Info.FuncEnd; // save function to call after balloon has been shown

            Timer1.Interval = Info.Interval;

            ++TimerCounter;
        }

        private void ShowToolTip(Point loc, ToolTipIcon ttIcon, string title, string text, ArrowLocationEnum ArrowLoc) {
            // figure out what quadrant to locate the arrow nicely
            if ((int) ArrowLoc == (int) -1) {
                if (loc.X < sftTree1.ClientRectangle.Width / 2) {
                    if (loc.X < sftTree1.ClientRectangle.Width / 4) {
                        if (loc.Y < sftTree1.ClientRectangle.Height / 2)
                            ArrowLoc = ArrowLocationEnum.LeftTop;
                        else
                            ArrowLoc = ArrowLocationEnum.LeftBottom;
                    } else {
                        if (loc.Y < sftTree1.ClientRectangle.Height / 2)
                            ArrowLoc = ArrowLocationEnum.TopLeft;
                        else
                            ArrowLoc = ArrowLocationEnum.BottomLeft;
                    }
                } else {
                    if (loc.X < sftTree1.ClientRectangle.Width / 4) {
                        if (loc.Y > sftTree1.ClientRectangle.Height * 3 / 4)
                            ArrowLoc = ArrowLocationEnum.RightTop;
                        else
                            ArrowLoc = ArrowLocationEnum.RightBottom;
                    } else {
                        if (loc.Y < sftTree1.ClientRectangle.Height / 2)
                            ArrowLoc = ArrowLocationEnum.TopRight;
                        else
                            ArrowLoc = ArrowLocationEnum.BottomLeft;
                    }
                }
            }
            ToolTipClass.ShowToolTip(sftTree1, loc, ttIcon, title, text, ArrowLoc);
        }

        private void sftTree1_ItemClick(object sender, ItemClickEventArgs e) {
            if (e.Item != null && e.Cell != null) {
                if (e.Item.UsageLocation == UsageLocationEnum.footer &&
                        e.Area == ItemClickAreaEnum.Cell &&
                        e.Item.VisibleIndex == 0 && e.Cell.ColumnIndex == 2 &&
                        e.Part is ButtonPartClass) {
                    try {
                        System.Diagnostics.Process.Start("http://www.softelvdm.com/treenet.html");
                    } catch {
                    }
                }
            }
        }

        private void Form1_Resize(object sender, EventArgs e) {
            AdjustInfo();
        }

        private void sftTree1_ColumnReordered(object sender, Softelvdm.SftTreeNET.ColumnReorderedEventArgs e) {
            AdjustInfo();
        }

        private void sftTree1_ColumnResized(object sender, ColumnResizedEventArgs e) {
            AdjustInfo();
        }

        private void Form1_Deactivate(object sender, EventArgs e) {
            Timer1.Enabled = false;
            ToolTipClass.HideToolTip();
        }

        private void Form1_Activated(object sender, EventArgs e) {
            Timer1.Interval = 500;
            Timer1.Enabled = true;
        }

        private void Form1_Move(object sender, EventArgs e) {
            Timer1.Interval = 2000;
            ToolTipClass.HideToolTip();
        }

        private void sftTree1_ItemCollapsed(object sender, ItemCollapsedEventArgs e) {
            AdjustInfo();
        }

        private void sftTree1_ItemExpanded(object sender, ItemExpandedEventArgs e) {
            AdjustInfo();
        }
        private void Form1_Load(object sender, EventArgs e) {
            Optimize();
            AdjustInfo();
        }
    }

    public class InfoTip {
        private static Collection InfoTips = new Microsoft.VisualBasic.Collection();
        public delegate void FPtr();

        private Point _Loc;
        private string _Text;
        private string _Title;
        private ArrowLocationEnum _ArrowLoc = (ArrowLocationEnum)(-1);
        private FPtr _Func = null;
        private FPtr _FuncEnd = null;
        private int _Interval = 0;

        public InfoTip(int Interval, Point Loc, string Title, string Text, ArrowLocationEnum ArrowLoc, FPtr Func, FPtr FuncEnd) {
            _Interval = Interval * 1000;
            _Title = Title;
            _Loc = Loc;
            _Text = Text;
            _ArrowLoc = ArrowLoc;
            _Func = Func;
            _FuncEnd = FuncEnd;
        }

        public InfoTip(Point Loc, string Text) {
            _Loc = Loc;
            _Text = Text;
        }

        public static void Clear() {
            InfoTips.Clear();
        }

        public static void Add(Point Loc, string Text) {
            InfoTip t = new InfoTip(0, Loc, "", Text, (ArrowLocationEnum)(-1), null, null);
            InfoTips.Add(t, null, null, null);
        }

        public static void Add(Point Loc, string Text, ArrowLocationEnum ArrowLoc) {
            InfoTip t = new InfoTip(0, Loc, "", Text, ArrowLoc, null, null);
            InfoTips.Add(t, null, null, null);
        }

        public static void Add(int Interval, Point Loc, string Title, string Text, ArrowLocationEnum ArrowLoc, FPtr Func, FPtr FuncEnd) {
            InfoTip t = new InfoTip(Interval, Loc, Title, Text, ArrowLoc, Func, FuncEnd);
            InfoTips.Add(t, null, null, null);
        }
        public static void Add(Point Loc, string Title, string Text, ArrowLocationEnum ArrowLoc, FPtr Func, FPtr FuncEnd) {
            InfoTip t = new InfoTip(0, Loc, Title, Text, ArrowLoc, Func, FuncEnd);
            InfoTips.Add(t, null, null, null);
        }

        public static int Count {
            get { return InfoTips.Count; }
        }

        public static InfoTip Info(int index) {
            return (InfoTip) InfoTips[index + 1];
        }

        public Point Location {
            get {
                return _Loc;
            }
        }

        public string Title {
            get {
                if (_Title == "") return "SftTree/NET 2.0 Features";
                return _Title;
            }
        }

        public string Text {
            get {
                return _Text;
            }
        }

        public ArrowLocationEnum ArrowLoc {
            get {
                return _ArrowLoc;
            }
        }

        public FPtr Func {
            get {
                return _Func;
            }
        }
        public FPtr FuncEnd {
            get {
                return _FuncEnd;
            }
        }
        public int Interval {
            get {
                if (_Interval <= 0) return 5000;
                return _Interval;
            }
        }
    }
}