using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

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

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Controller;
using CommonMP.HYMCO.CoreImpl.Data.TranInfo;

namespace CommonMP.HYMCO.CoreImpl.Data
{
    /// <summary><para>class outline:</para>
    /// <para>双方向通信データ</para>
    /// </summary>
    /// <remarks><para>remarks:</para>
    /// <para>
    /// 上流から下流、下流から上流へ流れるデータは全て同じ型である事
    /// 本クラスの派生クラスは全て[Serializable]であること
    /// </para>
    /// </remarks>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// <para> S.H. [2022/01/21][修正]</para>
    /// </remarks>
    [Serializable]
    public class McTimeSeriesMutualCellTranInfor : McTimeSeriesD1CellArrayTranInfo
    {
        /// <summary>上流要素→下流要素への伝送データ </summary>
        protected McTranInfo m_csDownStreamTranInfo = null;
        /// <summary>下流要素→上流要素への伝送データ </summary>
        protected McTranInfo m_csUpStreamTranInfo = null;

        /// <summary>プロパティ情報 </summary>
        protected McMutualTranInfoProperty m_csMutualTrnPrpty = null;

        protected HySObjectKind m_csTransDataKind = McTranInfoDefine.D1_CELL;

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McTranInfo csTrnData = new McTimeSeriesMutualCellTranInfor( csPropertyInfo ) </para>
        /// </example>
        /// <param name="csPropertyInfo">プロパティ情報</param>
        /// <returns>McTimeSeriesMutualCellTranInfor 生成されたクラスのインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McTimeSeriesMutualCellTranInfor(McPropertyInfoRoot csPropertyInfo)
            : base(csPropertyInfo)
        {
            m_csMutualTrnPrpty = csPropertyInfo as McMutualTranInfoProperty;
        }


        /// <summary><para>method outline:</para>
        /// <para>上流方向、下流方向への伝送データ設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetTranInfo(csDownTranInfo, csUpTranInfo) </para>
        /// </example>
        /// <param name="csDownstreamTranInfo">上流→下流伝送データ</param>
        /// <param name="csUpstreamTranInfo">下流→上流伝送データ</param>
        /// <returns> 無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void SetTranInfo(McTranInfo csDownstreamTranInfo, McTranInfo csUpstreamTranInfo)
        {
            m_csDownStreamTranInfo = csDownstreamTranInfo;
            m_csUpStreamTranInfo = csUpstreamTranInfo;
        }

        /// <summary><para>method outline:</para>
        /// <para>引数で与えたＩＤの要素が送信するデータを取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> (csDownstreamTranInfo , csUpstreamTranInfo) = GetTranInfo() </para>
        /// </example>
        /// <param name=""></param>
        /// <returns> (csDownstreamTranInfo , csUpstreamTranInfo)</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual (McTranInfo, McTranInfo) GetTranInfo()
        {
            return (m_csDownStreamTranInfo, m_csUpStreamTranInfo);
        }
        public virtual McTranInfo GetUpstream()
        {
            return m_csUpStreamTranInfo;
        }
        public virtual McTranInfo GetDownstream()
        {
            return m_csDownStreamTranInfo;
        }


        // ================================================
        // プロパティ設定関連
        // ================================================

        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetProperty(csPropertyInfo)</para>
        /// </example>
        /// <param name="csPropertyInfo">プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetProperty(McPropertyInfoRoot csPropertyInfo)
        {
            McMutualTranInfoProperty csPrpty = csPropertyInfo as McMutualTranInfoProperty;
            if( csPrpty == null) { return; }

            //McPropertyInfoRoot csDwnPropertyInf = csPrpty.GetDownstreamTranInfoProperty();
            McCellArrayTranInfoPropertyInfo csDwnPropertyInf = csPrpty.GetDownstreamTranInfoProperty();
            McCellArrayTranInfoPropertyInfo csUpPropertyInf  = csPrpty.GetUpstreamTranInfoProperty();
            //McCellArrayTranInfoPropertyInfo csCellPrpty      = csPrpty.GetDownstreamTranInfoProperty();
            if( m_csDownStreamTranInfo != null)
            {
                m_csDownStreamTranInfo.SetProperty(csDwnPropertyInf);
            }
            //csCellPrpty = csPrpty.GetUpstreamTranInfoProperty();
            if ( m_csUpStreamTranInfo != null)
            {
                m_csUpStreamTranInfo.SetProperty(csUpPropertyInf);
            }
            m_csCommonInfo.CreateSendCellData(csDwnPropertyInf);
        }

        public virtual HySID GetUpStreamPtternID()
        {
            return (((McTranInfoCommon)(m_csUpStreamTranInfo.GetCommonInf())).GetSendCellData()).GetID();
        }


