using System;
using System.Collections.Generic;
using System.Text;

//using CommonMP.HYSSOP.Interface.HSData;
//using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;

using CommonMP.HYMCO.Interface;
//using CommonMP.HYMCO.Interface.Model;
//using CommonMP.HYMCO.Interface.Data;
//using CommonMP.HYMCO.CoreImpl.Model;
//using CommonMP.HYMCO.CoreImpl.Data;

namespace CommonMP.HYMCO.OptionImpl.CommonControlLibrary
{
    /// <summary><para>class outline:</para>
    /// <para>表形式パラメータ用XML作成・読込みクラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2010/12/10][新規作成]</para>
    /// <para>remarks</para>
    /// <para>構造定義ファイルの表形式パラメータXMLを作成・読込みするクラス</para>
    /// <example>
    /// <para>■使用方法（Xml作成時）：</para>
    /// <code>
    /// StructXmlTable csTable1 = new StructXmlTable(csXmlWriter, "m_csData", "雨量(mm/hr)", true, true, false);
    /// //スキーマ出力
    /// csTable1.AddSchema("Time", "時間", McDefine.ValKind.STRING, false);
    /// csTable1.AddSchema("Obs", "観測所", McDefine.ValKind.DOUBLE, true);  //繰り返し項目
    /// //データ出力(データ数分繰り返し)
    /// HySXmlNode csRowNode = csTable1.CreateRow();  //行追加
    /// csTable1.AddCol(csRowNode, "Time", "2010/12/10 00:00");  //列追加
    /// csTable1.AddCol(csRowNode, "Obs", "1", "10");            //列追加
    /// //Tableノードを追加
    /// csRtn.AppendChild(csTable1.m_csTableNode);
    /// </code>
    /// <para>■使用方法（Xml読込み時）：</para>
    /// <code>
    /// StructXmlTable csTable1 = new StructXmlTable(csPrptyXml, "m_csData");
    /// //データ読込み(データ数分繰り返し)
    /// for (long lRow = 0; lRow ＜ csTable1.m_lRowCnt; lRow++)
    /// {
    ///     Dictionary＜string, string＞ csColsList = csTable1.GetCols(lRow);
    ///     double[] dVal = new double[csColsList.Count - 1];
    ///     foreach (KeyValuePair＜string, string＞ csCol in csColsList)
    ///     {
    ///         if (csCol.Key.Equals("Time"))
    ///             sTime = Convert.ToDateTime(csCol.Value).ToString("yyyy/MM/dd HH:mm:ss");
    ///         else if (csCol.Key.StartsWith("Obs")){
    ///             long lNo = Convert.ToInt64(csCol.Key.Substring(3));
    ///             dVal[lNo - 1] = Convert.ToDouble(csCol.Value);
    ///         }
    ///     }
    ///     //変数に追加
    ///     m_csData.Add(sTime, dVal);
    /// }
    /// </code>
    /// </example>
    /// </remarks>
    public class StructXmlTable
    {
        /// <summary> HySXmlWriter </summary>
        private HySXmlWriter m_csXmlWriter = null;
        /// <summary> Tableノード </summary>
        public HySXmlNode m_csTableNode = null;
        /// <summary> Schemaノード </summary>
        public HySXmlNode m_csSchemaNode = null;

        /// <summary> Table/Rowノードリスト </summary>
        public HySXmlNodeList m_csRowNodeList = null;
        /// <summary> Table/Rowノードリスト件数 </summary>
        public long m_lRowCnt = 0;


        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ（作成用）</para>
        /// </summary>
        /// <param name="csXmlWriter">HySXmlWriter</param>
        /// <param name="sKey">変数名</param>
        /// <param name="sName">項目（ラベル）</param>
        /// <param name="bAddCols">列追加可能か [True/False]</param>
        /// <param name="bAddRows">行追加可能か [True/False]</param>
        /// <param name="bRowNumHeader">行No見出し表示するか [True/False]</param>
        public StructXmlTable(HySXmlWriter csXmlWriter, string sKey, string sName, bool bAddCols, bool bAddRows, bool bRowNumHeader)
        {
            m_csXmlWriter = csXmlWriter;

            m_csTableNode = HySXmlNode.CreateElement("Table", csXmlWriter);
            m_csTableNode.SetAttribute("Key", sKey);
            m_csTableNode.SetAttribute("Name", sName);
            m_csTableNode.SetAttribute("AddCols", (bAddCols ? "True" : "False"));
            m_csTableNode.SetAttribute("AddRows", (bAddRows ? "True" : "False"));
            if (bRowNumHeader)
                m_csTableNode.SetAttribute("RowNumHeader", "True");

            m_csSchemaNode = HySXmlNode.CreateElement("Schema", csXmlWriter);
            m_csTableNode.AppendChild(m_csSchemaNode);
        }

