using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml.Linq;
using TZONE.OTA.Common;

namespace TZONE.OTA
{
    public partial class frmTools : Form
    {
        public frmTools()
        {
            InitializeComponent();
        }

        List<PackageItem> list_package = new List<PackageItem>();

        private void btn_File_Click(object sender, EventArgs e)
        {
            OpenFileDialog _openfile = new OpenFileDialog();
            _openfile.DefaultExt = "bin";
            _openfile.Filter = "*.bin|*.bin|*.*|*.*";
            _openfile.FileName = "config.xml";
            if (_openfile.ShowDialog() == DialogResult.OK)
            {
                this.txt_File.Text = _openfile.FileName;
                this.rtxt_Log.Invoke((MethodInvoker)(() => { this.rtxt_Log.AppendText(string.Format("{0}\r\n", " -->  Open OTA File")); }));
            }
        }

        private void btn_Generate_Click(object sender, EventArgs e)
        {
            this.pb_Show.Invoke((MethodInvoker)(() =>
            {
                this.pb_Show.Value = 0;
            }));
            if (!string.IsNullOrEmpty(this.txt_File.Text))
            {
                string dirPath = string.Format("{0}\\{1}", Application.StartupPath, "VTD");
                if (!Directory.Exists(dirPath))
                {
                    Directory.CreateDirectory(dirPath);
                }
                GeneratePackage(this.txt_File.Text);
                GeneratePKXML(
                    this.txt_Type.Text==""?"AVL":this.txt_Type.Text,
                    this.txt_Version.Text==""?"1.0":this.txt_Version.Text,
                    string.Format("{0}\\{1}{2}.xml",dirPath,this.txt_Type.Text,this.chk_isBin.Checked?".bin":"")
                    );
            }
            this.pb_Show.Invoke((MethodInvoker)(() =>
            {
                this.pb_Show.Value = this.pb_Show.Maximum;
            }));
        }

        private void SetProgressBar(int pb)
        {
            int cv = this.pb_Show.Value + pb;
            int cm = this.pb_Show.Maximum;
            if (cv < cm)
            {
                this.pb_Show.Invoke((MethodInvoker)(() =>
                {
                    this.pb_Show.Value += pb;
                }));
            }
            else
            {
                this.pb_Show.Invoke((MethodInvoker)(() =>
                    { this.pb_Show.Value -= 80; }));
            }
        }

        private void picb_Clear_Click(object sender, EventArgs e)
        {
            this.rtxt_Log.Clear();
        }

        private void rtxt_Log_TextChanged(object sender, EventArgs e)
        {
            this.rtxt_Log.ScrollToCaret();
        }

        private void GeneratePackage(string filePath)
        {
            list_package = new List<PackageItem>();
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                byte[] _package_data = new byte[256];
                int isdata = 0, _PI = 1;
                do
                {
                    string _pd_s = CRC.ToHexString(Encoding.ASCII.GetBytes(string.Format("@{0}", _PI.ToString("000"))));
                    isdata = fs.Read(_package_data, 0, _package_data.Length);
                    string _data = CRC.ToHexString(_package_data);
                    string _pd_e = CRC.ToHexString(Encoding.ASCII.GetBytes(string.Format("{0}#", CRC.GetCRC(_data))));
                    StringBuilder sb = new StringBuilder();
                    sb.Append(_pd_s).Append(_data).Append(_pd_e);
                    list_package.Add(new PackageItem()
                    {
                        itemid = _PI.ToString("000"),
                        itemdata = sb.ToString()
                    });
                    this.rtxt_Log.Invoke((MethodInvoker)(() => { this.rtxt_Log.AppendText(string.Format("{0}{1} {2}\r\n", " --> ", _PI.ToString("000"), "Package Item")); }));
                    SetProgressBar(2);
                    _PI++;
                } while (isdata > 0);

            }
        }
        private void GeneratePKXML(string TYPE, string version, string xmlPath)
        {
            if (list_package.Count > 0)
            {
                try
                {
                    //XDocument myXDoc = new XDocument(
                    //   new XElement("Bin",
                    //       new XAttribute("type", TYPE),
                    //        new XAttribute("version", version),
                    //       new XAttribute("packagenumber", list_package.Count.ToString()),
                    //       new XElement("packageitem",
                    //           new XAttribute("item", "111111")
                    //           )));
                    //myXDoc.Save(xmlPath);

                    XDocument doc = new XDocument();
                    doc.Declaration = new XDeclaration("1.0", "utf-8", "Upgrade package");
                    doc.Add(new XElement("Bin"));
                    doc.Element("Bin").Add(
                        new XAttribute("type", TYPE),
                        new XAttribute("version", version),
                        new XAttribute("packagenumber", list_package.Count.ToString()),
                        new XElement("packageitem")
                        );
                    doc.Element("Bin").Element("packageitem").Add(
                        from q in list_package
                        select new XElement("item",
                        new XAttribute("itemid", q.itemid),
                        new XAttribute("itemdata", q.itemdata)
                        ));
                    doc.Save(xmlPath);
                    this.rtxt_Log.Invoke((MethodInvoker)(() => { this.rtxt_Log.AppendText(string.Format("{0}{1}\r\n", " --> ", "Finish!")); }));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    //MessageBox.Show(ex.ToString());
                }
            }
        }

        public class PackageItem
        {
            public string itemid { get; set; }
            public string itemdata { get; set; }
        }
    }
}
