//! Constants, configurations, and core structures used across the `ssocr-rs` crate.
//!
//! This module defines the segment layouts, digit bitmasks, image processing option flags,
//! and configuration structures that govern the behavior of the Seven Segment OCR processor.

#![allow(non_upper_case_globals, dead_code)]

/// The program name.
pub const PROG: &str = "ssocr-rs";
/// The program version.
pub const VERSION: &str = "2.25.1-rs";

/// The default threshold value (in percent) to distinguish black from white.
pub const THRESHOLD: f64 = 50.0;

// States
/// Search state: finding a dark region.
pub const FIND_DARK: i32 = 0;
/// Search state: finding a light region.
pub const FIND_LIGHT: i32 = 1;

/// Constant representing a dark pixel/region.
pub const DARK: i32 = 0;
/// Constant representing a light pixel/region.
pub const LIGHT: i32 = 1;
/// Constant representing an unknown pixel/region state.
pub const UNKNOWN: i32 = 2;

// Segments
/// Bitmask for the upper horizontal segment (A).
pub const HORIZ_UP: u8 = 1;
/// Bitmask for the upper-left vertical segment (F).
pub const VERT_LEFT_UP: u8 = 2;
/// Bitmask for the upper-right vertical segment (B).
pub const VERT_RIGHT_UP: u8 = 4;
/// Bitmask for the middle horizontal segment (G).
pub const HORIZ_MID: u8 = 8;
/// Bitmask for the lower-left vertical segment (E).
pub const VERT_LEFT_DOWN: u8 = 16;
/// Bitmask for the lower-right vertical segment (C).
pub const VERT_RIGHT_DOWN: u8 = 32;
/// Bitmask for the lower horizontal segment (D).
pub const HORIZ_DOWN: u8 = 64;
/// Bitmask containing all active segments (A, B, C, D, E, F, G).
pub const ALL_SEGS: u8 = 127;
/// Bitmask representing the decimal point segment.
pub const DECIMAL: u8 = 128;
/// Bitmask representing a minus sign (same as middle segment).
pub const MINUS: u8 = HORIZ_MID;

/// Maximum value for character lookup table.
pub const CHARSET_MAX: usize = 128;

