using dmy.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace dmy.Library
{
   public class TuoLiDuo
    {
		//没有实体类的信息，请自行创建
        #region 托利多电子秤
        /// <summary> 
        /// 托利多条码秤上传下载接口 /// </summary> 
        /// <param name="str">传输配置文件(配置秤号和传输文件信息)</param> 
        ///  <param name="nkey">暂无意义</param> 
        ///  <returns></returns> 
        [DllImport("TransferEth.dll", EntryPoint = "Transfer_Ethernet", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Winapi)]
        public static extern int Transfer_Ethernet(StringBuilder str);
        
        /// <summary>
        /// 以文件方式传入参数执行任务，Ansi版本，文件必须以UTF-8格式保存
        /// </summary>
        /// <param name="szTaskID">传入的任务编号（唯一）,Ansi编码</param>
        /// <param name="szInputFile">传入的任务信息文件名（全路径），Ansi编码</param>
        /// <param name="szOutputFile">需要生成的任务结果信息文件名（全路径），Ansi编码</param>
        /// <param name="bSynch">执行方式，True为同步执行，即传输完毕后再返回，False为异步执行，即验证完输入参数正确性后就返回，后台自动执行任务。</param>
        /// <returns></returns>
        [DllImport("MTScaleAPI.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi)]
        public static extern bool ExecuteTaskInFile(string szTaskID, string szInputFile, string szOutputFile, bool bSynch);


        /// <summary>
        /// 以Xml字符串的方式传入参数执行任务，Ansi版本，由于内存占用的关系，字符串方式不能执行大数据的任务
        /// </summary>
        /// <param name="szTaskID">传入的任务编号（唯一），Ansi编码</param>
        /// <param name="szInput">传入的Xml信息字符串，Xml结构参见《3 传输结构说明》，Ansi编码</param>
        /// <param name="bSynch">执行方式，True为同步执行，即传输完毕后再返回，False为异步执行，即验证完输入参数正确性后就返回，后台自动执行任务。</param>
        /// <returns></returns>
        [DllImport("MTScaleAPI.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi)]
        public static extern bool ExecuteTaskInString(string szTaskID, string szInput, bool bSynch);


        /// <summary>
        /// 查询指定的任务状态，以Xml字符串的方式传入参数，Ansi版本。
        /// </summary>
        /// <param name="szInput">传入的Xml信息字符串，Xml结构参见《3 传输结构说明》，Ansi编码</param>
        /// <returns>返回指定的任务状态，以Xml形式体现，如果是批量查询多个任务，只返回已经存在的任务的状态，Ansi编码。</returns>
        [DllImport("MTScaleAPI.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi)]
        public static extern bool QueryTask(string szInput);

        /// <summary>
        /// 取消指定的任务，以字符串的方式传入参数，Ansi编码。
        /// </summary>
        /// <param name="szInput">传入的任务编号，Ansi编码。</param>
        /// <returns>返回调用是否成功。</returns>
        [DllImport("MTScaleAPI.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi)]
        public static extern bool CancelTask(string szInput);



        /// <summary>
        /// 查询中间件指定组件的配置参数，或电子秤列表，以字符串的方式传入参数，Ansi版本。
        /// </summary>
        /// <param name="szInput">传入的Xml信息字符串, Xml结构参见《3 传输结构说明》，Ansi编码。</param>
        /// <returns></returns>
        [DllImport("MTScaleAPI.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi)]
        public static extern bool QueryStatus(string szInput);


        /// <summary>
        /// 释放以上方法中返回的字符串资源，必须调用，否则会产生内存泄漏。
        /// </summary>
        /// <param name="p">，传入的字符串指针。</param>
        /// <returns></returns>
        [DllImport("MTScaleAPI.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi)]
        public static extern bool Free(IntPtr p);


        /// <summary>
        /// 释放动态库资源，动态调用动态库时，必须在卸载动态库之前调用此方法，直接卸载动态库会导致错误。
        /// </summary>
        /// <returns></returns>
        [DllImport("MTScaleAPI.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi)]
        public static extern bool Release();

        /// <summary>
        /// 托利多电子秤下传（带服务和不带服务 是厂家提供的dll 不同）
        /// </summary>
        /// <param name="listscales">秤列表</param>
        /// <param name="list">商品列表</param>
        /// <param name="scaleType">秤型号</param>
        private static void TuoLiDuoDownLoadS(List<base_scales_info> listscales, List<base_goods_info> list, string scaleType)
        {
            //使用服务的话这里要放开，并且有相应的服务程序
            if (!ProcessHelper.ExistsProcess("MTScaleKey"))
            {
                //Msg.ShowInformation("需要开启下传服务，如有权限提示请点击确定");
                ProcessHelper.StartExe(Application.StartupPath + "\\ScaleKey\\MTScaleKey.exe");
            }
            bool rest = CreatFileDownload(listscales, list, scaleType);
            if (rest)
            {
                Msg.ShowInformation("下传成功");
            }
            else
            {
                Msg.ShowInformation("下传失败，请查看日志确定具体问题");
            }
        }


        private static bool CreatFileDownload(List<base_scales_info> listscales, List<base_goods_info> list, string scaleType)
        {
            string parentPath = Application.StartupPath;
            Encoding en = Encoding.UTF8;
            string taskPath = parentPath + "\\Task.xml";//任务信息结构
            string scalesPath = parentPath + "\\ScaleList.xml";//秤信息列表
            string scaleDataPath = parentPath + "\\ScaleDataFile.xml";//命令字信息结构
            string scaleCommandDataPath = parentPath + "\\CommandDataFile.xml";//商品信息数据
            string outScalePath = parentPath + "\\outScaleFile.xml";//商品信息数据

            string taskNum = DateTime.Now.ToString("yyMMddHHmmssfff");
            //任务信息结构
            StringBuilder sbTask = new StringBuilder();
            //sbTask.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sbTask.Append("<MTTask>");
            sbTask.Append("<TaskType>0</TaskType>");
            sbTask.Append(string.Format("<TaskID>{0}</TaskID>", taskNum));
            sbTask.Append("<DataFile>ScaleList.xml</DataFile>");
            sbTask.Append("</MTTask>");

            using (FileStream fs = new FileStream(taskPath, FileMode.Create, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(fs, en))
                {
                    sw.Write(sbTask.ToString());
                    sw.Flush();
                }
            }

            //秤信息列表
            StringBuilder sbScales = new StringBuilder();
            //sbScales.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sbScales.Append("<Devices>");
            int scaleIndex = 1;
            foreach (var item in listscales)
            {
                sbScales.Append("<Scale>");
                sbScales.Append(string.Format("<DeviceID>{0}</DeviceID>", scaleIndex));//设备号唯一标志
                sbScales.Append(string.Format("<ScaleNo>{0}</ScaleNo>", scaleIndex));//称号（同上就行）
                sbScales.Append(string.Format("<ScaleType>{0}</ScaleType>", scaleType));//需要根据选择类型进行处理（bCom,bPro,bPlus）
                sbScales.Append("<ConnectType>Network</ConnectType>");//通讯类型
                sbScales.Append(string.Format("<ConnectParams><NetworkParams Type=\"Network\" Address=\"{0}\" Port=\"3001\" /></ConnectParams>", item.scales_ip));//填写成的IP地址
                sbScales.Append("<DecimalDigits>1</DecimalDigits>");//小数位，保留几位小数
                sbScales.Append("<DataFile>ScaleDataFile.xml</DataFile>");//命令文件的地址
                sbScales.Append("</Scale>");
                scaleIndex++;
            }
            sbScales.Append("</Devices>");

            using (FileStream fs = new FileStream(scalesPath, FileMode.Create, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(fs, en))
                {
                    sw.Write(sbScales.ToString());
                    sw.Flush();
                }
            }


            //命令字信息结构
            StringBuilder sbData = new StringBuilder();
            //sbData.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sbData.Append("<Commands>");
            sbData.Append("<Command>");
            sbData.Append(string.Format("<CommandID>C{0}</CommandID>", DateTime.Now.ToString("yyMMddHHmmssf")));
            sbData.Append("<CommandText>Item</CommandText>");
            sbData.Append("<Control>Update</Control>");
            sbData.Append("<ClearData>false</ClearData>");
            sbData.Append("<DataFile>CommandDataFile.xml</DataFile>");
            sbData.Append("</Command>");
            sbData.Append("</Commands>");

            using (FileStream fs = new FileStream(scaleDataPath, FileMode.Create, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(fs, en))
                {
                    sw.Write(sbData.ToString());
                    sw.Flush();
                }
            }

            StringBuilder sbCommand = new StringBuilder();
            //sbCommand.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sbCommand.Append("<Data>");
            foreach (var item in list)
            {
                sbCommand.Append("<Item>");
                sbCommand.Append(string.Format("<PLU>{0}</PLU>", item.scale_num));//PLU号
                sbCommand.Append("<DepartmentID>0</DepartmentID>");//部门号
                sbCommand.Append(string.Format("<AlternativeItemIDs><AlternativeItemID>{0}</AlternativeItemID></AlternativeItemIDs>", item.goods_code));//商品条码
                sbCommand.Append(string.Format("<Descriptions><Description ID=\"0\" Language=\"zho\" Type=\"ItemName\" Index=\"0\">{0}</Description></Descriptions>", item.goods_name));//商品名称.

                sbCommand.Append(string.Format("<ItemPrices><ItemPrice Index=\"0\" UnitOfMeasureCode=\"{0}\" PriceOverrideFlag=\"true\" DiscountFlag=\"true\" Quantity=\"0\" Currency=\"CNY\">{1}</ItemPrice></ItemPrices>", item.scale_type == "称重" ? "KGM" : "PCS", (item.goods_unit == "斤" ? Math.Round(item.goods_price * 2, 2, MidpointRounding.ToEven) : Math.Round(item.goods_price, 2, MidpointRounding.ToEven)) * (scaleType == "bCom" ? 10 : 1)));//称重方式KGM(元/千克)/PCS(计数)；价格(元)

                sbCommand.Append(string.Format("<Dates><Dateoffset Type=\"BestBefore\" UnitOfOffset=\"day\" PrintEnabled=\"True\" PrintFormat=\"Days\">{0}</Dateoffset><Dateoffset Type=\"SellBy\" UnitOfOffset=\"day\" PrintEnabled=\"True\" PrintFormat=\"Days\">{0}</Dateoffset><Dateoffset Type=\"PackedDate\" PrintEnabled=\"True\" PrintFormat=\"YYMMDD\">0</Dateoffset></Dates>", item.shelf_life));//保质期
                sbCommand.Append("<LabelFormats><LabelFormatID Index=\"0\">1</LabelFormatID></LabelFormats>");//标签号，请提示标签号填1
                sbCommand.Append(string.Format("<Barcodes><BarcodeID>{0}</BarcodeID></Barcodes>", "1"));//条码号
                sbCommand.Append("</Item>");
            }
            sbCommand.Append("</Data>");

            using (FileStream fs = new FileStream(scaleCommandDataPath, FileMode.Create, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(fs, en))
                {
                    sw.Write(sbCommand.ToString());
                    sw.Flush();
                }
            }

            bool rest = false;

            rest = ExecuteTaskInFile(taskNum, taskPath, outScalePath, true);
            return rest;

        }
        #endregion
    }
}
