#region COPYRIGHT
//
//     THIS IS GENERATED BY TEMPLATE
//     
//     AUTHOR  :     ROYE
//     DATE       :     2010
//
//     COPYRIGHT (C) 2010, TIANXIAHOTEL TECHNOLOGIES CO., LTD. ALL RIGHTS RESERVED.
//
#endregion

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Win32;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace TX.Framework.WindowUI.Controls
{
    internal class CustomEdit : NativeWindow, IWin32Window
    {
        private TreeListViewItemEditControlHandle _EditorHandle;
        private EditItemInformations _Informations;
        private Control _Editor;
        private TreeListView _TreeListView;

        private CustomEdit()
        {
        }

        public CustomEdit(IntPtr handle, TreeListView treeListView, Control editor)
        {
            _TreeListView = treeListView;
            _Informations = _TreeListView.EditedItem;
            if (editor == null)
            {
                _Editor = new TextBox();
            }
            else
            {
                _Editor = editor;
            }
            _Editor.Hide();
            if (!_TreeListView.Controls.Contains(_Editor))
            {
                _TreeListView.Controls.Add(_Editor);
            }
            _EditorHandle = new TreeListViewItemEditControlHandle(_TreeListView, _Editor, this);
            AssignHandle(handle);
        }

        public void ShowEditControl()
        {
            if (_TreeListView.FocusedItem == null) return;
            ListViewItem item = (ListViewItem)_TreeListView.EditedItem.Item;
            Rectangle rec = _TreeListView.EditedItem.ColumnIndex > 0 ?
                _TreeListView.GetSubItemRect(item.Index, _TreeListView.EditedItem.ColumnIndex) :
                _TreeListView.GetItemRect(item.Index, ItemBoundsPortion.Label);
            _Editor.Size = rec.Size;
            _Editor.Location = rec.Location;
            _Editor.Top--;
            _Editor.Show();
            _Editor.Text = item.SubItems[_TreeListView.EditedItem.ColumnIndex].Text;
            _Editor.Focus();
        }

        public void HideEditControl()
        {
            _Editor.Hide();
            ReleaseHandle();
            _EditorHandle.ReleaseHandle();
        }

        public void SendMessage(ref Message m)
        {
            WndProc(ref m);
        }

        protected override void WndProc(ref Message m)
        {
            switch ((WindowMessages)m.Msg)
            {
                case WindowMessages.SHOWWINDOW:
                    bool show = m.WParam != IntPtr.Zero;
                    if (show) ShowEditControl();
                    else HideEditControl();
                    return;
            }
        }

        public new IntPtr Handle
        {
            get { return base.Handle; }
        }
    }

    internal class TreeListViewItemEditControlHandle : NativeWindow, IWin32Window
    {
        private CustomEdit _customedit;
        private Control _control;
        private TreeListView _treelistview;

        public TreeListViewItemEditControlHandle(TreeListView treelistview, Control control, CustomEdit customedit)
        {
            _control = control;
            _treelistview = treelistview;
            _customedit = customedit;
            if (!control.Created) control.CreateControl();
            AssignHandle(control.Handle);
        }

        private void EndEdit(bool Cancel)
        {
            if (!_treelistview.InEdit) return;
            _treelistview.ExitEdit(Cancel, _control.Text);
        }

        private bool OnKillFocus(Message m)
        {
            if (!(_control is ComboBox)) return true;
            PCOMBOBOXINFO info = new PCOMBOBOXINFO();
            info.cbSize = (uint)Marshal.SizeOf(typeof(PCOMBOBOXINFO));
            if (!NativeMethods.GetComboBoxInfo(_control.Handle, ref info)) return true;
            if (m.WParam == info.hwndCombo || m.WParam == info.hwndItem || m.WParam == info.hwndList)
            {
                ReleaseHandle();
                AssignHandle(m.WParam);
                return false;
            }
            return true;
        }

        protected override void WndProc(ref Message m)
        {
            switch ((WindowMessages)m.Msg)
            {
                case WindowMessages.KEYDOWN:
                    Keys key = (Keys)(int)m.WParam;
                    if (key != Keys.Return && key != Keys.Escape) break;
                    bool Cancel = key != Keys.Enter;
                    EndEdit(Cancel);
                    return;
                case WindowMessages.KILLFOCUS:
                    if (OnKillFocus(m))
                    {
                        EndEdit(!(_control is ComboBox && _treelistview.EditedItem.Label != _control.Text));
                        return;
                    }
                    break;
            }
            base.WndProc(ref m);
        }

        private int HighOrder(IntPtr Param)
        {
            int intparam = Param.ToInt32();
            return (intparam >> 16) & 0x0000ffff;
        }

        private int LowOrder(IntPtr Param)
        {
            int intparam = Param.ToInt32();
            return intparam & 0x0000ffff;
        }

        public new IntPtr Handle
        {
            get { return base.Handle; }
        }
    }
}