// Digits bitmasks
/// Bitmask representing digit '0' (all segments except middle horizontal).
pub const D_ZERO: u8 = ALL_SEGS & !HORIZ_MID;
/// Bitmask representing digit '1' (right vertical segments).
pub const D_ONE: u8 = VERT_RIGHT_UP | VERT_RIGHT_DOWN;
/// Bitmask representing digit '2'.
pub const D_TWO: u8 = ALL_SEGS & !(VERT_LEFT_UP | VERT_RIGHT_DOWN);
/// Bitmask representing digit '3'.
pub const D_THREE: u8 = ALL_SEGS & !(VERT_LEFT_UP | VERT_LEFT_DOWN);
/// Bitmask representing digit '4'.
pub const D_FOUR: u8 = ALL_SEGS & !(HORIZ_UP | VERT_LEFT_DOWN | HORIZ_DOWN);
/// Bitmask representing digit '5'.
pub const D_FIVE: u8 = ALL_SEGS & !(VERT_RIGHT_UP | VERT_LEFT_DOWN);
/// Bitmask representing digit '6'.
pub const D_SIX: u8 = ALL_SEGS & !VERT_RIGHT_UP;
/// Bitmask representing digit '7'.
pub const D_SEVEN: u8 = HORIZ_UP | VERT_RIGHT_UP | VERT_RIGHT_DOWN;
/// Alternate bitmask representing digit '7' with vertical left up segment.
pub const D_ALTSEVEN: u8 = VERT_LEFT_UP | D_SEVEN;
/// Bitmask representing digit '8' (all segments active).
pub const D_EIGHT: u8 = ALL_SEGS;
/// Bitmask representing digit '9' (all segments except lower-left vertical).
pub const D_NINE: u8 = ALL_SEGS & !VERT_LEFT_DOWN;
/// Alternate bitmask representing digit '9' without lower-left vertical and lower horizontal.
pub const D_ALTNINE: u8 = ALL_SEGS & !(VERT_LEFT_DOWN | HORIZ_DOWN);
/// Bitmask representing decimal point.
pub const D_DECIMAL: u8 = DECIMAL;
/// Bitmask representing a minus sign.
pub const D_MINUS: u8 = MINUS;
/// Bitmask representing hexadecimal letter 'a/A'.
pub const D_HEX_A: u8 = ALL_SEGS & !HORIZ_DOWN;
/// Bitmask representing hexadecimal letter 'b'.
pub const D_HEX_b: u8 = ALL_SEGS & !(HORIZ_UP | VERT_RIGHT_UP);
/// Bitmask representing hexadecimal letter 'C'.
pub const D_HEX_C: u8 = ALL_SEGS & !(VERT_RIGHT_UP | HORIZ_MID | VERT_RIGHT_DOWN);
/// Bitmask representing hexadecimal letter 'c'.
pub const D_HEX_c: u8 = HORIZ_MID | VERT_LEFT_DOWN | HORIZ_DOWN;
/// Bitmask representing hexadecimal letter 'd'.
pub const D_HEX_d: u8 = ALL_SEGS & !(HORIZ_UP | VERT_LEFT_UP);
/// Bitmask representing hexadecimal letter 'E'.
pub const D_HEX_E: u8 = ALL_SEGS & !(VERT_RIGHT_UP | VERT_RIGHT_DOWN);
/// Bitmask representing hexadecimal letter 'F'.
pub const D_HEX_F: u8 = ALL_SEGS & !(VERT_RIGHT_UP | VERT_RIGHT_DOWN | HORIZ_DOWN);
/// Bitmask representing letter 'U'.
pub const D_U: u8 = D_ZERO & !HORIZ_UP;
/// Bitmask representing letter 'T'.
pub const D_T: u8 = ALL_SEGS & !(HORIZ_UP | VERT_RIGHT_UP | VERT_RIGHT_DOWN);
/// Bitmask representing letter 'L'.
pub const D_L: u8 = D_T & !HORIZ_MID;
/// Bitmask representing letter 'H'.
pub const D_H: u8 = ALL_SEGS & !(HORIZ_UP | HORIZ_DOWN);
/// Bitmask representing letter 'h'.
pub const D_h: u8 = VERT_LEFT_UP | VERT_LEFT_DOWN | HORIZ_MID | VERT_RIGHT_DOWN;
/// Bitmask representing letter 'R'.
pub const D_R: u8 = D_ZERO & !(VERT_RIGHT_DOWN | HORIZ_DOWN);
/// Alternate bitmask representing letter 'R'.
pub const D_ALT_R: u8 = VERT_LEFT_UP | VERT_LEFT_DOWN | HORIZ_UP;
/// Bitmask representing letter 'r'.
pub const D_r: u8 = VERT_LEFT_DOWN | HORIZ_MID;
/// Bitmask representing letter 'P'.
pub const D_P: u8 = D_HEX_F | VERT_RIGHT_UP;
/// Bitmask representing letter 'N'.
pub const D_N: u8 = D_ZERO & !HORIZ_DOWN;
/// Bitmask representing letter 'n'.
pub const D_n: u8 = VERT_LEFT_DOWN | VERT_RIGHT_DOWN | HORIZ_MID;
/// Bitmask representing letter 'Y'.
pub const D_Y: u8 = ALL_SEGS & !(HORIZ_UP | VERT_LEFT_DOWN);
/// Bitmask representing letter 'J'.
pub const D_J: u8 = HORIZ_DOWN | VERT_RIGHT_UP | VERT_RIGHT_DOWN;
/// Alternate bitmask representing a malformed or custom '7' (used by TTRobot).
pub const D_TT_WRONG_SEVEN_1: u8 = D_SEVEN | VERT_LEFT_DOWN | HORIZ_DOWN;
/// Alternate bitmask representing another malformed or custom '7' (used by TTRobot).
pub const D_TT_WRONG_SEVEN_2: u8 = D_SEVEN | HORIZ_DOWN;
/// Bitmask representing an unknown character state (no segments active).
pub const D_UNKNOWN: u8 = 0;

/// Default number of expected digits to recognize.
pub const NUMBER_OF_DIGITS: i32 = 6;
/// Default maximum height-to-height ratio for a decimal point.
pub const DEC_H_RATIO: i32 = 5;
/// Default maximum width-to-width ratio for a decimal point.
pub const DEC_W_RATIO: i32 = 2;
/// Default height-to-width ratio required to recognize the digit '1'.
pub const ONE_RATIO: i32 = 3;
/// Default width-to-height ratio required to recognize a minus sign.
pub const MINUS_RATIO: i32 = 2;
/// Default multiplier/factor for spacing between digits.
pub const SPC_FAC: f64 = 1.4;
/// Default minimum pixels needed to recognize a segment.
pub const NEED_PIXELS: i32 = 1;
/// Default minimum size of a segment.
pub const MIN_SEGMENT: i32 = 1;
/// Default minimum width of a recognized character/digit.
pub const MIN_CHAR_W: i32 = 1;
/// Default minimum height of a recognized character/digit.
pub const MIN_CHAR_H: i32 = 1;
/// Default number of boundary pixels to ignore when locating characters.
pub const IGNORE_PIXELS: i32 = 0;

/// Default filename for the output debug image.
pub const DEBUG_IMAGE_NAME: &str = "testbild.png";

