// The MIT License (MIT)
//
// Copyright (C) 2026 Scott Duensing
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// dvx_video.h  -- Layer 1: VESA VBE video backend for DVX GUI
//
// The lowest layer in the DVX stack. Responsible for VESA VBE mode
// negotiation, linear framebuffer (LFB) mapping via DPMI, system RAM
// backbuffer allocation, and pixel format discovery.
//
// LFB-only design: bank switching is deliberately unsupported. Every
// VESA 2.0+ card provides LFB, and the code complexity of managing
// 64K bank windows (with scanlines that straddle bank boundaries) is
// not worth supporting ancient VESA 1.x hardware. If videoInit() can't
// find an LFB-capable mode, it fails immediately.
//
// This layer also owns color packing (RGB -> native pixel format) and
// the display-wide clip rectangle. These live here rather than in the
// draw layer because they depend on pixel format knowledge that only
// the video layer has.
#ifndef DVX_VIDEO_H
#define DVX_VIDEO_H

#include "dvxTypes.h"

// Probes VBE for a mode matching the requested resolution and depth,
// enables it, maps the LFB into the DPMI linear address space, and
// allocates a system RAM backbuffer of the same size. preferredBpp is
// a hint  -- if the exact depth isn't available, the closest match is used.
int32_t videoInit(DisplayT *d, int32_t requestedW, int32_t requestedH, int32_t preferredBpp);

// Restores VGA text mode (INT 10h AH=0, mode 3), unmaps the LFB, and
// frees the backbuffer. Safe to call even if videoInit() failed.
void videoShutdown(DisplayT *d);

// Pack an RGB triplet into the display's native pixel format.
// For direct-color modes (15/16/32 bpp): returns a packed pixel value
// using the shift/mask fields from PixelFormatT.
// For 8-bit mode: returns the nearest palette index using Euclidean
// distance in RGB space (fast path through the 6x6x6 color cube, then
// linear scan of the grey ramp and chrome entries).
uint32_t packColor(const DisplayT *d, uint8_t r, uint8_t g, uint8_t b);

// Unpack a native pixel value back to 8-bit R, G, B components.
void unpackColor(const DisplayT *d, uint32_t color, uint8_t *r, uint8_t *g, uint8_t *b);

// Set the clip rectangle on the display. All subsequent draw operations
// will be clipped to this rectangle. The caller is responsible for
// saving and restoring the clip rect around scoped operations.
void setClipRect(DisplayT *d, int32_t x, int32_t y, int32_t w, int32_t h);

// Reset clip rectangle to the full display dimensions.
void resetClipRect(DisplayT *d);

#endif // DVX_VIDEO_H
