using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using GWSocketClient.xml.dataItem;
using GWSocketClient.xml.dataItem.data;

namespace GWSocketClient.xml
{
    class XmlLoader
    {
        private XmlDocument document;

        private VcarecityPD vcarecityPd = null;
        private string filePath = "";

        public VcarecityPD getVcarecityPD()
        {
            if (vcarecityPd == null)
            {
                if (filePath.Equals(""))
                {
                    MessageBox.Show("XML路径为空!!!");
                    return null;
                }
                loadXmlDocument(this.filePath);
            }
            return vcarecityPd;
        }


        public XmlLoader load(string xmlFilePath)
        {
            this.filePath = xmlFilePath;
            loadXmlDocument(xmlFilePath);
            return this;
        }

        public XmlLoader()
        {
            try
            {
//            string xmlFilePath = @"D:\TestProject\GW\config\dtu.xml";
                string xmlFilePath = Application.StartupPath + "/xml/dtu.xml";

                loadXmlDocument(xmlFilePath);
            }
            catch (Exception exception)
            {
                
            }
        }

        public XmlLoader(string xmlFilePath)
        {
            loadXmlDocument(xmlFilePath);
        }

        private void loadXmlDocument(string xmlFilePath)
        {
            vcarecityPd = new VcarecityPD();
            document = new XmlDocument();
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreComments = true;
            XmlReader reader = XmlReader.Create(xmlFilePath, settings);
            document.Load(reader);
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(document.NameTable);
            xmlNamespaceManager.AddNamespace("ns2", "http://www.example.org/GolfCountryClub");

            vcarecityPd = loadXml();

            reader.Close();
        }

        public VcarecityPD loadXml()
        {
            if (document.DocumentElement == null)
            {
                return null;
            }

            XmlNodeList allChildNodes = document.DocumentElement.ChildNodes;

            foreach (XmlElement node in allChildNodes)
            {
                switch (node.Name)
                {
                    case "ProtocolName":
                        vcarecityPd.ProtocolName = node.InnerText;
//                        Console.WriteLine(node.Name + ":" + node.InnerText);
                        break;
                    case "ProtocolNo":
                        vcarecityPd.ProtocolNo = Convert.ToInt32(node.InnerText);
//                        Console.WriteLine(node.Name + ":" + node.InnerText);
                        break;
                    case "ProtocolStartSymbol":
                        vcarecityPd.ProtocolStartSymbol = node.InnerText;
//                        Console.WriteLine(node.Name + ":" + node.InnerText);
                        break;
                    case "ProtocolStartSymbolLen":
                        vcarecityPd.ProtocolStartSymbolLen = Convert.ToInt32(node.InnerText);
//                        Console.WriteLine(node.Name + ":" + node.InnerText);
                        break;
                    case "ProtocolEndSymbol":
                        vcarecityPd.ProtocolEndSymbol = node.InnerText;
//                        Console.WriteLine(node.Name + ":" + node.InnerText);
                        break;
                    case "ProtocolEndSymbolLen":
                        vcarecityPd.ProtocolEndSymbolLen = Convert.ToInt32(node.InnerText);
//                        Console.WriteLine(node.Name + ":" + node.InnerText);
                        break;
                    case "dataItem":
//                        Console.WriteLine(node.Name + ":" + node.InnerText);
                        handleDataItem(node);
                        break;
                    default:
                        handleDItem(node);

                        break;
                }
            }

            return vcarecityPd;
        }

        private void handleDItem(XmlElement node)
        {
            switch (node.Name)
            {
                case "FAddress":
                    vcarecityPd.FAddress = getDItem(node);
                    break;
                case "TAddress":
                    vcarecityPd.TAddress = getDItem(node);
                    break;
                case "Function":
                    vcarecityPd.Function = getDItem(node);
                    break;
                case "DataLen":
                    vcarecityPd.DataLen = getDItem(node);
                    break;
                case "Sn":
                    vcarecityPd.Sn = getDItem(node);
                    break;
                /*case "reverse":
                    vcarecityPd.reverse = getDItem(node);
                    break;*/
                case "DataSeq":
                    vcarecityPd.DataSeq = getDItem(node);
                    break;
                case "DataCheck":
                    vcarecityPd.DataCheck = getDItem(node);
                    break;
                default:
                    break;
            }
        }

        private List<AFN> dataItems = new List<AFN>();

