/*
Crafter®.Graphics
Copyright (C) 2026 Catcrafts®
Catcrafts.net

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
*/
module;
// DOM builds drop the Vulkan header — DescriptorBinding (the only
// Vk-typed entity here) compiles out under the same guard below.
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
#include "vulkan/vulkan.h"
#endif
export module Crafter.Graphics:Types;
import std;
import Crafter.Math;

export namespace Crafter {
    struct MouseMoveEvent {
        Vector<float, 2> lastMousePos;
        Vector<float, 2> currentMousePos;
        Vector<float, 2> mouseDelta;
    };

    struct ScaleData2D {
        Vector<std::int16_t, 2, 2> position;
        Vector<std::int16_t, 2, 2> size;
    };

    struct ClipRect {
        std::uint16_t left;
		std::uint16_t right;
		std::uint16_t top;
		std::uint16_t bottom;
    };
    
    struct FrameTime {
        std::chrono::time_point<std::chrono::high_resolution_clock> now;
        std::chrono::duration<double> delta;
    };

    enum class CrafterKeys : std::uint8_t {
        // Alphabetic keys
        A, B, C, D, E, F, G, H, I, J, K, L, M,
        N, O, P, Q, R, S, T, U, V, W, X, Y, Z,

        // Numeric keys
        _0, _1, _2, _3, _4, _5, _6, _7, _8, _9,

        // Function keys
        F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,

        // Control keys
        Escape, Tab, Enter, Space, Backspace, Delete, Insert,
        Home, End, PageUp, PageDown, CapsLock, NumLock, ScrollLock,

        // Modifier keys
        LeftShift, RightShift, LeftCtrl, RightCtrl,
        LeftAlt, RightAlt, LeftSuper, RightSuper,

        // Arrow keys
        Up, Down, Left, Right,

        // Keypad keys
        keypad_0, keypad_1, keypad_2, keypad_3, keypad_4,
        keypad_5, keypad_6, keypad_7, keypad_8, keypad_9,
        keypad_enter, keypad_plus, keypad_minus, keypad_multiply,
        keypad_divide, keypad_decimal,

        // Punctuation and special keys
        grave, minus, equal, bracket_left, bracket_right,
        backslash, semicolon, quote, comma, period, slash,
        print_screen, pause, menu,

        // Additional keys
        volume_up, volume_down, volume_mute,
        media_play, media_stop, media_prev, media_next,
        browser_back, browser_forward, browser_refresh,
        browser_stop, browser_search, browser_home,
        launch_mail, launch_calculator, launch_media_player,

        CrafterKeysMax
    };

