using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Echo.UserInterface.Backend;
using ImGuiNET;
using SDL2;
using skyscraper8.Skyscraper.FrequencyListGenerator;
using testdrid.SdlWrapper;

namespace SDL2Demo.Forms
{
    internal class PictureWindow : IRenderable, IDisposable
    {
        private readonly string _title;
        private Texture _texture;
        private Surface _surface;
        private Vector2 _sizeVector;
        public bool isOpen;
        public Vector2 position;

        public PictureWindow(Renderer renderer, string title, byte[] buffer)
        {
            if (string.IsNullOrEmpty(title))
                throw new ArgumentNullException(nameof(title));
            
            _title = title;

            lock (Renderer.Lockable)
            {
                _surface = Surface.ImageLoadFromPtr(buffer);
                _texture = Texture.FromSurface(renderer, _surface);
                SDL.SDL_Surface data = _surface.GetSurfaceData();
                _sizeVector = new Vector2(data.w, data.h);
                isOpen = true;
                position = new Vector2(100, 100);
            }
        }

        ~PictureWindow()
        {
            Dispose();
        }

        public void Render()
        {
            if (!isOpen)
            {
                Dispose();
                return;
            }

            ImGui.PushStyleVar(ImGuiStyleVar.WindowMinSize, _sizeVector);
            ImGui.SetNextWindowPos(position, ImGuiCond.FirstUseEver | ImGuiCond.Once);
            if (ImGui.Begin(_title, ref isOpen, ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoSavedSettings))
            {
                ImGui.Image(_texture.Pointer, _sizeVector);
            }
            ImGui.End();
            ImGui.PopStyleVar();
        }


        private bool disposed;
        public void Dispose()
        {
	        if (disposed)
		        return;

	        tasks.EnqueueTask(() =>
	        {
		        renderables.Remove(this);
		        _texture.Dispose();
		        _surface.Dispose();
	        });

	        disposed = true;
        }
        
        internal static Renderer Renderer { get; set; }

        public void SetPosition(int x, int y)
        {
            position.X = x;
            position.Y = y;
        }

        private TaskQueue tasks;
        private List<IRenderable> renderables;
        public void SetTaskQueue(TaskQueue tasks, List<IRenderable> jobContextRenderables)
        {
	        this.tasks = tasks;
	        this.renderables = jobContextRenderables;
        }
    }
}