        private void handleDataItem(XmlElement node)
        {
            AFN myAfn = new AFN();

            #region 处理属性问题

            myAfn.afn = Convert.ToInt32(node.Attributes["afn"].Value);
            myAfn.respAfnId = Convert.ToInt32(node.Attributes["respAfnId"].Value);

            if (node.HasAttribute("cmdId"))
            {
                myAfn.cmdId = Convert.ToInt32(node.Attributes["cmdId"].Value);
            }
            if (node.HasAttribute("type"))
            {
                myAfn.type = Convert.ToInt32(node.Attributes["type"].Value);
            }

            if (node.HasAttribute("check"))
            {
                myAfn.check = Convert.ToInt32(node.Attributes["check"].Value);
            }

            if (node.HasAttribute("isPT"))
            {
                myAfn.isPT = Convert.ToInt32(node.Attributes["isPT"].Value);
            }

            if (node.HasAttribute("dir"))
            {
                myAfn.dir = Convert.ToInt32(node.Attributes["dir"].Value);
            }

            if (node.HasAttribute("ack"))
            {
                myAfn.ack = Convert.ToInt32(node.Attributes["ack"].Value);
            }
            if (node.HasAttribute("status"))
            {
                myAfn.status = Convert.ToInt32(node.Attributes["status"].Value);
            }
            if (node.HasAttribute("mq"))
            {
                myAfn.mq = Convert.ToInt32(node.Attributes["mq"].Value);
            }

            #endregion


            #region MyRegion

            XmlNodeList data_DataElement = node.ChildNodes;


            foreach (XmlElement ddE in data_DataElement)
            {
                if (ddE.Name == "DataElement")
                {
                    DataElementType det = handleDataElement(ddE);
                    myAfn.DataElement.Add(det);
                }
                else if (ddE.Name == "data")
                {
                    DataType2 type2 = handleData(ddE);
                    myAfn.data.Add(type2);
                }
            }

            #endregion

            //添加到列表中去
            vcarecityPd.dataItem.Add(myAfn);
        }


        /*
         <data>
            <ElementSequence>1</ElementSequence>
            <ElementLen>6</ElementLen>
            <ElementName>sysDate</ElementName>
            <ElementValue>ElementValue</ElementValue>
            <ElementType>3</ElementType>
            <ElementPrecision>0</ElementPrecision>
        </data>
         */
        private DataType2 handleData(XmlElement ddE)
        {
            return handlerDataType2(ddE);
        }


        /*
        <DataElement>
            <flag>519</flag>
            <num>1</num>
            <data>
                <d1>
                    <ElementSequence>1</ElementSequence>
                    <ElementLen>2</ElementLen>
                    <ElementName>dataType</ElementName>
                    <ElementValue>ElementValue</ElementValue>
                    <ElementType>5</ElementType>
                    <ElementPrecision>0</ElementPrecision>
                </d1>
            </data>
        </DataElement>  
       */
        private DataElementType handleDataElement(XmlElement ddE)
        {
            DataElementType det = new DataElementType();

            XmlNodeList de = ddE.ChildNodes;

            foreach (XmlElement data in de)
            {
                switch (data.Name)
                {
                    case "flag":
                        det.flag = Convert.ToInt32(data.InnerText);

                        break;
                    case "num":
                        det.num = Convert.ToInt32(data.InnerText);

                        break;
                    case "data":
                        XmlNodeList d1List = data.ChildNodes; //得到所有<data/>,现在来说,只有一个

                        DataType d1s = new DataType();

                        foreach (XmlElement d1Item in d1List)
                        {
                            //处理第一个<d1></d1>中的数据,这里得到一个<d1>对象
                            DataType2 dataType2 = handlerDataType2(d1Item);
                            d1s.d1.Add(dataType2);
                        }
                        det.data.Add(d1s);
                        break;
                }
            }

            return det;
        }


        public DItem getDItem(XmlElement node)
        {
            DItem ditme = new DItem();
            if (node.HasAttribute("Len"))
            {
                ditme.Len = Convert.ToInt32(node.Attributes["Len"].Value);
            }

            if (node.HasAttribute("Name"))
            {
                ditme.Name = node.Attributes["Name"].Value;
            }

            if (node.HasAttribute("Seq"))
            {
                ditme.Seq = Convert.ToInt32(node.Attributes["Seq"].Value);
            }

            if (node.HasAttribute("type"))
            {
                ditme.type = Convert.ToInt32(node.Attributes["type"].Value);
            }

            if (node.HasAttribute("val"))
            {
                ditme.val = Convert.ToInt32(node.Attributes["val"].Value);
            }

            return ditme;
        }


        public DataType2 handlerDataType2(XmlElement d1Item)
        {
            XmlNodeList d1Element = d1Item.ChildNodes;
            DataType2 dataType2 = new DataType2();
            foreach (XmlElement jsonValue in d1Element)
            {
                switch (jsonValue.Name)
                {
                    case "ElementSequence":
                        dataType2.ElementSequence = Convert.ToInt32(jsonValue.InnerText);
                        break;
                    case "ElementLen":
                        dataType2.ElementLen = Convert.ToInt32(jsonValue.InnerText);
                        break;
                    case "ElementName":
                        dataType2.ElementName = jsonValue.InnerText;
                        break;
                    case "ElementValue":
                        dataType2.ElementValue = jsonValue.InnerText;
                        break;
                    case "ElementType":
                        dataType2.ElementType = Convert.ToInt32(jsonValue.InnerText);
                        break;
                    case "ElementFactor":
                        dataType2.ElementFactor = jsonValue.InnerText;
                        break;
                    case "ElementPrecision":
                        dataType2.ElementPrecision = Convert.ToInt32(jsonValue.InnerText);
                        break;
                }
            }
            return dataType2;
        }
    }
}