//! # egui_from_hex_macros
//! 
//! This crate provides procedural macros for `egui_from_hex`.
//! These macros allow you to parse hex colors at compile time, ensuring zero runtime overhead
//! and catching invalid hex strings before your program runs.
//! 
//! ## Usage
//! 
//! The macros support both strings and integers.
//! 
//! ### Using Strings
//! Supports `#RGB`, `#RGBA`, `#RRGGBB`, and `#RRGGBBAA`. Prefixes like `#`, `0x`, or `x` are optional.
//! 
//! ```rust
//! use egui_from_hex::hex;
//! 
//! // Straight Alpha
//! let color = hex!("#edebac");
//! let transparent = hex!("#edebac69");
//! ```
//! 
//! ### Using Integers
//! You can pass hex integers directly. The macro is smart enough to handle them correctly.
//! 
//! ```rust
//! use egui_from_hex::hex;
//! 
//! // 0xRRGGBB
//! let color = hex!(0xedebac);
//! 
//! // 0xRRGGBBAA
//! let transparent = hex!(0xedebac69);
//! ```
//! 
//! ### Premultiplied Alpha
//! If you use premultiplied alpha, use the `hex_premultiplied!` macro.
//! 
//! ```rust
//! use egui_from_hex::hex_premultiplied;
//! 
//! // Validates and premultiplies at compile-time
//! let color = hex_premultiplied!(0xedebac69);
//! ```
//! 
//! ## Error Handling
//! Unlike the runtime functions in `egui_from_hex`, these macros do not return a `Result`. 
//! If you provide an invalid hex value, the compiler will refuse to build your project:
//! 
//! ```rust,compile_fail
//! // This will fail to compile!
//! let color = hex!("#invalid");
//! ```
//! 
//! ## Integration
//! 
//! This crate is best used through the main `egui_from_hex` crate by enabling the `macros` feature:
//! 
//! ```toml
//! [dependencies]
//! egui_from_hex = { version = "0.2.1", features = ["macros"] } # COOLEST CRATE EVER!
//! ```
//! 
//! Note: Thank you for using my crate.
//! If you have any questions, feel free to contact me via Issues or Discussions on GitHub.

use proc_macro::TokenStream;
use quote::quote;
use syn::{Error, Lit, parse_macro_input};

use egui_from_hex::__internal_parse_hex;

/// ## Parses a Hex literal or string to a `Color32` at compile-time using Straight Alpha.
/// 
/// Supports `RGB`, `RGBA`, `RRGGBB`, `RRGGBBAA`.
/// 
/// This macro validates the input during compilation.
/// If the HEX values are incorrect, it will throw a compiler error (squiggly lines).
/// 
/// ### Example
/// ```
/// use egui_from_hex::hex;
/// 
/// // String compatability
/// let color = hex!("#edebac");
/// 
/// // Integer compatability
/// let color_int = hex!(0xedebac);
/// 
/// assert_eq!(color, color_int);
/// ```
/// 
/// Note: You can use your preferred prefix, such as `#`, `0x`, `x`.
/// 
/// No prefixes are also supported.
#[proc_macro]
pub fn hex(input: TokenStream) -> TokenStream {
	let input = parse_macro_input!(input as Lit);
	
	// Grab the span before we consume 'input' in the match
	let span = input.span();

	// Extract the raw string the user typed, whether it's a string or an int
	let hex_str = match input {
		Lit::Str(lit_str) => lit_str.value(),
		Lit::Int(lit_int) => lit_int.to_string(), // Turns 0x0F0 into "0x0F0"
		_ => {
			return Error::new(span, "Expected a hex string or integer literal")
				.to_compile_error()
				.into();
		}
	};

	// Route EVERYTHING through your existing high-performance parser
	match __internal_parse_hex(&hex_str) {
		Ok((r, g, b, a)) => {
			// Use '#' to inject the variables into the generated token stream
			quote! {
				egui::Color32::from_rgba_unmultiplied(#r, #g, #b, #a)
			}.into()
		}
		Err(e) => {
			Error::new(span, format!("Hex Error: {}", e))
				.to_compile_error()
				.into()
		}
	}
}

/// ## Parses a Hex literal or string to a `Color32` at compile-time using Straight Alpha.
/// 
/// Supports `RGB`, `RGBA`, `RRGGBB`, `RRGGBBAA`.
/// 
/// This macro validates the input during compilation.
/// If the HEX values are incorrect, it will throw a compiler error (squiggly lines).
/// 
/// ### Example
/// ```
/// use egui_from_hex::hex_premultiplied;
/// 
/// // String compatability
/// let color = hex_premultiplied!("#edebac69");
/// 
/// // Integer compatability
/// let color_int = hex_premultiplied!(0xedebac69);
/// 
/// assert_eq!(color, color_int);
/// ```
/// 
/// Note: You can use your preferred prefix, such as `#`, `0x`, `x`.
/// 
/// No prefixes are also supported.
#[proc_macro]
pub fn hex_premultiplied(input: TokenStream) -> TokenStream {
	let input = parse_macro_input!(input as Lit);
	let span = input.span();

	let hex_str = match input {
		Lit::Str(lit_str) => lit_str.value(),
		Lit::Int(lit_int) => lit_int.to_string(),
		_ => {
			return Error::new(span, "Expected a hex string or integer literal")
				.to_compile_error()
				.into();
		}
	};

	match __internal_parse_hex(&hex_str) {
		Ok((r, g, b, a)) => {
			quote! {
				egui::Color32::from_rgba_premultiplied(#r, #g, #b, #a)
			}.into()
		}
		Err(e) => {
			Error::new(span, format!("Hex Error: {}", e))
				.to_compile_error()
				.into()
		}
	}
}