using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Xml;

namespace Machinations.UserComponents
{
    public sealed class CardTemplate : UserComponent
    {
        public int m_density;
        public Cards m_cards;

        public CardTemplate(List<InnerInOut> inAndOuts, Cards cards):base(inAndOuts)
        {
            m_cards = cards;
            m_density = 1;
        }

        public CardTemplate(List<InnerInOut> inAndOuts, XmlElement element, Cards cards): this(inAndOuts, cards)
        {
            ReadXml(element);
        }

        public int Density
        {
            get { return m_density; }
            set { m_density = value; }
        }


        public override XmlElement GenerateXmlTemplate(XmlDocument document)
        {
            var element = base.GenerateXmlTemplate(document);
            element.SetAttribute("density", m_density+"");
            return element; 
        }

        public override void ReadXml(XmlElement element)
        {
            ReadXmlTemplate(element);
            m_density = int.Parse(element.GetAttribute("density"));
        }

        public override InnerInOut CreateInOut(Point position, bool? input = null, int? inOutNumber = null)
        {
            return m_cards.CreateInOut(position, input);
        }

        //v tuhle chvili by meli byt nactene inOuty z karet v inOutech, a v grafu by mely byt inouty z filu
        protected override void AddInOutsAfterLoad()
        {
            var cardInOuts = InnerInOuts.ToDictionary(inOut => inOut.InOutNumber);
            var loaded = InternalGraph.Elements.OfType<InnerInOut>().ToList();
            loaded.ForEach(inOut =>
            {
                int cardNumber = inOut.InOutNumber;
                if (cardInOuts.ContainsKey(cardNumber))
                {
                    SwitchInOut(cardInOuts[cardNumber], inOut);
                    cardInOuts.Remove(cardNumber);
                }
                else
                {
                    foreach (var connection in inOut.InnerConnections.Where(c => c.Points.Count == 0))
                    {
                        connection.Points.Add(inOut.Position);
                    }
                    inOut.Dispose();
                }
            });
            foreach (var userComponentInOut in cardInOuts.Values)
            {
                InternalGraph.AddElement(userComponentInOut);
            }
            //base.AddInOutsAfterLoad();
        }

        private void SwitchInOut(InnerInOut cardInOut, InnerInOut loadedInOut)
        {
            //jedna moznost je nahradit inOut v grafu
            loadedInOut.GetGeneralValues(cardInOut);
            int position = m_innerInOuts.IndexOf(cardInOut);
            m_innerInOuts.RemoveAt(position);
            m_innerInOuts.Insert(position, loadedInOut);
        }
    }
}
