using ButcherFactory.BO;
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ButcherFactory.SegmentStockUp_
{
  internal static class SegmentStockUpPrint
  {
    const string PRINTFILE = @"PrintTemplate\SegmentStockUpPrint.html";
    //public static void Print(StockUpDetail entity, string customer)
    //{
    //  var dic = new Dictionary<string, string>();
    //  dic.Add("$Customer_Name", customer);
    //  dic.Add("$DriverLine_Name", entity.DeliverGoodsLine_Name);
    //  dic.Add("$Date", entity.Date.ToString("yyyy/MM/dd"));
    //  BwpClientPrint.BwpClientWebPrint.Print(PRINTFILE, dic);
    //}

    //public static void Print2(StockUpDetail entity, string customer)
    //{
    //  PrintAPI.B_GetUSBBufferLen();
    //  PrintAPI.B_EnumUSB(new byte[128]);
    //  PrintAPI.B_CreateUSBPort(1);

    //  PrintAPI.B_Prn_Text_TrueType(42, 40, 36, "宋体", 1, 900, 0, 0, 0, "C1", "客户：张三");
    //  PrintAPI.B_Prn_Text_TrueType(42, 100, 36, "宋体", 1, 900, 0, 0, 0, "C2", "线路：青岛一线");
    //  PrintAPI.B_Prn_Text_TrueType(42, 160, 36, "宋体", 1, 900, 0, 0, 0, "C4", string.Format("日期：{0}", entity.Date.ToString("yyyy/MM/dd")));

    //  PrintAPI.B_Prn_Barcode(42, 220, 0, "1", 3, 22, 40, 'B', entity.BarCode);
    //  //PrintAPI.B_Prn_Text_TrueType(173, 360, 25, "宋体", 1, 500, 0, 0, 0, "C9", entity.BarCode);

    //  PrintAPI.B_Set_Direction('B');
    //  PrintAPI.B_Print_Out(1);
    //  PrintAPI.B_ClosePrn();
    //}

    public static void Print(SegmentStockUp entity, decimal last, SaleOutStoreInfo bill)
    {
      var templateString = File.ReadAllText("PrintTemplate\\SegmentStockUpPrint.txt", Encoding.UTF8);

      var str = string.Format(templateString, bill.Customer_Name, entity.DeliverGoodsLine_Name, entity.Date, entity.BarCode, last, bill.SendQueue);


      var printName = GetZebraPrintName();
      SendBytesToPrinter(printName, System.Text.Encoding.Default.GetBytes(str));
    }

    private static string GetZebraPrintName()
    {
      foreach (string item in PrinterSettings.InstalledPrinters)
      {
        PrinterSettings setting = new PrinterSettings() { PrinterName = item };
        if (setting.IsDefaultPrinter)
        {
          return setting.PrinterName;
        }
      }
      throw new Exception("没有找到对应的打印机");
    }

    [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string printerName, out IntPtr intptrPrinter, IntPtr intptrPrintDocument);

    [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool StartDocPrinter(IntPtr intptrPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DocInfo docInfo);

    [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool StartPagePrinter(IntPtr intptrPrinter);

    [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool EndDocPrinter(IntPtr intptrPrinter);

    [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool WritePrinter(IntPtr intptrPrinter, IntPtr intptrBytes, Int32 count, out Int32 written);

    [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool EndPagePrinter(IntPtr intptrPrinter);

    [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool ClosePrinter(IntPtr intptrPrinter);  

    #region 定义打印文档信息类
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public class DocInfo
    {
      [MarshalAs(UnmanagedType.LPStr)]
      public string DocName;
      [MarshalAs(UnmanagedType.LPStr)]
      public string OutputFile;
      [MarshalAs(UnmanagedType.LPStr)]
      public string DataType;
    }
    #endregion  

    public static bool SendBytesToPrinter(string printerName, byte[] bytes)
    {
      bool bSuccess = false;
      IntPtr pUnmanagedBytes = new IntPtr(0);
      int nLength = bytes.Length;
      // Allocate some unmanaged memory for those bytes.  
      pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
      // Copy the managed byte array into the unmanaged array.  
      Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
      // Send the unmanaged bytes to the printer.  
      bSuccess = SendBytesToPrinter(printerName, pUnmanagedBytes, nLength);
      // Free the unmanaged memory that you allocated earlier.  
      Marshal.FreeCoTaskMem(pUnmanagedBytes);
      return bSuccess;
    }

    private static bool SendBytesToPrinter(string printerName, IntPtr intptrBytes, Int32 count)
    {
      Int32 error = 0, written = 0;
      IntPtr intptrPrinter = new IntPtr(0);
      DocInfo docInfo = new DocInfo();
      bool bSuccess = false;

      docInfo.DocName = ".NET RAW Document";
      docInfo.DataType = "RAW";

      // Open the printer.  
      if (OpenPrinter(printerName.Normalize(), out intptrPrinter, IntPtr.Zero))
      {
        // Start a document.  
        if (StartDocPrinter(intptrPrinter, 1, docInfo))
        {
          // Start a page.  
          if (StartPagePrinter(intptrPrinter))
          {
            // Write your bytes.  
            bSuccess = WritePrinter(intptrPrinter, intptrBytes, count, out written);
            EndPagePrinter(intptrPrinter);
          }
          EndDocPrinter(intptrPrinter);
        }
        ClosePrinter(intptrPrinter);
      }
      // If you did not succeed, GetLastError may give more information  
      // about why not.  
      if (bSuccess == false)
      {
        error = Marshal.GetLastWin32Error();
      }
      return bSuccess;
    }  
  }
}