    constexpr std::string CrafterKeyToString(CrafterKeys key) {
        switch (key) {
            // Alphabetic keys
            case CrafterKeys::A: return "A";
            case CrafterKeys::B: return "B";
            case CrafterKeys::C: return "C";
            case CrafterKeys::D: return "D";
            case CrafterKeys::E: return "E";
            case CrafterKeys::F: return "F";
            case CrafterKeys::G: return "G";
            case CrafterKeys::H: return "H";
            case CrafterKeys::I: return "I";
            case CrafterKeys::J: return "J";
            case CrafterKeys::K: return "K";
            case CrafterKeys::L: return "L";
            case CrafterKeys::M: return "M";
            case CrafterKeys::N: return "N";
            case CrafterKeys::O: return "O";
            case CrafterKeys::P: return "P";
            case CrafterKeys::Q: return "Q";
            case CrafterKeys::R: return "R";
            case CrafterKeys::S: return "S";
            case CrafterKeys::T: return "T";
            case CrafterKeys::U: return "U";
            case CrafterKeys::V: return "V";
            case CrafterKeys::W: return "W";
            case CrafterKeys::X: return "X";
            case CrafterKeys::Y: return "Y";
            case CrafterKeys::Z: return "Z";

            // Numeric keys
            case CrafterKeys::_0: return "0";
            case CrafterKeys::_1: return "1";
            case CrafterKeys::_2: return "2";
            case CrafterKeys::_3: return "3";
            case CrafterKeys::_4: return "4";
            case CrafterKeys::_5: return "5";
            case CrafterKeys::_6: return "6";
            case CrafterKeys::_7: return "7";
            case CrafterKeys::_8: return "8";
            case CrafterKeys::_9: return "9";

            // Function keys
            case CrafterKeys::F1:  return "F1";
            case CrafterKeys::F2:  return "F2";
            case CrafterKeys::F3:  return "F3";
            case CrafterKeys::F4:  return "F4";
            case CrafterKeys::F5:  return "F5";
            case CrafterKeys::F6:  return "F6";
            case CrafterKeys::F7:  return "F7";
            case CrafterKeys::F8:  return "F8";
            case CrafterKeys::F9:  return "F9";
            case CrafterKeys::F10: return "F10";
            case CrafterKeys::F11: return "F11";
            case CrafterKeys::F12: return "F12";

            // Control keys
            case CrafterKeys::Escape:     return "Escape";
            case CrafterKeys::Tab:        return "Tab";
            case CrafterKeys::Enter:      return "Enter";
            case CrafterKeys::Space:      return "Space";
            case CrafterKeys::Backspace:  return "Backspace";
            case CrafterKeys::Delete:     return "Delete";
            case CrafterKeys::Insert:     return "Insert";
            case CrafterKeys::Home:       return "Home";
            case CrafterKeys::End:        return "End";
            case CrafterKeys::PageUp:     return "PageUp";
            case CrafterKeys::PageDown:   return "PageDown";
            case CrafterKeys::CapsLock:   return "CapsLock";
            case CrafterKeys::NumLock:    return "NumLock";
            case CrafterKeys::ScrollLock: return "ScrollLock";

            // Modifier keys
            case CrafterKeys::LeftShift:  return "LeftShift";
            case CrafterKeys::RightShift: return "RightShift";
            case CrafterKeys::LeftCtrl:   return "LeftCtrl";
            case CrafterKeys::RightCtrl:  return "RightCtrl";
            case CrafterKeys::LeftAlt:    return "LeftAlt";
            case CrafterKeys::RightAlt:   return "RightAlt";
            case CrafterKeys::LeftSuper:  return "LeftSuper";
            case CrafterKeys::RightSuper: return "RightSuper";

            // Arrow keys
            case CrafterKeys::Up:    return "Up";
            case CrafterKeys::Down:  return "Down";
            case CrafterKeys::Left:  return "Left";
            case CrafterKeys::Right: return "Right";

            // Keypad keys
            case CrafterKeys::keypad_0:        return "Keypad0";
            case CrafterKeys::keypad_1:        return "Keypad1";
            case CrafterKeys::keypad_2:        return "Keypad2";
            case CrafterKeys::keypad_3:        return "Keypad3";
            case CrafterKeys::keypad_4:        return "Keypad4";
            case CrafterKeys::keypad_5:        return "Keypad5";
            case CrafterKeys::keypad_6:        return "Keypad6";
            case CrafterKeys::keypad_7:        return "Keypad7";
            case CrafterKeys::keypad_8:        return "Keypad8";
            case CrafterKeys::keypad_9:        return "Keypad9";
            case CrafterKeys::keypad_enter:    return "KeypadEnter";
            case CrafterKeys::keypad_plus:     return "KeypadPlus";
            case CrafterKeys::keypad_minus:    return "KeypadMinus";
            case CrafterKeys::keypad_multiply: return "KeypadMultiply";
            case CrafterKeys::keypad_divide:   return "KeypadDivide";
            case CrafterKeys::keypad_decimal:  return "KeypadDecimal";

            // Punctuation and special keys
            case CrafterKeys::grave:         return "Grave";
            case CrafterKeys::minus:         return "Minus";
            case CrafterKeys::equal:         return "Equal";
            case CrafterKeys::bracket_left:  return "BracketLeft";
            case CrafterKeys::bracket_right: return "BracketRight";
            case CrafterKeys::backslash:     return "Backslash";
            case CrafterKeys::semicolon:     return "Semicolon";
            case CrafterKeys::quote:         return "Quote";
            case CrafterKeys::comma:         return "Comma";
            case CrafterKeys::period:        return "Period";
            case CrafterKeys::slash:         return "Slash";
            case CrafterKeys::print_screen:  return "PrintScreen";
            case CrafterKeys::pause:         return "Pause";
            case CrafterKeys::menu:          return "Menu";

            // Additional keys
            case CrafterKeys::volume_up:          return "VolumeUp";
            case CrafterKeys::volume_down:        return "VolumeDown";
            case CrafterKeys::volume_mute:        return "VolumeMute";
            case CrafterKeys::media_play:         return "MediaPlay";
            case CrafterKeys::media_stop:         return "MediaStop";
            case CrafterKeys::media_prev:         return "MediaPrev";
            case CrafterKeys::media_next:         return "MediaNext";
            case CrafterKeys::browser_back:       return "BrowserBack";
            case CrafterKeys::browser_forward:    return "BrowserForward";
            case CrafterKeys::browser_refresh:    return "BrowserRefresh";
            case CrafterKeys::browser_stop:       return "BrowserStop";
            case CrafterKeys::browser_search:     return "BrowserSearch";
            case CrafterKeys::browser_home:       return "BrowserHome";
            case CrafterKeys::launch_mail:        return "LaunchMail";
            case CrafterKeys::launch_calculator:  return "LaunchCalculator";
            case CrafterKeys::launch_media_player:return "LaunchMediaPlayer";

            case CrafterKeys::CrafterKeysMax: return "Unknown";
        }
        return "Unknown";
    }

    template <typename T, typename T2>
    constexpr T AlignUp(T value, T2 alignment) {
        return (value + alignment - 1) & ~(alignment - 1);
    }

    template <typename T>
    constexpr T GetTanHalfFov(T fov) {
        return std::tan(fov * std::numbers::pi / 360.0);
    }

    #ifndef CRAFTER_GRAPHICS_WINDOW_DOM
    struct DescriptorBinding {
        VkDescriptorType type;
        std::uint32_t slot;
    };
    #endif
}
