using System;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;

namespace ANSCENTER
{
    /// <summary>
    /// Unicode helper for LabVIEW .NET interop.
    /// All methods are static — no instance creation needed.
    /// In LabVIEW: use Invoke Node with class type ANSCENTER.ANSUnicodeHelper.
    /// Thread-safe: no shared mutable state.
    /// </summary>
    public class ANSUnicodeHelper
    {
        // Pre-compiled regex — compiled once at class load, zero per-call cost
        private static readonly Regex UnicodeEscapeRegex =
            new Regex(@"\\u([0-9a-fA-F]{4})", RegexOptions.Compiled);

        /// <summary>
        /// Constructor for LabVIEW (if needed). Lightweight, no state.
        /// </summary>
        public ANSUnicodeHelper() { }

        /// <summary>
        /// Decodes \uXXXX escape sequences to Unicode characters.
        /// ASCII strings pass through unchanged (zero allocation).
        /// </summary>
        public static string Decode(string input)
        {
            if (string.IsNullOrEmpty(input)) return input ?? string.Empty;
            if (input.IndexOf("\\u", StringComparison.Ordinal) < 0) return input;
            return UnicodeEscapeRegex.Replace(input, match =>
            {
                int codepoint = Convert.ToInt32(match.Groups[1].Value, 16);
                return ((char)codepoint).ToString();
            });
        }

        /// <summary>
        /// Draws Unicode string at position (x, y).
        /// </summary>
        public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, float x, float y)
        {
            if (g == null || string.IsNullOrEmpty(escapedText)) return;
            g.DrawString(Decode(escapedText), font, brush, x, y);
        }

        /// <summary>
        /// Draws Unicode string at position (x, y) with StringFormat.
        /// </summary>
        public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, float x, float y, StringFormat format)
        {
            if (g == null || string.IsNullOrEmpty(escapedText)) return;
            g.DrawString(Decode(escapedText), font, brush, x, y, format);
        }

        /// <summary>
        /// Draws Unicode string at PointF with StringFormat.
        /// </summary>
        public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, PointF point, StringFormat format)
        {
            if (g == null || string.IsNullOrEmpty(escapedText)) return;
            g.DrawString(Decode(escapedText), font, brush, point, format);
        }

        /// <summary>
        /// Draws Unicode string inside a RectangleF with word wrapping.
        /// </summary>
        public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, RectangleF layoutRect)
        {
            if (g == null || string.IsNullOrEmpty(escapedText)) return;
            g.DrawString(Decode(escapedText), font, brush, layoutRect);
        }

        /// <summary>
        /// Draws Unicode string inside a RectangleF with StringFormat.
        /// </summary>
        public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, RectangleF layoutRect, StringFormat format)
        {
            if (g == null || string.IsNullOrEmpty(escapedText)) return;
            g.DrawString(Decode(escapedText), font, brush, layoutRect, format);
        }

        /// <summary>
        /// Measures Unicode string size after decoding.
        /// </summary>
        public static SizeF MeasureString(Graphics g, string escapedText, Font font)
        {
            if (g == null || string.IsNullOrEmpty(escapedText)) return SizeF.Empty;
            return g.MeasureString(Decode(escapedText), font);
        }

        /// <summary>
        /// Measures Unicode string size with layout area and StringFormat.
        /// </summary>
        public static SizeF MeasureString(Graphics g, string escapedText, Font font, SizeF layoutArea, StringFormat format)
        {
            if (g == null || string.IsNullOrEmpty(escapedText)) return SizeF.Empty;
            return g.MeasureString(Decode(escapedText), font, layoutArea, format);
        }

        /// <summary>
        /// Checks if string contains \uXXXX escapes.
        /// </summary>
        public static bool HasUnicodeEscapes(string input)
        {
            if (string.IsNullOrEmpty(input)) return false;
            return input.IndexOf("\\u", StringComparison.Ordinal) >= 0;
        }

        /// <summary>
        /// Checks if string is pure ASCII.
        /// </summary>
        public static bool IsAsciiOnly(string input)
        {
            if (string.IsNullOrEmpty(input)) return true;
            foreach (char c in input)
            {
                if (c > 127) return false;
            }
            return true;
        }
    }
}
