using Quik.CommandMachine;
using Quik.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Quik.PAL
{
    /// <summary>
    /// An abstraction layer over the UI input and output.
    /// </summary>
    public class QuikPort
    {
        private readonly IQuikPortHandle handle;
        private readonly IQuikPlatform platform;

        public string Title
        { 
            get => platform.PortGetTitle(handle);
            set => platform.PortSetTitle(handle, value);
        }

        public QVec2 Size
        { 
            get => platform.PortGetSize(handle);
            set => platform.PortSetSize(handle, value);
        }

        public QVec2 Position
        { 
            get => platform.PortGetPosition(handle); 
            set => platform.PortSetPosition(handle, value);
        }

        public UIBase UIElement { get; set; }

        public bool IsValid => platform.PortIsValid(handle);

        public event EventHandler EventRaised
        {
            add
            {
                platform.PortSubscribeEvent(handle, value);
            }
            remove
            {
                platform.PortUnsubscribeEvent(handle, value);
            }
        }

        public QuikPort(IQuikPlatform platform)
        {
            this.platform = platform;
            handle = platform.CreatePort();
        }

        bool isDisposed = false;
        public void Dispose()
        {
            if (isDisposed) return;

            platform.DestroyPort(handle);
            isDisposed = true;
        }

        public void Focus()
        {
            platform.PortFocus(handle);
        }

        public void Paint(CommandList list = null)
        {
            if (UIElement == null)
                return;

            if(list == null)
                list = new CommandList();

            list.Clear();
            UIElement.Bounds = new QRectangle(Size, new QVec2(0,0));
            UIElement.Paint(list);
            platform.PortPaint(handle, list);
        }

        public void Show(bool shown = true)
        {
            platform.PortShow(handle, shown);
        }
    }
}