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

using Softelvdm.SftTreeNET;
using Softelvdm.Controls;

namespace DragDrop
{
    public partial class Form1 : Form
    {
        // This example implements dragging (moving, copying) items between two tree controls.
        public Form1()
        {
            InitializeComponent();
        }

        private void CloseButton_Click(object sender, EventArgs e) {
            Close();
        }

        private void Form1_Load(object sender, EventArgs e) {
            sftTree1.Initializing = true;
            sftTree1.AllowDrop = true;
            sftTree1.AutoExpandDragDrop = true;
            sftTree1.Columns.Count = 2;
            sftTree1.Headers[0, 0].Text = "Left Tree Control";
            for (int c = 1; c < sftTree1.Columns.Count; ++c) {
                sftTree1.Headers[0, c].Text = "Column " + c.ToString();
            }
            for (int i = 0; i < 100; ++i) {
                ItemClass itemParent = sftTree1.ItemCollection.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() } );
                itemParent.RowHeader.Text = i.ToString();
                ++i;
                ItemClass item = itemParent.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                item.RowHeader.Text = i.ToString();
                ++i;
                ItemClass subitem = item.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                subitem.RowHeader.Text = i.ToString();
                ++i;
                ItemClass child = subitem.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                child.RowHeader.Text = i.ToString();
                ++i;
                child = item.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                child.RowHeader.Text = i.ToString();
            }
            sftTree1.Columns.MakeOptimal(0, false);
            sftTree1.RowHeaders.MakeOptimal(0, false);
            sftTree1.RecalcHorizontalExtent();
            sftTree1.Initializing = false;

            sftTree2.Initializing = true;
            sftTree2.AllowDrop = true;
            sftTree2.AutoExpandDragDrop = true;
            sftTree2.Columns.Count = 3;
            sftTree2.RowHeaders.Width = 0;
            sftTree2.Headers[0, 0].Text = "Right Tree Control";
            for (int c = 1; c < sftTree2.Columns.Count; ++c) {
                sftTree2.Headers[0, c].Text = "Column " + c.ToString();
            }
            for (int i = 0; i < 100; ++i) {
                ItemClass itemParent = sftTree2.ItemCollection.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                itemParent.RowHeader.Text = i.ToString();
                ++i;
                ItemClass item = itemParent.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                item.RowHeader.Text = i.ToString();
                ++i;
                ItemClass subitem = item.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                subitem.RowHeader.Text = i.ToString();
                ++i;
                ItemClass child = subitem.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                child.RowHeader.Text = i.ToString();
                ++i;
                child = item.Add(new string[] { "Item " + i.ToString(), "Cell 1 in Item " + i.ToString(), "Cell 2 in Item " + i.ToString() });
                child.RowHeader.Text = i.ToString();
            }
            sftTree2.Columns.MakeOptimal(0, false);
            sftTree2.RecalcHorizontalExtent();
            sftTree2.Initializing = false;
        }

        private void sftTree1_DragDetected(object sender, DragDetectedEventArgs e) {
            Debug.Write("sftTree1_DragDetected ");
            DumpValues(e);
            // get the current item
            if (e.Item == null) return;
            ItemClass item = e.Item;
            // don't drag headers, footers
            if (item.UsageLocation != UsageLocationEnum.items) 
                return;
            // start dragging the item
            sftTree1.DoDragDrop(e.Item, DragDropEffects.Copy|DragDropEffects.Move);
        }

        private void sftTree1_DragOver(object sender, DragEventArgs e) {
            Debug.WriteLine("sftTree1_DragOver ");
            e.Effect = DragDropEffects.None;
            if (sftTree1.DropTarget != null && e.Data.GetDataPresent(typeof(ItemClass))) {
                // Copy or move based on control key
                if ((Control.ModifierKeys & Keys.Control) != 0)
                    e.Effect = DragDropEffects.Copy;
                else
                    e.Effect = DragDropEffects.Move;
            }
        }
 
       private void sftTree1_DragDrop(object sender, DragEventArgs e) {
            Debug.Write("sftTree1_DragDrop ");
            DumpValues(e);
            if (sftTree1.DropTarget != null && e.Data.GetDataPresent(typeof(ItemClass))) {
                ItemClass originalItem = (ItemClass)e.Data.GetData(typeof(ItemClass));
                ItemClass targetItem = (ItemClass)sftTree1.DropTarget;
                ItemClass newItem = null;
                if (e.Effect == DragDropEffects.Move) {
                    try {
                        newItem = originalItem.Move(targetItem, MoveStyleEnum.TargetAsParentInsertFirst);
                    } catch (Exception exc) {
                        MessageBox.Show(exc.Message);
                    }
                } else {
                    try {
                        newItem = originalItem.Copy(targetItem, CopyStyleEnum.TargetAsParentInsertFirst, true);
                    } catch (Exception exc) {
                        MessageBox.Show(exc.Message);
                    }
                }
                if (newItem != null) {
                    sftTree1.Columns.MakeOptimal(0, false);
                    newItem.ScrollIntoView();
                }
            }
        }

        private void sftTree2_DragDetected(object sender, DragDetectedEventArgs e) {
            Debug.Write("sftTree2_DragDetected ");
            DumpValues(e);
            // get the current item
            if (e.Item == null) return;
            ItemClass item = e.Item;
            // don't drag headers, footers
            if (item.UsageLocation != UsageLocationEnum.items)
                return;
            // start dragging the item
            sftTree2.DoDragDrop(e.Item, DragDropEffects.Copy | DragDropEffects.Move);
        }

        private void sftTree2_DragOver(object sender, DragEventArgs e) {
            Debug.WriteLine("sftTree2_DragOver ");
            e.Effect = DragDropEffects.None;
            if (sftTree2.DropTarget != null && e.Data.GetDataPresent(typeof(ItemClass))) {
                // Copy or move based on control key
                if ((Control.ModifierKeys & Keys.Control) != 0)
                    e.Effect = DragDropEffects.Copy;
                else
                    e.Effect = DragDropEffects.Move;
            }
        }

        private void sftTree2_DragDrop(object sender, DragEventArgs e) {
            Debug.Write("sftTree2_DragDrop ");
            DumpValues(e);
            if (sftTree2.DropTarget != null && e.Data.GetDataPresent(typeof(ItemClass))) {
                ItemClass originalItem = (ItemClass)e.Data.GetData(typeof(ItemClass));
                ItemClass targetItem = (ItemClass)sftTree2.DropTarget;
                ItemClass newItem = null;
                if (e.Effect == DragDropEffects.Move) {
                    try {
                        newItem = originalItem.Move(targetItem, MoveStyleEnum.TargetAsParentInsertFirst);
                    } catch (Exception exc) {
                        MessageBox.Show(exc.Message);
                    }
                } else {
                    try {
                        newItem = originalItem.Copy(targetItem, CopyStyleEnum.TargetAsParentInsertFirst, true);
                    } catch (Exception exc) {
                        MessageBox.Show(exc.Message);
                    }
                }
                if (newItem != null) {
                    sftTree2.Columns.MakeOptimal(0, false);
                    newItem.ScrollIntoView();
                }
            }
        }

        // 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("");
        }

    }
}