using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SlatedGameToolkit.Framework.Graphics.OpenGL;
using SlatedGameToolkit.Framework.Logging;

namespace SlatedGameToolkit.Framework.Graphics.Window
{
    public static class WindowContextsManager {
        internal static WindowContext current;

        /// <summary>
        /// The current window context.
        /// </summary>
        /// <value>The currently active window context.</value>
        public static WindowContext CurrentWindowContext {
            get {
                return current;
            }

            set {
                value.MakeCurrent();
            }
        }
        
        private static Dictionary<uint, WindowContext> existingWindows = new Dictionary<uint, WindowContext>();
        
        /// <summary>
        /// The currently loaded windows.
        /// </summary>
        /// <typeparam name="uint">The ID of the window.</typeparam>
        /// <typeparam name="WindowContext">The window context.</typeparam>
        /// <returns>A readonly dictionary of all the window contexts that were created.</returns>
        public static ReadOnlyDictionary<uint, WindowContext> LoadedWindows { get; private set; } = new ReadOnlyDictionary<uint, WindowContext>(existingWindows);

        /// <summary>
        /// The OpenGL context of the active window.
        /// Equivalent to retrieving the current window context, and then using the context from that instance.
        /// </summary>
        /// <value>The currently active window's OpenGL context.</value>
        public static GLContext CurrentGL {
            get {
                return CurrentWindowContext.Context;
            }
        }

        internal static void RegisterWindow(WindowContext windowHandle) {
            Logger.Log("Registering window: " + windowHandle.WindowID, LogLevel.DEBUG);
            existingWindows.Add(windowHandle.WindowID, windowHandle);
        }
        
        internal static void DeregisterWindow(WindowContext windowHandle) {
            Logger.Log("Deregistering window: " + windowHandle.WindowID, LogLevel.DEBUG);
            existingWindows.Remove(windowHandle.WindowID);
        }

        public static WindowContext ContextFromWindowID(uint ID) {
            return existingWindows[ID];
        }

        /// <summary>
        /// Disposes all the created window contexts.
        /// This includes their OpenGL contexts.
        /// </summary>
        public static void DisposeAllWindowContexts() {
            foreach (WindowContext context in LoadedWindows.Values)
            {
                context.Dispose();
            }
        }
    }
}