using Microsoft.Extensions.Logging; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; namespace Inspectron.Epson; /// /// IEpsonPrinter proxy that defers HtmlPrinter creation until ConnectAsync is called, /// selecting the correct configuration (output file, printer ID, paper width) based on the IP address. /// public class EmulationPrinterProxy : IEpsonPrinter { private readonly Dictionary _printerConfigs; private readonly ILogger? _logger; private HtmlPrinter? _inner; public EmulationPrinterProxy( Dictionary printerConfigs, ILogger? logger = null) { _printerConfigs = printerConfigs; _logger = logger; } public bool IsConnected => _inner?.IsConnected ?? false; public Task ConnectAsync(string ip, int port = 9100, int timeoutSeconds = 10) { if (!_printerConfigs.TryGetValue(ip, out var config)) throw new EpsonConnectionException($"No emulation configuration for IP {ip}"); _logger?.LogInformation("EmulationPrinterProxy: Creating HtmlPrinter for {IP} (id=0x{Id:X2}, width={Width}px, output={Path})", ip, config.PrinterId, config.PaperWidth, config.OutputPath); _inner = new HtmlPrinter(config.OutputPath, config.PaperWidth, _logger, config.PrinterId); return _inner.ConnectAsync(ip, port, timeoutSeconds); } private HtmlPrinter Inner => _inner ?? throw new EpsonConnectionException("Not connected. Call ConnectAsync first."); public void Disconnect() => Inner.Disconnect(); public Task GetPrinterStatusAsync() => Inner.GetPrinterStatusAsync(); public Task GetOfflineStatusAsync() => Inner.GetOfflineStatusAsync(); public Task GetErrorStatusAsync() => Inner.GetErrorStatusAsync(); public Task GetPaperSensorStatusAsync() => Inner.GetPaperSensorStatusAsync(); public Task GetTM220StatusAsync() => Inner.GetTM220StatusAsync(); public Task GetPrinterIdAsync() => Inner.GetPrinterIdAsync(); public Task GetOverallStatusAsync() => Inner.GetOverallStatusAsync(); public Task InitAsync() => Inner.InitAsync(); public Task SetQuadrupleMode(bool enable) => Inner.SetQuadrupleMode(enable); public Task SetRedColor(bool enable) => Inner.SetRedColor(enable); public Task SetEmphasized(bool enable) => Inner.SetEmphasized(enable); public Task SelectFont(EpsonCommands.PrinterFont font) => Inner.SelectFont(font); public Task SetBiggerFontTM220(bool biggerWidth, bool biggerHeight = false, bool secondaryFont = true) => Inner.SetBiggerFontTM220(biggerWidth, biggerHeight, secondaryFont); public Task PrintTextAsync(string text) => Inner.PrintTextAsync(text); public Task SetFontSizeAsync(int width, int height) => Inner.SetFontSizeAsync(width, height); public Task PrintTextAndCutAsync(string text, int feedLines = 5) => Inner.PrintTextAndCutAsync(text, feedLines); public Task PrintBuffer() => Inner.PrintBuffer(); public Task FeedLinesAsync(int lines) => Inner.FeedLinesAsync(lines); public Task CutAsync(bool fullCut = true) => Inner.CutAsync(fullCut); public Task LoadImageAsync(string imagePath, int maxWidth = 384) => Inner.LoadImageAsync(imagePath, maxWidth); public Task LoadImageAsync(Stream imageStream, int maxWidth = 384) => Inner.LoadImageAsync(imageStream, maxWidth); public Task LoadImageAsync(Image image, int maxWidth = 384) => Inner.LoadImageAsync(image, maxWidth); public Task PrintLoadedImage() => Inner.PrintLoadedImage(); public Task PrintImageBitModeAsync(string imagePath, EpsonCommands.BitImageMode mode = EpsonCommands.BitImageMode.SingleDensity8Dot, int maxWidth = 10) => Inner.PrintImageBitModeAsync(imagePath, mode, maxWidth); public Task PrintImageBitModeAsync(Stream imageStream, EpsonCommands.BitImageMode mode = EpsonCommands.BitImageMode.DoubleDensity24Dot, int maxWidth = 384) => Inner.PrintImageBitModeAsync(imageStream, mode, maxWidth); public Task PrintImageBitModeAsync(Image image, EpsonCommands.BitImageMode mode, int maxWidth) => Inner.PrintImageBitModeAsync(image, mode, maxWidth); public Task SendRawCommandAsync(byte[] command) => Inner.SendRawCommandAsync(command); public Task SetAbsolutePrintPosition(int x) => Inner.SetAbsolutePrintPosition(x); public Task SetDefaultLineSpacing() => Inner.SetDefaultLineSpacing(); public Task SetCustomLineSpacing(int spacing = 24) => Inner.SetCustomLineSpacing(spacing); public ValueTask DisposeAsync() { if (_inner != null) return _inner.DisposeAsync(); return ValueTask.CompletedTask; } }