﻿using AngleSharp.Common;
using AngleSharp.Css.Dom;
using Integrative.Lara;
using OKHOSTING.UI.Controls;
using OKHOSTING.UI.Controls.Layout;
using OKHOSTING.UI.CSS;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OKHOSTING.UI.Lara.Controls.Layout
{
    public class Stack : Control, IStack
    {
        public Stack() : base("div")
        {
            _Children = new ControlCollection(this);
        }

        public readonly ControlCollection _Children;

        ICollection<IControl> IContainer.Children
        {
            get
            {
                return _Children;
            }
        }

        IImage _BackgroundImage;
        public IImage BackgroundImage 
        {
            get
            {
                return _BackgroundImage;
            }
            set
            {
                _BackgroundImage = value;

                if (value.Uri != null || value.Bytes != null)
                {
                    if (value.Uri != null)
                    {
                        InnerElement.SetAttribute("background", value.Uri.ToString());
                        return;
                    }

                    if (value.Bytes != null)
                    {
                        string base64String = Convert.ToBase64String(value.Bytes, 0, value.Bytes.Length);
                        InnerElement.SetAttribute("background", "data:image/png;base64," + base64String);
                        return;
                    }

                    var src = ((Image)value).InnerElement.GetAttribute("src");

                    if (!string.IsNullOrEmpty(src))
                    {
                        InnerElement.SetAttribute("background", src);
                        return;
                    }
                }
                else
                {
                    throw new ArgumentNullException(nameof(value));
                }
            }
        }

        /// <summary>
        /// Represents a list of controls in Xamarin:Forms
        /// <para xml:lang="es">
        /// Representa una lista de controles en Xamarin:Forms
        /// </para>
        /// </summary>
        public class ControlCollection : Data.CollectionProxy<IControl>
        {
            public readonly Stack Container;

            public ControlCollection(Stack container): base(new List<IControl>())
            {
                if (container == null)
                {
                    throw new ArgumentNullException(nameof(container));
                }

                Container = container;
            }

            /// <summary>
            /// Add the specified item.
            /// <para xml:lang="es">
            /// Agrega el elemento especificado.
            /// </para>
            /// </summary>
            /// <param name="item">The item specific
            /// <para xml:lang="es">El elemento especificado.</para>
            /// </param>
            public override void Add(IControl item)
            {
                var index = Container.InnerElement.ChildCount;

                Container.InnerElement.InsertChildAt(index, ((Control)item).InnerElement);
                Container.InnerElement.InsertChildAt(index + 1, Element.Create("br"));

                base.Add(item);
            }

            /// <summary>
            /// Clear this instance.
            /// <para xml:lang="es">
            /// Limpia esta instancia.
            /// </para>
            /// </summary>
            public override void Clear()
            {
                Container.InnerElement.ClearChildren();
                base.Clear();
            }

            /// <summary>
            /// Remove the specified item.
            /// <para xml:lang="es">
            /// Elimina el elemento especificado.
            /// </para>
            /// </summary>
            /// <param name="item">Item
            /// <para xml:lang="es">El elemento.</para>
            /// </param>
            /// <returns>True.</returns>
            public override bool Remove(IControl item)
            {
                if (Contains(item))
                {
                    int index = IndexOf(item);

                    Container.InnerElement.RemoveAt(index);
                    Container.InnerElement.RemoveAt(index); //remove <br />
                    base.Remove(item);

                    return true;
                }

                else return false;
            }

            /// <summary>
            /// Get the index of a specific control.
            /// <para xml:lang="es">
            /// Obtiene el index de un control en especifico
            /// </para>
            /// </summary>
            /// <param name="item">Item
            /// <para xml:lang="es">El elemento.</para>
            /// </param>
            /// <returns>Int</returns>
            public int IndexOf(IControl item)
            {
                return Container.InnerElement.GetChildElementPosition(((Control) item).InnerElement);
            }
        }
    }
}
