using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PXP.Crawler.API.Designers.Controls;
using PXP.Crawler.API.Model;

namespace PXP.Crawler.API.Plugins.Values.Lists
{
    [NodeInfo("Get", typeof(GetElementNode), Category = "List",
        DefaultWidth = 100, DefaultHeight = 40, Description = "Get list item...")]
    public class GetElementNode : Node
    {
        internal Type listType = null;
        internal IList listObj = null;
        internal object selElement = null;
        private int selIndex = -1;

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

        public override void CreateDesigner()
        {
            base.CreateDesigner();
            NodeDesignerControl ndCont = (NodeDesignerControl)designer.Control;

            NodeDesignerPin nelPin = ndCont.FindOutDesignerPin("Element");

            if (listObj == null)
            {
                nelPin.PinType = typeof (object);
            }
            else
            {
                nelPin.PinType = listObj.GetType().GetElementType(); //GetGenericArguments().Single();
            }

            ndCont.BackColor = Color.DarkOrchid;
        }

        [NodePropertyPin(NodePinDirection.Input)]
        public IList List
        {
            get { return listObj; }
            set
            {
                listObj = value;
                if (listObj == null)
                {
                    listType = null;
                    DisconnectOutProperty("Element");
                }
                else
                {
                    Type nlType = listObj.GetType().GetElementType();
                    if (nlType != listType)
                    {
                        DisconnectOutProperty("Element");
                        listType = nlType;
                    }

                    if (designer != null)
                    {
                        NodeDesignerControl ndCont = (NodeDesignerControl)designer.Control;
                        NodeDesignerPin nelPin = ndCont.FindOutDesignerPin("Element");
                        if (listObj.GetType().GetGenericArguments().Length > 0)
                        {
                            nelPin.PinType = listObj.GetType().GetGenericArguments().Single();                            
                        }
                    }
                    if (selIndex == -1)
                        selIndex = 0;
                }
                NotifyPropertyChange("List");
                Index = selIndex;
            }
        }


        [NodePropertyPin(NodePinDirection.Input)]
        public int Index
        {
            get
            {
                return selIndex;
            }
            set
            {
                selIndex = value;
                if (listObj != null)
                {
                    if (selIndex > listObj.Count)
                    {
                        selIndex = listObj.Count % selIndex;
                    }
                    
                    if (selIndex >= 0 && selIndex < listObj.Count)
                    {
                        Element = listObj[selIndex];
                    }
                    else
                    {                        
                        Element = null;
                    }
                }
                else
                {
                    selIndex = value;
                    Element = null;
                }
            }
        }

        [NodePropertyPin(NodePinDirection.Output)]
        public object Element
        {
            get
            {
                return selElement;
            }
            set
            {
                selElement = value;
                NotifyPropertyChange("Element");
            }
        }
    }
}
