using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraTreeList;
using PXP.Crawler.API.Data;
using PXP.Crawler.API.Designers.Controls.Forms;
using PXP.Crawler.API.Model;

namespace PXP.Crawler.API.Designers.Controls
{
    public partial class NodeTypePickUserControl : UserControl
    {
        private DataView nodesDataView;

        public NodeTypePickUserControl()
        {
            InitializeComponent();
        }
        
        
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        public event EventHandler DoHide;

        internal void OnDoHide()
        {
            if (!Visible)
                return;Hide();
            
            if (DoHide != null)
            {
                DoHide(this, EventArgs.Empty);
            }
        }


        public event EventHandler DoNodeSelect;

        internal void OnDoNodeSelect()
        {
            if (nodesTreeList.FocusedNode == null)
            {
                selNodeInfo = null;
            }
            else
            {
                selNodeInfo = (NodeInfo)nodesTreeList.FocusedNode.GetValue(colNodeInfo);                
            }



            if (DoNodeSelect != null)
            {
                DoNodeSelect(this, EventArgs.Empty);
            }
        }

        public void UpdateNodesTree()
        {
            if (DesignMode)
                return;
            
            nodesDataSet.Clear();
            PluginManager pm = PluginManager.Current;
            foreach (string catName in pm.GetCategoryNames())
            {
                int imInd = -1;
                //nodesImageCollection.Images.IndexOf(nodesImageCollection.Images["category"]);
                NodesDataSet.CategoriesRow rcatRow = nodesDataSet.Categories.AddCategoriesRow(catName);

                //NodesDataSet.NodesRow catRow = nodesDataSet.Nodes.AddNodesRow(null, catName, imInd, null, 0, rcatRow);

                SortedDictionary<string, NodeInfo> nodeTypes = pm.GetCategoryTypes(catName);
                foreach (string nodeTypeName in nodeTypes.Keys)
                {
                    NodeInfo nInfo = nodeTypes[nodeTypeName];
                    int ntImgInd = nodesImageCollection.Images.Add(nInfo.Icon.Image, nInfo.Icon.ImageName);
                    NodesDataSet.NodesRow nTypeRow = nodesDataSet.Nodes.AddNodesRow(null, nInfo.Name, ntImgInd, nInfo, 1, rcatRow);
                }
            }

            if (nodesDataView == null)
            {
                nodesDataView = new DataView(nodesDataSet.Nodes);
                nodesDataView.Sort = "Category, Name";
                nodesDataView.RowFilter = "";
                nodesTreeList.DataSource = nodesDataView;
                nodesTreeList.ExpandAll();
            }



            if (nodesTreeList.Nodes.Count > 0)
            {
                nodesTreeList.ExpandAll();
                nodesTreeList.FocusedNode = nodesTreeList.Nodes[0];
            }
        }

        private NodeInfo selNodeInfo;

        [Browsable(false)]
        public NodeInfo SelectedNodeType
        {
            get { return selNodeInfo; }   
        }

        private void NodeTypePickUserControl_Load(object sender, EventArgs e)
        {
            UpdateNodesTree();
        }

     
        private void filterTextEdit_Leave(object sender, EventArgs e)
        {
            if (!Visible)
                return;

            if (!nodesTreeList.Focused)
            {
                OnDoHide();
            }
        }

        private void filterTextEdit_TextChanged(object sender, EventArgs e)
        {
            nodesDataView.RowFilter = "Name LIKE '%" + filterTextEdit.Text + "%'";
            nodesTreeList.ExpandAll();
                                    
            nodesTreeList.MoveFirst();
        }

        private void filterTextEdit_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (nodesDataView.Count > 0)
                {
                    OnDoNodeSelect();
                    return;
                }
            }
            if (e.KeyCode == Keys.Down)
            {
                int nnt = -1;
                if (nodesTreeList.FocusedNode.NextVisibleNode != null)
                    nnt = Convert.ToInt32(nodesTreeList.FocusedNode.NextVisibleNode.GetValue(colType));if (nnt == 0)
                {
                    nodesTreeList.FocusedNode = nodesTreeList.FocusedNode.NextVisibleNode.NextVisibleNode;
                }
                else
                {
                    nodesTreeList.MoveNextVisible();
                }
                e.Handled = true;
                return;
            }
            if (e.KeyCode == Keys.Up)
            {
                int nnt = -1;
                if (nodesTreeList.FocusedNode.PrevVisibleNode != null)
                    nnt = Convert.ToInt32(nodesTreeList.FocusedNode.PrevVisibleNode.GetValue(colType));
                if (nnt == 0)
                {
                    nodesTreeList.FocusedNode = nodesTreeList.FocusedNode.PrevVisibleNode.PrevVisibleNode;
                }
                else
                {
                    nodesTreeList.MovePrevVisible();
                }
                e.Handled = true;
                return;
            }
            if (e.KeyCode == Keys.Escape)
            {
                e.Handled = true;
                OnDoHide();
                return;
            }
            if (e.KeyCode == Keys.PageDown)
            {
                nodesTreeList.MoveLastVisible();
                e.Handled = true;
                return;
            }
            if (e.KeyCode == Keys.PageUp)
            {
                nodesTreeList.MoveFirst();
                e.Handled = true;
                return;
            }
        }
        
        private void nodesTreeList_Leave(object sender, EventArgs e)
        {
            if (!Visible)
                return;

            if (!filterTextEdit.Focused)
            {
                OnDoHide();
            }
        }

        private void nodesTreeList_MouseDown(object sender, MouseEventArgs e)
        {
            TreeListHitInfo hi = nodesTreeList.CalcHitInfo(e.Location);
            if (hi.HitInfoType == HitInfoType.Cell)
            {
                nodesTreeList.FocusedNode = hi.Node;
                if (e.Clicks == 1)
                {
                    filterTextEdit.Focus();
                    filterTextEdit.SelectAll();
                }
                else if (e.Clicks > 1)
                {
                    OnDoNodeSelect();
                }
            }            
        }

        public void Reset()
        {
            selNodeInfo = null;
            filterTextEdit.Text = "";
            nodesTreeList.MoveFirst();
        }

        private void nodesTreeList_BeforeFocusNode(object sender, BeforeFocusNodeEventArgs e)
        {
            int nt = Convert.ToInt32(e.Node.GetValue(colType));
            if (nt == 0)
            {
                e.CanFocus = false;                
            }
        }

        private void nodesTreeList_AfterFocusNode(object sender, NodeEventArgs e)
        {
            int nt = Convert.ToInt32(e.Node.GetValue(colType));
            if (nt == 0)
            {
                nodesTreeList.FocusedNode = e.Node.NextVisibleNode;}
        }

        private void nodesTreeList_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
        {
            }


    }
}
