using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraPrinting.Export;
using PXP.Crawler.API.Designers;
using PXP.Crawler.API.Designers.Controls;
using PXP.Crawler.API.Model;
using PXP.Crawler.API.Utils;

namespace PXP.Crawler.API.Plugins.Values.Lists
{
    [NodeInfo("Set", typeof(SetElementNode), Category = "List",
        DefaultWidth = 100, DefaultHeight = 40, Description = "Set list item...")]
    public class SetElementNode : Node
    {
        private IList list = null;
        private object item = null;
        private Type listItemType = null;
        private int index = -1;

        public SetElementNode(Program program) : base(program)
        {
        }

        public override void CreateDesigner()
        {
            base.CreateDesigner();
            base.designer.Control.BackColor = Color.DarkOrchid;
        }

        [NodePin()]
        public IList List
        {
            get { return list; }
            set
            {
                list = value;
                if (list != null)
                {
                    ListItemType = list.GetType().GetElementType();                    
                }                
                if (item != null)
                {
                    if (list == null)
                    {
                        if (listItemType != null)
                        {
                            list = Misc.CreateList(listItemType);
                        }
                    }
                    if (item.GetType() != listItemType)
                    {
                        DisconnectInProperty("List");
                    }
                }
                if (designer != null)
                {
                    NodeDesignerControl ndCont = (NodeDesignerControl)designer.Control;
                    if (list != null)
                    {
                        ndCont.FindInDesignerPin("List").PinType = list.GetType();
                        ndCont.FindOutDesignerPin("List").PinType = list.GetType();
                    }
                    else
                    {
                        ndCont.FindInDesignerPin("List").PinType = typeof(IList);
                        ndCont.FindOutDesignerPin("List").PinType = typeof(IList);
                    }                 
                }
                NotifyPropertyChange("List");
            }
        }

        [NodePin(NodePin.NodePinDirection.Input)]
        public object Item
        {
            get
            {
                return item;
            }
            set
            {
                if (value != null)
                {
                    if (value != item)
                    {
                        if (list != null)
                        {
                            if (list.Contains(item))
                                list.Remove(item);
                        }
                        item = value;
                    }
                    if (listItemType == null)
                        ListItemType = item.GetType();
                    
                    if (item.GetType() != listItemType)
                    {
                        if (item != null)
                            ListItemType = item.GetType();

                        DisconnectInProperty("List");
                    }
                }
                else
                {
                    if (list != null)
                    {
                        if (list.Contains(item))
                        {
                            list.Remove(item);
                        }
                    }
                    item = null;
                    ListItemType = typeof (object);
                }
                if (list == null)
                {
                    List = list;
                }
                if (list != null && item != null)
                {
                    if (!list.Contains(item))
                    {
                        if (index <= 0)
                        {
                            list.Add(item);
                        }
                        NotifyPropertyChange("List");
                    }
                }
            }
        }

        [NodePin(NodePin.NodePinDirection.Input)]
        public int Index
        {
            get
            {
                return index;
            }
            set
            {
                index = value;
            }
        }

        public Type ListItemType
        {
            get
            {
                return listItemType;
            }
            set
            {
                listItemType = value;
                if (designer != null)
                {
                    NodeDesignerControl ndCont = (NodeDesignerControl) designer.Control;
                    if (listItemType != null)
                        ndCont.FindInDesignerPin("Item").PinType = listItemType;
                }
            }
        }
    }
}