        #region 作成用

        /// <summary><para>method outline:</para>
        /// <para>Schema追加</para>
        /// </summary>
        /// <param name="sKey">変数名</param>
        /// <param name="sName">項目（ラベル）</param>
        /// <param name="DataType">型 [LONG/DOUBLE/STRING/BOOL]</param>
        /// <param name="IsOccurs">繰り返し項目か [True/False]</param>
        public void AddSchema(string sKey, string sName, McDefine.ValKind DataType, bool IsOccurs)
        {
            HySXmlNode csENode1 = HySXmlNode.CreateElement("Element", m_csXmlWriter);
            csENode1.SetAttribute("Key", sKey);
            csENode1.SetAttribute("Name", sName);
            csENode1.SetAttribute("DataType", DataType.ToString());

            if (IsOccurs)
                csENode1.SetAttribute("Occurs", "True");

            m_csSchemaNode.AppendChild(csENode1);
        }
        /// <summary><para>method outline:</para>
        /// <para>Rowノード作成</para>
        /// </summary>
        /// <returns></returns>
        public HySXmlNode CreateRow()
        {
            HySXmlNode csRowNode = HySXmlNode.CreateElement("Row", m_csXmlWriter);
            m_csTableNode.AppendChild(csRowNode);
            return csRowNode;
        }
        /// <summary><para>method outline:</para>
        /// <para>Colノード追加</para>
        /// </summary>
        /// <param name="csRowNode">Rowノード</param>
        /// <param name="sKey">変数名</param>
        /// <param name="sNo">同じ変数ごとの番号（※繰り返し項目の場合のみ）</param>
        /// <param name="sValue">値</param>
        public void AddCol(HySXmlNode csRowNode, string sKey, string sNo, string sValue)
        {
            HySXmlNode csColNode = HySXmlNode.CreateElement("Col", m_csXmlWriter);
            csColNode.SetAttribute("Key", sKey);
            if (!string.IsNullOrEmpty(sNo))
                csColNode.SetAttribute("No", sNo);
            csColNode.SetAttribute("Value", sValue);

            csRowNode.AppendChild(csColNode);
        }
        /// <summary><para>method outline:</para>
        /// <para>Colノード追加</para>
        /// </summary>
        /// <param name="csRowNode">>Rowノード</param>
        /// <param name="sKey">変数名</param>
        /// <param name="sValue">値</param>
        public void AddCol(HySXmlNode csRowNode, string sKey, string sValue)
        {
            AddCol(csRowNode, sKey, "", sValue);
        }

        #endregion


        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ（読込み用）</para>
        /// </summary>
        /// <param name="csPrptyXml">HySXmlNode</param>
        /// <param name="sKey">変数名</param>
        public StructXmlTable(HySXmlNode csPrptyXml, string sKey)
        {
            HySXmlNodeList csXmlList = csPrptyXml.GetChildNodeListByTagName("Table");
            long lCnt = csXmlList.GetCount();
            for (long lLoop = 0; lLoop < lCnt; lLoop++)
            {
                HySXmlNode csXml = csXmlList.GetNode(lLoop);
                if (csXml == null)
                    continue;

                string sKeyAttr = csXml.GetAttribute("Key");
                if (sKeyAttr == sKey)
                {
                    m_csTableNode = csXml;

                    m_csRowNodeList = csXml.GetChildNodeListByTagName("Row");
                    m_lRowCnt = m_csRowNodeList.GetCount();
                    break;
                }
            }
        }

        #region 読込み用

        /// <summary><para>method outline:</para>
        /// <para>Rowノード内のColデータ取得</para>
        /// </summary>
        /// <param name="lRow">インデックス</param>
        /// <returns>Colデータリスト[key=変数名+No, value=値]</returns>
        public Dictionary<string, string> GetCols(long lRow)
        {
            Dictionary<string, string> csColsList = new Dictionary<string, string>();

            if (m_csRowNodeList != null)
            {
                HySXmlNode csRowNode = m_csRowNodeList.GetNode(lRow);
                if (csRowNode != null)
                {
                    HySXmlNodeList csXmlCols = csRowNode.GetChildNodeListByTagName("Col");
                    long lColCnt = csXmlCols.GetCount();

                    for (long lCol = 0; lCol < lColCnt; lCol++)
                    {
                        HySXmlNode csXmlC = csXmlCols.GetNode(lCol);
                        string sKey = csXmlC.GetAttribute("Key");
                        string sNo = csXmlC.GetAttribute("No");
                        string sVal = csXmlC.GetAttribute("Value");

                        csColsList.Add(sKey + sNo, sVal);
                    }
                }
            }
            return csColsList;
        }

        #endregion
    }
}
