use crate::structs::{Status, GUID};
use crate::types::char16;

#[repr(C)]
pub struct SimpleTextOutputProtocol {
    pub reset: TextReset,
    pub output_string: TextString,
    pub test_string: TextTestString,
    pub query_mode: TextQueryMode,
    pub set_mode: TextSetMode,
    pub set_attribute: TextSetAttribute,
    pub clear_screen: TextClearScreen,
    pub set_cursor_position: TextSetCursorPosition,
    pub enable_cursor: TextEnableCursor,
    pub mode: *mut SimpleTextOutputMode,
}

impl SimpleTextOutputProtocol {
    pub const SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID: GUID = GUID {
        data1: 0x387477c2,
        data2: 0x69c7,
        data3: 0x11d2,
        data4: [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b],
    };
}

pub type TextReset =
    extern "efiapi" fn(this: &SimpleTextOutputProtocol, extended_verification: bool) -> Status;
pub type TextString =
    extern "efiapi" fn(this: &SimpleTextOutputProtocol, string: *const char16) -> Status;
pub type TextTestString =
    extern "efiapi" fn(this: &SimpleTextOutputProtocol, string: *const char16) -> Status;
pub type TextQueryMode = extern "efiapi" fn(
    this: &SimpleTextOutputProtocol,
    mode_number: usize,
    column: &mut usize,
    rows: &mut usize,
) -> Status;
pub type TextSetMode =
    extern "efiapi" fn(this: &SimpleTextOutputProtocol, mode_number: usize) -> Status;
pub type TextSetAttribute =
    extern "efiapi" fn(this: &SimpleTextOutputProtocol, Attribute: usize) -> Status;
pub type TextClearScreen = extern "efiapi" fn(this: &SimpleTextOutputProtocol) -> Status;
pub type TextSetCursorPosition =
    extern "efiapi" fn(this: &SimpleTextOutputProtocol, column: usize, row: usize) -> Status;
pub type TextEnableCursor =
    extern "efiapi" fn(this: &SimpleTextOutputProtocol, visible: bool) -> Status;

#[repr(C)]
pub enum Attribute {
    Black = 0x00,
    Blue = 0x01,
    Green = 0x02,
    Cyan = 0x03,
    Red = 0x04,
    Magenta = 0x05,
    Brown = 0x06,
    LightGray = 0x07,
    Bright = 0x08,
    // DarkGray = 0x08 ,
    LightBlue = 0x09,
    LightGreen = 0x0a,
    LightCyan = 0x0b,
    LightRed = 0x0c,
    LightMagenta = 0x0d,
    Yellow = 0x0e,
    White = 0x0f,
    // BackgroundBlack = 0x00 ,
    BackgroundBlue = 0x10,
    BackgroundGreen = 0x20,
    BackgroundCyan = 0x30,
    BackgroundRed = 0x40,
    BackgroundMagenta = 0x50,
    BackgroundBrown = 0x60,
    BackgroundLightGray = 0x70,
}

#[repr(C)]
pub struct SimpleTextOutputMode {
    max_mode: i32,
    mode: i32,
    attribute: i32,
    cursor_column: i32,
    cursor_row: i32,
    cursor_visible: bool,
}