// Option flags
/// Do not adjust threshold to the average/min/max of the image.
pub const ABSOLUTE_THRESHOLD: u32 = 1;
/// Use the iterative thresholding method to find the optimal global threshold.
pub const DO_ITERATIVE_THRESHOLD: u32 = 1 << 1;
/// Print verbose logging of program execution.
pub const VERBOSE: u32 = 1 << 2;
/// Write intermediate and final debug images to disk.
pub const USE_DEBUG_IMAGE: u32 = 1 << 3;
/// Perform image processing commands only, skipping the OCR step.
pub const PROCESS_ONLY: u32 = 1 << 4;
/// Print additional image dimensions and luminance information.
pub const PRINT_INFO: u32 = 1 << 5;
/// Interpret gray-stretching values as percentages instead of absolute thresholds.
pub const ADJUST_GRAY: u32 = 1 << 6;
/// Output detailed debug tracing information to stdout/stderr.
pub const DEBUG_OUTPUT: u32 = 1 << 7;
/// Print the recognized segments as ASCII art representations.
pub const ASCII_ART_SEGMENTS: u32 = 1 << 8;
/// Format the binary segment output as hexadecimal characters.
pub const PRINT_AS_HEX: u32 = 1 << 9;
/// Omit any detected decimal points from the final output string.
pub const OMIT_DECIMAL: u32 = 1 << 10;
/// Print spaces in the output string if digits are separated by significant distance.
pub const PRINT_SPACES: u32 = 1 << 11;
/// Use average digit distance instead of minimum distance when deciding to insert spaces.
pub const SPC_USE_AVG_DST: u32 = 1 << 12;
/// Perform threshold adaptation after cropping rather than immediately.
pub const ADAPT_AFTER_CROP: u32 = 1 << 13;

/// Black pixel luminance value (usually 0).
pub const SSOCR_BLACK: u8 = 0;
/// White pixel luminance value (usually 255).
pub const SSOCR_WHITE: u8 = 255;
/// Default foreground color value (black).
pub const SSOCR_DEFAULT_FOREGROUND: u8 = SSOCR_BLACK;
/// Default background color value (white).
pub const SSOCR_DEFAULT_BACKGROUND: u8 = SSOCR_WHITE;

/// Maximum RGB value (255.0).
pub const MAXRGB: f64 = 255.0;

/// Represents Foreground (FG) or Background (BG) selector.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FgBg {
    /// Foreground pixel/region.
    FG,
    /// Background pixel/region.
    BG,
}

/// Formulas/methods for converting color pixels to luminance values.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LuminanceType {
    /// Use ITU-R Rec. BT.601-4 formula: 0.299*R + 0.587*G + 0.114*B.
    Rec601,
    /// Use ITU-R Rec. BT.709 formula: 0.2125*R + 0.7154*G + 0.0721*B.
    Rec709,
    /// Linear average: (R + G + B) / 3.0.
    Linear,
    /// Use minimum channel value: min(R, G, B).
    Minimum,
    /// Use maximum channel value: max(R, G, B).
    Maximum,
    /// Extract only the Red channel.
    Red,
    /// Extract only the Green channel.
    Green,
    /// Extract only the Blue channel.
    Blue,
}

/// Scan direction options.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
    /// Scan along the horizontal axis.
    Horizontal,
    /// Scan along the vertical axis.
    Vertical,
}

/// Supported character sets.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Charset {
    /// Full character set (digits, minus, hex, and letters).
    Full,
    /// Digits 0-9 only.
    Digits,
    /// Digits 0-9, decimal point, and minus sign.
    Decimal,
    /// Hexadecimal characters (0-9, a-f) plus decimal and minus.
    Hexadecimal,
    /// Special character set for table tennis robot displays.
    TTRobot,
}

/// Structure containing bounding box and OCR segment state of a detected digit.
#[derive(Debug, Clone, Default)]
pub struct DigitStruct {
    /// Bounding box top-left X coordinate.
    pub x1: i32,
    /// Bounding box top-left Y coordinate.
    pub y1: i32,
    /// Bounding box bottom-right X coordinate.
    pub x2: i32,
    /// Bounding box bottom-right Y coordinate.
    pub y2: i32,
    /// Bitmask of active segments.
    pub digit: u8,
    /// Number of blank spaces before this digit.
    pub spaces: i32,
}

/// A numeric range/interval with a minimum and maximum.
#[derive(Debug, Clone, Copy)]
pub struct IntervalStruct {
    /// Minimum value of the range.
    pub min: i32,
    /// Maximum value of the range.
    pub max: i32,
}

/// RGBA color representation helper.
pub struct ColorStruct {
    /// Red component.
    pub r: u8,
    /// Green component.
    pub g: u8,
    /// Blue component.
    pub b: u8,
    /// Alpha channel.
    pub a: u8,
}