        //★★★★★★★
        //★★★★★★★★★★★★★★★★★★★★★
        // Ver1.4で追加(伝送情報の事前作成、インスタンスの共有化)
        //★★★★★★★★★★★★★★★★★★★★★★★★★★★★
        /// <summary><para>method outline:</para>
        /// <para>上流側要素モデルタイムステップの設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetUpperElmTimeStep( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetUpperElmTimeStep()
        {
            //m_csCommonInfo
            if (m_csDownStreamTranInfo != null)
            {
                McTranCommonCellDataIF csCmmnInf = m_csDownStreamTranInfo.GetCommonInf();

                csCmmnInf.SetConnectionID(m_csCommonInfo.GetConnectionID() + new HySID("D"));
                csCmmnInf.SetConnectionName(m_csCommonInfo.GetConnectionName() + new HySString("D"));

                csCmmnInf.SetUpperElement(m_csCommonInfo.GetUpperElement());
                csCmmnInf.SetUpperPort( m_csCommonInfo.GetUpperPort());

                csCmmnInf.SetLowerElement(m_csCommonInfo.GetLowerElement());
                csCmmnInf.SetLowerPort(m_csCommonInfo.GetLowerPort());

                if (m_csDownStreamTranInfo is McTimeSeriesD1CellArrayTranInfo)
                {
                    ((McTimeSeriesD1CellArrayTranInfo)m_csDownStreamTranInfo).SetUpperElmTimeStep();
                }
                else if (m_csDownStreamTranInfo is McTimeSeriesD2CellArrayTranInfo)
                {
                    ((McTimeSeriesD2CellArrayTranInfo)m_csDownStreamTranInfo).SetUpperElmTimeStep();
                }
                else if (m_csDownStreamTranInfo is McTimeSeriesD3CellArrayTranInfo)
                {
                    ((McTimeSeriesD3CellArrayTranInfo)m_csDownStreamTranInfo).SetUpperElmTimeStep();
                }
            }
            if (m_csUpStreamTranInfo != null)
            {
                McTranCommonCellDataIF csCmmnInf = m_csUpStreamTranInfo.GetCommonInf();

                csCmmnInf.SetConnectionID(m_csCommonInfo.GetConnectionID() + new HySID("U"));
                csCmmnInf.SetConnectionName(m_csCommonInfo.GetConnectionName() + new HySString("U"));

                csCmmnInf.SetLowerElement(m_csCommonInfo.GetUpperElement());
                csCmmnInf.SetLowerPort(m_csCommonInfo.GetUpperPort());

                csCmmnInf.SetUpperElement(m_csCommonInfo.GetLowerElement());
                csCmmnInf.SetUpperPort(m_csCommonInfo.GetLowerPort());

                if (m_csUpStreamTranInfo is McTimeSeriesD1CellArrayTranInfo)
                {
                    ((McTimeSeriesD1CellArrayTranInfo)m_csUpStreamTranInfo).SetUpperElmTimeStep();
                }
                else if (m_csUpStreamTranInfo is McTimeSeriesD2CellArrayTranInfo)
                {
                    ((McTimeSeriesD2CellArrayTranInfo)m_csUpStreamTranInfo).SetUpperElmTimeStep();
                }
                else if (m_csUpStreamTranInfo is McTimeSeriesD3CellArrayTranInfo)
                {
                    ((McTimeSeriesD3CellArrayTranInfo)m_csUpStreamTranInfo).SetUpperElmTimeStep();
                }
            }

            //// Gr要素内で中継端子に接している場合、このタイミングで導通設定が行われておらず
            //// 取得できない為、明示的にNullとする
            //HySTime csTimeStep = null;
            //if (this.m_csCommonInfo.GetUpperElement() != null)
            //{
            //    csTimeStep = this.m_csCommonInfo.GetUpperElement().GetCalModel().GetDeltaTime();
            //}
            //bool bChkFlg = false;// 設定ファイルから取得
            //HySString csChkString = HySEnvInf.GetEnvInf("HYMCO_CELL_SERIAL_COMMON_USE");
            //if ((object)csChkString != null)
            //{
            //    bChkFlg = Convert.ToBoolean(csChkString.ToString());
            //}
            //if (bChkFlg == true)
            //{
            //    // Do Nothing
            //}
            //else
            //{
            //    McTranInfoDataPool.m_bCommonUseFlg = false;
            //}
            //// 此処でプールに自身の情報（伝送情報型、最大レコード数）を教える
            //McTranInfoDataPool.SetUpperElmTimeStep(m_sPrjID, m_csRecordKind, csTimeStep, base.m_lMaxDataNum, this.m_csCommonInfo);

        }

        /// <summary><para>method outline:</para>
        /// <para>プロジェクトIDの設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetPrjID( ) </para>
        /// </example>
        /// <param name="sPrjID">プロジェクトID</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetPrjID(string sPrjID)
        {
            m_sPrjID = sPrjID;
            if (m_csDownStreamTranInfo is McTimeSeriesD1CellArrayTranInfo)
            {
                ((McTimeSeriesD1CellArrayTranInfo)m_csDownStreamTranInfo).SetPrjID(sPrjID);
            }
            else if (m_csDownStreamTranInfo is McTimeSeriesD2CellArrayTranInfo)
            {
                ((McTimeSeriesD2CellArrayTranInfo)m_csDownStreamTranInfo).SetPrjID(sPrjID);
            }
            else if (m_csDownStreamTranInfo is McTimeSeriesD3CellArrayTranInfo)
            {
                ((McTimeSeriesD3CellArrayTranInfo)m_csDownStreamTranInfo).SetPrjID(sPrjID);
            }
            if (m_csUpStreamTranInfo is McTimeSeriesD1CellArrayTranInfo)
            {
                ((McTimeSeriesD1CellArrayTranInfo)m_csUpStreamTranInfo).SetPrjID(sPrjID);
            }
            else if (m_csUpStreamTranInfo is McTimeSeriesD2CellArrayTranInfo)
            {
                ((McTimeSeriesD2CellArrayTranInfo)m_csUpStreamTranInfo).SetPrjID(sPrjID);
            }
            else if (m_csUpStreamTranInfo is McTimeSeriesD3CellArrayTranInfo)
            {
                ((McTimeSeriesD3CellArrayTranInfo)m_csUpStreamTranInfo).SetPrjID(sPrjID);
            }
        }

        //-------------------------------------------
        /// <summary><para>method outline:</para>
        /// <para>内部蓄積データのクリア</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> ResetData() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        override public void ResetData()
        {
            m_csDownStreamTranInfo.ResetData();
            m_csUpStreamTranInfo.ResetData();
        }

        /// <summary><para>method outline:</para>
        /// <para>自分と同じクラスのインスタンスを生成する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McTranInfo csNewObj = Clone() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns> McTranInfo 生成されたクラスのインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McTranInfo Clone()
        {
            McTimeSeriesMutualCellTranInfor csRtnObj = new McTimeSeriesMutualCellTranInfor(m_csMutualTrnPrpty.Clone() );
            csRtnObj.SetTranInfo(m_csDownStreamTranInfo.Clone(), m_csUpStreamTranInfo.Clone());
            return csRtnObj;
        }

        /// <summary><para>method outline:</para>
        /// <para>引数で与えられた情報を自分にコピーを行う</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = CopyInfo(csOrgInfo) </para>
        /// </example>
        /// <param name="csOrgInfo">コピー元情報</param>
        /// <returns> bool true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool CopyInfo(McTranInfo csOrgInfo)
        {
            bool bRtn = false;
            McTimeSeriesMutualCellTranInfor csOrgRecord = csOrgInfo as McTimeSeriesMutualCellTranInfor;
            if (csOrgRecord != null)
            {
                if (m_csUpStreamTranInfo.SameKind(csOrgRecord.m_csUpStreamTranInfo) == true &&
                    m_csDownStreamTranInfo.SameKind(csOrgRecord.m_csDownStreamTranInfo) == true)
                {
                    bRtn = true;
                    if (m_csDownStreamTranInfo.CopyInfo(csOrgRecord.m_csDownStreamTranInfo) != true)
                    { bRtn = false; }
                    if (m_csUpStreamTranInfo.CopyInfo(csOrgRecord.m_csUpStreamTranInfo) != true)
                    { bRtn = false; }
                }
                m_csCommonInfo.CopyInfo(csOrgRecord.m_csCommonInfo);
            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>引数で与えられた情報から、最後に追加された情報を　自分の情報に追加する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = LastDataCopy(csOrgInfo) </para>
        /// </example>
        /// <param name="csOrgInfo">コピー元情報</param>
        /// <returns> bool true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>中継端子処理、別マシンへの伝送情報転送処理等に必要</para>
        /// </remarks>
        public override bool LastDataCopy(McTranInfo csOrgInfo)
        {
            bool bRtn = false;
            McTimeSeriesMutualCellTranInfor csOrgRecord = csOrgInfo as McTimeSeriesMutualCellTranInfor;
            if (csOrgRecord != null)
            {
                if (m_csUpStreamTranInfo.SameKind(csOrgRecord.m_csUpStreamTranInfo) == true &&
                    m_csDownStreamTranInfo.SameKind(csOrgRecord.m_csDownStreamTranInfo) == true)
                {
                    bRtn = true;
                    if (m_csDownStreamTranInfo.LastDataCopy(csOrgRecord.m_csDownStreamTranInfo) != true)
                    { bRtn = false; }
                    if (csOrgRecord.m_csUpStreamTranInfo.LastDataCopy(m_csUpStreamTranInfo) != true)
                    { bRtn = false; }
                }
            }
            return bRtn;
        }

    }
}
