// <summary>ソースコード：ＨＹＭＣＯ何も行わないクラス</summary>
// <author>CommonMP</author>

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

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

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Controller;
using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.Interface.Data;

using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Tool;


namespace CommonMP.HYMCO.CoreImpl.Model
{
    /// <summary><para>class outline:</para>
    /// <para>データマージモデルクラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>
    /// [CommonMP][ver 1.0.0][2008/10/01][新規作成]
    /// </para>
    /// </remarks>
    public class McDataMergeModel : McStateCalModelBase //McForecastModelBase //McStateCalModelBase
    {
        /// <summary> データマージモデル演算中データ（キャスト用） </summary>
        McDataMergeModelCalInfo m_csMargeInfo = null;   // 便利の為、キャスト用に定義しておく

        // 一時保管データ（計算の最中に使用し無い為、FileOutの必要なし）
        /// <summary>入力接続側の接続要素ID  （一時保管）：計算の最中には使用しない</summary>
        protected HySID[] m_csInElementID = null;
        /// <summary>入力接続側の内挿処理区分 （一時保管）：計算の最中には使用しない</summary>
        public HySDefine.InterpolateType[] m_eInterpolateType = null;


        //=========================
        // 演算実行前処理関連メソッド
        //=========================

        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csInputDataList, ref csErrorInf)</para>
        /// </example>
        /// <param name="csInputDataList">入力情報リスト</param>
        /// <param name="csErrorInf">エラー出力</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        public override bool ReceiveConnectionCheck(ref HySDataLinkedList csInputDataList, ref McStructErrorInfo csErrorInf)
        {
            bool bRtn = true;
            bool bChildChekOK = true;
            // 入力情報の配列化
            m_lInputDataNum = csInputDataList.GetCount();
            m_csInputData = new McTranInfo[m_lInputDataNum];
            m_InputCellData = new McReceiveCellDataIF[m_lInputDataNum];

            McSendCellDataIF csSndCellData = null;
            
            // 入力要素ＩＤを求めておく
            HySID[] csElmID = new HySID[m_lInputDataNum];
            csInputDataList.SetCursorFirst();
            for (long lP = 0; lP < m_lInputDataNum; lP++)
            {   // 入力データ数分
                // TranInfo 配列設定
                m_csInputData[lP] = csInputDataList.GetCursorData() as McTranInfo;
                if (m_csInputData[lP] == null)
                {
                    bRtn = false;
                    bChildChekOK = false;
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                         Properties.HymcoImplResources.STATEMENT_INPUTDATA_PROPE_NG_R + m_csInputData[lP].GetUpperElementID().ToString() + ")");
                   // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                   //      "Input data property setting is wrong . (Check Connection data property.) (Received from " + m_csInputData[lP].GetUpperElementID().ToString() + ")");
                }
                else
                {
                    csElmID[lP] = m_csInputData[lP].GetUpperElementID();
                }
                csInputDataList.MoveCursorNext();
            }

            // 詳細設定及びチェック
            McTranInfoIFCellType csCellTrnInfo = null;
            for (long lP = 0; lP < m_lInputDataNum; lP++)
            {   // 入力データ数分

                csCellTrnInfo = m_csInputData[lP] as McTranInfoIFCellType;
                if (csCellTrnInfo != null)
                {   // セル型データならば
                    m_InputCellData[lP] = csCellTrnInfo.GetReceiveCellData();
                    if (m_InputCellData[lP] == null)
                    {
                        bRtn = false;
                        bChildChekOK = false;
                       // ver1.5 エラートレース日本語対応
                        csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                                 Properties.HymcoImplResources.STATEMENT_WRONG_RECEIVEDATA + m_csInputData[lP].GetConnectionID().ToString() + ")");
                       // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                       //          "Wrong receive data setting.(Received:Connection ID =" + m_csInputData[lP].GetConnectionID().ToString() + ")");
                    }
                    else
                    {
                        csSndCellData = csCellTrnInfo.GetSendCellData();    // 送信情報を取得
                        if (csSndCellData != null)
                        {
                            McTranInfoPatternPropertyIF csTranPtn = csSndCellData.GetTranInfoPattern(); // 送信側で設定されたパターンを取得
                            if (csTranPtn != null)
                            {   // 送信パターン有り
                                HySDataCharacteristicInCell csCellChara = csTranPtn.GetCellDataCharacteristic();    // 送信側の設定データ内容を取得
                                if (csCellChara != null)
                                {   // 内容有り
                                    long lN = csCellChara.GetDataNumber(); // 送信側で設定されたセル内のデータ数を取得
                                    HySCellDataGetter csCellGetter = new HySCellDataGetter(lN); // デフォルトで生成されたゲッターが必要
                                    m_InputCellData[lP].SetCellDataGetter(csCellGetter);    // 送信側がセットしたパターンをそのまま取得できるゲッターを設定する
                                    for (long lElm = 0; lElm < m_lInputDataNum; lElm++)
                                    {
                                        if (lElm < this.m_eInterpolateType.Length && lElm < this.m_csInElementID.Length)
                                        {
                                            if (csElmID[lP].Equals(this.m_csInElementID[lElm]) == true)
                                            {
                                                // 内挿処理を設定
                                                m_InputCellData[lP].SetInterpolateType(this.m_eInterpolateType[lElm]);
                                                break;
                                            }
                                       }
                                    }
                                }
                            }
                            else
                            {
                                bRtn = false;
                                bChildChekOK = false;
                               // ver1.5 エラートレース日本語対応
                                csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                                         Properties.HymcoImplResources.STATEMENT_INPUT_NO_SNDTYPE + m_csInputData[lP].GetUpperElementID().ToString() + ")");
                               // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                               //          "Input data is not set SndType.(Received from " + m_csInputData[lP].GetUpperElementID().ToString() + ")");

                            }
                        }
                        else
                        {
                            bRtn = false;
                            bChildChekOK = false;
                           // ver1.5 エラートレース日本語対応
                            csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                                     Properties.HymcoImplResources.STATEMENT_INPUT_NO_SENDCELL + m_csInputData[lP].GetUpperElementID().ToString() + ")");
                           // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                           //          "Input data has not SendCellData.(Received from " + m_csInputData[lP].GetUpperElementID().ToString() + ")");

                        }
                        // マージモデルは、通常のモデルと異なり、エラーとしない。
                        //if (m_InputCellData[lP].GetReceiveTranInfoPattern() == null)
                        //{
                        //    // 受信伝送情報パターン未設定の場合
                        //    csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.ELEMENT_CALC,
                        //                    "ReceiveData Property is not set.");
                        //    bChildChekOK = false;
                        //    bRtn = false;
                        //}
                    }
                }
                else
                {
                    bRtn = false;
                    bChildChekOK = false;
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                             Properties.HymcoImplResources.STATEMENT_INPUTDATA_NO_CELLTYPE + m_csInputData[lP].GetUpperElementID().ToString() + ")");
                   // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                   //          "Input data is not CellType.(Received from " + m_csInputData[lP].GetUpperElementID().ToString() + ")");
                }
            }
            if (bChildChekOK == true && m_bSetPropertyFlg == true)
            {
                // プロパティ情報未設定の場合は、子クラスのチェックは行わない
                if (this.ReceiveConnectionCheck(ref csErrorInf, m_lInputDataNum, m_InputCellData) != true)
                { bRtn = false; }
            }

            return bRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;

            m_csMargeInfo.m_lInputNum = lInputDataNum; // 入力数
            //m_csMargeInfo.m_lInCnctnIdxNum = new long[lInputDataNum];  // 入力接続数
            HySID[] csInElmID = new HySID[lInputDataNum];
            if (lInputDataNum <= 0)
            {
                bRtn = false;
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                         Properties.HymcoImplResources.STATEMENT_NO_RECEIVE_DATA );
               // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
               //          "No receive data.");
            }
            else
            {
                long lD1 = 0; long lD2 = 0; long lD3 = 0; long lDataDimInCell = 0;
                long lDm = 0;
                for (long lLp = 0; lLp < lInputDataNum; lLp++)
                {   // 入力する伝送データ数分繰り返します。
                    lDm = csInputCellData[lLp].GetDimension(ref lD1, ref lD2, ref lD3, ref lDataDimInCell);
                    if (lLp == 0)
                    {
                        m_csMargeInfo.m_lDataDim = lDm; // データの次元
                        m_csMargeInfo.m_lDim1Num = lD1; // ｘ軸？の配列数
                        m_csMargeInfo.m_lDim2Num = lD2; // ｙ軸？の配列数
                        m_csMargeInfo.m_lDim3Num = lD3; // ｚ軸？の配列数
                    }
                    else
                    {
                        if (m_csMargeInfo.m_lDataDim != lDm ||
                            m_csMargeInfo.m_lDim1Num != lD1 ||
                            m_csMargeInfo.m_lDim2Num != lD2 ||
                            m_csMargeInfo.m_lDim3Num != lD3)
                        {
                            bRtn = false;
                           // ver1.5 エラートレース日本語対応
                            csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                                     Properties.HymcoImplResources.STATEMENT_REC_DATA_DIM_MIS + m_csInputData[lLp].GetUpperElementID().ToString() + ")");
                           // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                           //          "Each receive data dimension mismatch.(Each receive data must have the same dimension.)" +
                           //          "  (Received from " + m_csInputData[lLp].GetUpperElementID().ToString() + ")");
                        }
                    }

                    csInElmID[lLp] = csInputCellData[lLp].GetUpperElementID();
                }
                
                // 接続端子順序が変化した場合、接続要素ＩＤに従って、入力インデックスを設定し直す
                McDataMergePropertyInfo.McMergeConnection csTmpCnct = new McDataMergePropertyInfo.McMergeConnection(m_csMargeInfo.m_csConnectionData);
                long lTmpCnctNum = csTmpCnct.GetIdxNum();  // 接続セルの変数の数
                HySID[] csTmpElmID = csTmpCnct.GetConnectElementID();
                long[] csTmpCnctIdx = csTmpCnct.GetConnectIdx();
                long[] csTmpCellIdx = csTmpCnct.GetIdx();
                bool[] bSetFlg = new bool[lTmpCnctNum];
                for (long lLp = 0; lLp < lTmpCnctNum; lLp++)
                {   // 接続セルの変数の数分繰り返す
                    bSetFlg[lLp] = false;
                    for (long lS = 0; lS < lInputDataNum; lS++)
                    {   // 入力されたコネクション分繰り返す
                        if (csTmpElmID[lLp].Equals(csInElmID[lS]) == true)
                        {   // 接続セルＩＤは、どのコネクションに対応するか？
                            m_csMargeInfo.m_csConnectionData.SetIdx(lLp, lS, csTmpElmID[lLp], csTmpCellIdx[lLp]);
                            bSetFlg[lLp] = true;
                            break;
                        }
                    }
                }
                for (long lLp = 0; lLp < lTmpCnctNum; lLp++)
                {   // 接続セルの変数の数分繰り返す
                    if (bSetFlg[lLp] == false)
                    {
                       // ver1.5 エラートレース日本語対応
                        csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                                 Properties.HymcoImplResources.STATEMENT_WRONG_CONNECT_SET );
                       // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                       //          "Wrong connection setting. (Check model property.)");
                        bRtn = false;
                    }
                }


                // 入力データに対する接続数リセット
                m_csMargeInfo.m_lInCnctnIdxNum = new long[lInputDataNum];
                for (long lLp = 0; lLp < lInputDataNum; lLp++)
                {
                    m_csMargeInfo.m_lInCnctnIdxNum[lLp] = 0;
                }

                // マージデータのセルの数を取得
                long lCnctDtNum = m_csMargeInfo.m_csConnectionData.GetIdxNum();
                m_csMargeInfo.m_lReadIndexInCell = new long[lInputDataNum, lCnctDtNum];
                m_csMargeInfo.m_lWriteIdxInCell = new long[lInputDataNum, lCnctDtNum];
                // 入力データインデックス値を取得
                long[] lCnnctIdx = m_csMargeInfo.m_csConnectionData.GetConnectIdx();
                long[] lCellValIdx = m_csMargeInfo.m_csConnectionData.GetIdx();
                for (long lLp = 0; lLp < lCnctDtNum; lLp++)
                {
                    if (lCnnctIdx[lLp] >= lInputDataNum || lCnnctIdx[lLp] < 0)
                    {
                       // ver1.5 エラートレース日本語対応
                        csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                                 Properties.HymcoImplResources.STATEMENT_WRONG_CONNECT_SET );
                       // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                       //          "Wrong connection setting. (Check model property.)");
                        bRtn = false;
                        continue;
                    }
                    else
                    {
                        m_csMargeInfo.m_lReadIndexInCell[lCnnctIdx[lLp], m_csMargeInfo.m_lInCnctnIdxNum[lCnnctIdx[lLp]]] = lCellValIdx[lLp];
                        for (long lWrtIdx = 0; lWrtIdx < lCnctDtNum; lWrtIdx++)
                        {
                            if (csTmpCnctIdx[lWrtIdx] == lCnnctIdx[lLp] &&
                                csTmpCellIdx[lWrtIdx] == lCellValIdx[lLp])
                            {
                                m_csMargeInfo.m_lWriteIdxInCell[lCnnctIdx[lLp], m_csMargeInfo.m_lInCnctnIdxNum[lCnnctIdx[lLp]]] = lWrtIdx;
                                break;
                            }
                        }

                        m_csMargeInfo.m_lInCnctnIdxNum[lCnnctIdx[lLp]] += 1;  // 入力データ接続数のインクリメント
                    }
                    //for (long lWrtIdx = 0; lWrtIdx < lCnctDtNum; lWrtIdx++)
                    //{
                    //    if( csTmpCnctIdx[lWrtIdx] == lCnnctIdx[lLp]  &&
                    //        csTmpCellIdx[lWrtIdx] ==  lCellValIdx[lLp]  )
                    //    {
                    //        m_csMargeInfo.m_lWriteIdxInCell[lLp]= lWrtIdx;
                    //        break;
                    //    }
                    //}
                }
                // ここで　m_csMargeInfo.m_lWriteIdxInCell[lCnnctIdx[lLp], m_csMargeInfo.m_lInCnctnIdxNum[lCnnctIdx[lLp]]]のチェックを行っておく
                for (long lLp = 0; lLp < lInputDataNum; lLp++)
                {
                    //m_csMargeInfo.m_lWriteIdxInCell = new long[lInputDataNum, lCnctDtNum];
                    for (long lLp2 = 0; lLp2 < lCnctDtNum; lLp2++)
                    {
                        if (m_csMargeInfo.m_lWriteIdxInCell[lLp, lLp2] >= lCnctDtNum)
                        {
                            bRtn = false;
                           // ver1.5 エラートレース日本語対応
                            csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                                     Properties.HymcoImplResources.STATEMENT_WRONG_CONNECT_SET );
                           // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                           //          "Wrong connection setting. (Check model property.)");
                            break;
                        }
                    }
                    if (bRtn == false)
                    {
                        break;
                    }
                }
            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>出力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SendConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lOutputDataNum">出力情報数</param>
        /// <param name="csOutputCellData">出力情報配列</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>送信端子に設定されている伝送データが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool SendConnectionCheck(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)
        {
            bool bRtn = true;
            if (lOutputDataNum == 0)
            {
                // 警告（エラーではない）
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckWarningData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE, 
                    Properties.HymcoImplResources.STATEMENT_NO_SEND_PORT　);
               // csErrorInf.AddCheckWarningData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE, "No send port.");
            }
            long lD1 = 0; long lD2 = 0; long lD3 = 0; long lDataDimInCell = 0;
            long lDm = 0;
            for (long lLp = 0; lLp < lOutputDataNum; lLp++)
            {   // 出力する伝送データ数分繰り返します。
                lDm = csOutputCellData[lLp].GetDimension(ref lD1, ref lD2, ref lD3, ref lDataDimInCell);
                if (m_csMargeInfo.m_lDataDim != lDm ||
                    m_csMargeInfo.m_lDim1Num != lD1 ||
                    m_csMargeInfo.m_lDim2Num != lD2 ||
                    m_csMargeInfo.m_lDim3Num != lD3)
                {
                    bRtn = false;
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                             Properties.HymcoImplResources.STATEMENT_SEND_DATA_DIM_MIS + csOutputCellData[lLp].GetLowerElementID().ToString() + ")");
                   // csErrorInf.AddCheckErrorData(this.GetID(), McModelLibraryDefine.HYM_MODEL_DATA_MERGE,
                   //          "Each send data dimension mismatch.(The dimension of receive and send data must be the same.)" +
                   //          "  (Send to " + csOutputCellData[lLp].GetLowerElementID().ToString() + ")");
                }
                //if (csOutputCellData[lLp].GetTranInfoPattern() == null) <-- このチェックは親クラスで行っている為不用
            }
            if (bRtn != false)
            {   // 異常なければ
                // マージ結果格納用　セル情報を準備する
                if (m_csMargeInfo.m_lDataDim == 1)
                {
                    m_csMargeInfo.m_csD1RcvCellData = new HySCellData[m_csMargeInfo.m_lDim1Num];
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        m_csMargeInfo.m_csD1RcvCellData[lP1] = new HySCellData(m_csMargeInfo.m_lValNumInCell);
                    }
                }
                else if (m_csMargeInfo.m_lDataDim == 2)
                {
                    m_csMargeInfo.m_csD2RcvCellData = new HySCellData[m_csMargeInfo.m_lDim1Num, m_csMargeInfo.m_lDim2Num];
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                        {
                            m_csMargeInfo.m_csD2RcvCellData[lP1, lP2] = new HySCellData(m_csMargeInfo.m_lValNumInCell);
                        }
                    }
                }
                else if (m_csMargeInfo.m_lDataDim == 3)
                {
                    m_csMargeInfo.m_csD3RcvCellData = new HySCellData[m_csMargeInfo.m_lDim1Num, m_csMargeInfo.m_lDim2Num, m_csMargeInfo.m_lDim3Num];
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                        {
                            for (long lP3 = 0; lP3 < m_csMargeInfo.m_lDim3Num; lP3++)
                            {
                                m_csMargeInfo.m_csD3RcvCellData[lP1, lP2, lP3] = new HySCellData(m_csMargeInfo.m_lValNumInCell);
                            }
                        }
                    }
                }

            } // end of if(正常）
            return bRtn;
        }


        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize(csInitialData)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override bool Initialize(ref McPropertyInfoRoot csInitialData, long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            // 引数で与えられたデータを　キャストしています。
            McDataMergeInitialInfo csInDt = csInitialData as McDataMergeInitialInfo;
            if (csInDt != null)
            {
                // Do Nothing
            }
            return true;
        }
        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>OnlineInitialize(csInitialData)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>bool</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override bool OnlineInitialize(ref McPropertyInfoRoot csInitialData, long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            // DoNothing
            return true;
        }

        //=======================
        // 演算実行処理関連メソッド
        //=======================

        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate(ref csInputCellData)</para>
        /// </example>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override long Calculate(long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            HySCellData[] csD1RcvCellData = null;
            HySCellData[,] csD2RcvCellData = null;
            HySCellData[, ,] csD3RcvCellData = null;
            long lCllValIdx = 0; // 読み出しセル内変数インデックス
            long lWriteDtIdxInCell = 0; // 書き出しセル内変数インデックス

            // ========================
            // 此処でデータのマージを行う
            //  マージした情報は、m_csMargeInfo内のメンバー変数に覚えておく
            // ========================
            for (long lLp = 0; lLp < m_lInputDataNum; lLp++)
            {   // 入力データ数繰り返す
                if (m_csMargeInfo.m_lInCnctnIdxNum[lLp] < 1) { continue; }
                if (m_csMargeInfo.m_lDataDim == 1)
                {
                    csD1RcvCellData = m_InputCellData[lLp].GetInterpolatedCellD1();
                    for (long lInDtIdx = 0; lInDtIdx < m_csMargeInfo.m_lInCnctnIdxNum[lLp]; lInDtIdx++)
                    {   // 設定数繰り返す

                        lCllValIdx = m_csMargeInfo.m_lReadIndexInCell[lLp, lInDtIdx];
                        lWriteDtIdxInCell = m_csMargeInfo.m_lWriteIdxInCell[lLp, lInDtIdx];
                        for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                        {
                            m_csMargeInfo.m_csD1RcvCellData[lP1].m_dData[lWriteDtIdxInCell] = csD1RcvCellData[lP1].m_dData[lCllValIdx];
                        }
                    }
                }
                else if (m_csMargeInfo.m_lDataDim == 2)
                {
                    csD2RcvCellData = m_InputCellData[lLp].GetInterpolatedCellD2();
                    for (long lInDtIdx = 0; lInDtIdx < m_csMargeInfo.m_lInCnctnIdxNum[lLp]; lInDtIdx++)
                    {   // 設定数繰り返す
                        lCllValIdx = m_csMargeInfo.m_lReadIndexInCell[lLp, lInDtIdx];
                        lWriteDtIdxInCell = m_csMargeInfo.m_lWriteIdxInCell[lLp, lInDtIdx];
                        for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                        {
                            for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                            {
                                m_csMargeInfo.m_csD2RcvCellData[lP1, lP2].m_dData[lWriteDtIdxInCell] = csD2RcvCellData[lP1, lP2].m_dData[lCllValIdx];
                            }
                        }
                    }
                }
                else if (m_csMargeInfo.m_lDataDim == 3)
                {
                    csD3RcvCellData = m_InputCellData[lLp].GetInterpolatedCellD3();
                    for (long lInDtIdx = 0; lInDtIdx < m_csMargeInfo.m_lInCnctnIdxNum[lLp]; lInDtIdx++)
                    {   // 設定数繰り返す
                        lCllValIdx = m_csMargeInfo.m_lReadIndexInCell[lLp, lInDtIdx];
                        lWriteDtIdxInCell = m_csMargeInfo.m_lWriteIdxInCell[lLp, lInDtIdx];
                        for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                        {
                            for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                            {
                                for (long lP3 = 0; lP3 < m_csMargeInfo.m_lDim3Num; lP3++)
                                {
                                    m_csMargeInfo.m_csD3RcvCellData[lP1, lP2, lP3].m_dData[lWriteDtIdxInCell]
                                        = csD3RcvCellData[lP1, lP2, lP3].m_dData[lCllValIdx];
                                }
                            }
                        }
                    }

                } // end of if(次元）
            }
            /*
            // ========================
            // 送信情報の設定
            // ========================
            HySCellData[] csSndCellData1 = null;
            HySCellData[,] csSndCellData2 = null;
            HySCellData[, ,] csSndCellData3 = null;

            if (m_csMargeInfo.m_lDataDim == 1)
            {
                for (long lLp = 0; lLp < m_lOutputDataNum; lLp++)
                {   // 出力する伝送データ数分繰り返します。
                    m_OutputCellData[lLp].SetCurrentTime(this.m_csSimTime);

                    csSndCellData1 = m_OutputCellData[lLp].PrepareSendCellD1();
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lValIdx = 0; lValIdx < m_csMargeInfo.m_lValNumInCell; lValIdx++)
                        {
                            csSndCellData1[lP1].m_dData[lValIdx] = m_csMargeInfo.m_csD1RcvCellData[lP1].m_dData[lValIdx];
                        }
                    }

                    m_OutputCellData[lLp].SendData();
                }   // end of for(伝送データ数)
            }
            else if (m_csMargeInfo.m_lDataDim == 2)
            {
                for (long lLp = 0; lLp < m_lOutputDataNum; lLp++)
                {   // 出力する伝送データ数分繰り返します。
                    m_OutputCellData[lLp].SetCurrentTime(this.m_csSimTime);

                    csSndCellData2 = m_OutputCellData[lLp].PrepareSendCellD2();
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                        {
                            for (long lValIdx = 0; lValIdx < m_csMargeInfo.m_lValNumInCell; lValIdx++)
                            {
                                csSndCellData2[lP1, lP2].m_dData[lValIdx] = m_csMargeInfo.m_csD2RcvCellData[lP1, lP2].m_dData[lValIdx];
                            }
                        }
                    }

                    m_OutputCellData[lLp].SendData();
                }   // end of for(伝送データ数)
            }
            else if (m_csMargeInfo.m_lDataDim == 3)
            {
                for (long lLp = 0; lLp < m_lOutputDataNum; lLp++)
                {   // 出力する伝送データ数分繰り返します。
                    m_OutputCellData[lLp].SetCurrentTime(this.m_csSimTime);

                    csSndCellData3 = m_OutputCellData[lLp].PrepareSendCellD3();
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                        {
                            for (long lP3 = 0; lP3 < m_csMargeInfo.m_lDim3Num; lP3++)
                            {
                                for (long lValIdx = 0; lValIdx < m_csMargeInfo.m_lValNumInCell; lValIdx++)
                                {
                                    csSndCellData3[lP1, lP2, lP3].m_dData[lValIdx] = m_csMargeInfo.m_csD3RcvCellData[lP1, lP2, lP3].m_dData[lValIdx];
                                }
                            }                     
                        }
                    }

                    m_OutputCellData[lLp].SendData();
                }   // end of for(伝送データ数)
            }
            */
            return 0;
        }

        /*    
        /// <summary><para>method outline:</para>
        /// <para>モデル演算結果を外部のエレメントに対して公開する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = DataFusion(ref csOutputDataList)</para>
        /// </example>
        /// <param name="csOutputDataList">演算結果を公開する出力情報リスト</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override long DataFusion(ref HySDataLinkedList csOutputDataList)
        {
            // Do Nothing
            return 0;
        }
        */
        /// <summary><para>method outline:</para>
        /// <para>モデル演算結果を外部のエレメントに対して公開する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = DataFusion( lOutputDataNum, ref csOutputCellData)</para>
        /// </example>
        /// <param name="lOutputDataNum">出力情報数</param>
        /// <param name="csOutputCellData">出力情報配列</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override long DataFusion(long lOutputDataNum, ref McSendCellDataIF[] csOutputCellData)
        {
            /* Do Nothing
            HySCellData[] csD1RcvCellData = null;
            HySCellData[,] csD2RcvCellData = null;
            HySCellData[, ,] csD3RcvCellData = null;
            long lCllValIdx = 0; // 読み出しセル内変数インデックス
            long lWriteDtIdxInCell = 0; // 書き出しセル内変数インデックス

            // ========================
            // 此処でデータのマージを行う
            //  マージした情報は、m_csMargeInfo内のメンバー変数に覚えておく
            // ========================
            for (long lLp = 0; lLp < m_lInputDataNum; lLp++)
            {   // 入力データ数繰り返す
                if (m_csMargeInfo.m_lInCnctnIdxNum[lLp] < 1) { continue; }
                if (m_csMargeInfo.m_lDataDim == 1)
                {
                    csD1RcvCellData = m_InputCellData[lLp].GetInterpolatedCellD1();
                    for (long lInDtIdx = 0; lInDtIdx < m_csMargeInfo.m_lInCnctnIdxNum[lLp]; lInDtIdx++)
                    {   // 設定数繰り返す

                        lCllValIdx = m_csMargeInfo.m_lReadIndexInCell[lLp, lInDtIdx];
                        lWriteDtIdxInCell = m_csMargeInfo.m_lWriteIdxInCell[lLp, lInDtIdx];
                        for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                        {
                            m_csMargeInfo.m_csD1RcvCellData[lP1].m_dData[lWriteDtIdxInCell] = csD1RcvCellData[lP1].m_dData[lCllValIdx];
                        }
                    }
                }
                else if (m_csMargeInfo.m_lDataDim == 2)
                {
                    csD2RcvCellData = m_InputCellData[lLp].GetInterpolatedCellD2();
                    for (long lInDtIdx = 0; lInDtIdx < m_csMargeInfo.m_lInCnctnIdxNum[lLp]; lInDtIdx++)
                    {   // 設定数繰り返す
                        lCllValIdx = m_csMargeInfo.m_lReadIndexInCell[lLp, lInDtIdx];
                        lWriteDtIdxInCell = m_csMargeInfo.m_lWriteIdxInCell[lLp, lInDtIdx];
                        for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                        {
                            for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                            {
                                m_csMargeInfo.m_csD2RcvCellData[lP1, lP2].m_dData[lWriteDtIdxInCell] = csD2RcvCellData[lP1, lP2].m_dData[lCllValIdx];
                            }
                        }
                    }
                }
                else if (m_csMargeInfo.m_lDataDim == 3)
                {
                    csD3RcvCellData = m_InputCellData[lLp].GetInterpolatedCellD3();
                    for (long lInDtIdx = 0; lInDtIdx < m_csMargeInfo.m_lInCnctnIdxNum[lLp]; lInDtIdx++)
                    {   // 設定数繰り返す
                        lCllValIdx = m_csMargeInfo.m_lReadIndexInCell[lLp, lInDtIdx];
                        lWriteDtIdxInCell = m_csMargeInfo.m_lWriteIdxInCell[lLp, lInDtIdx];
                        for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                        {
                            for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                            {
                                for (long lP3 = 0; lP3 < m_csMargeInfo.m_lDim3Num; lP3++)
                                {
                                    m_csMargeInfo.m_csD3RcvCellData[lP1, lP2, lP3].m_dData[lWriteDtIdxInCell]
                                        = csD3RcvCellData[lP1, lP2, lP3].m_dData[lCllValIdx];
                                }
                            }
                        }
                    }

                } // end of if(次元）
            }
            */
            // ========================
            // 送信情報の設定
            // ========================
            HySCellData[] csSndCellData1 = null;
            HySCellData[ , ] csSndCellData2 = null;
            HySCellData[, ,] csSndCellData3 = null;

            if (m_csMargeInfo.m_lDataDim == 1)
            {
                for (long lLp = 0; lLp < lOutputDataNum; lLp++)
                {   // 出力する伝送データ数分繰り返します。
                    csSndCellData1 = csOutputCellData[lLp].PrepareSendCellD1();
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lValIdx = 0; lValIdx < m_csMargeInfo.m_lValNumInCell; lValIdx++)
                        {
                            csSndCellData1[lP1].m_dData[lValIdx] = m_csMargeInfo.m_csD1RcvCellData[lP1].m_dData[lValIdx];
                        }
                    }
                }   // end of for(伝送データ数)
            }
            else if (m_csMargeInfo.m_lDataDim == 2)
            {
                for (long lLp = 0; lLp < lOutputDataNum; lLp++)
                {   // 出力する伝送データ数分繰り返します。
                    csSndCellData2 = csOutputCellData[lLp].PrepareSendCellD2();
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                        {
                            for (long lValIdx = 0; lValIdx < m_csMargeInfo.m_lValNumInCell; lValIdx++)
                            {
                                csSndCellData2[lP1, lP2].m_dData[lValIdx] = m_csMargeInfo.m_csD2RcvCellData[lP1, lP2].m_dData[lValIdx];
                            }
                        }
                    }
                }   // end of for(伝送データ数)
            }
            else if (m_csMargeInfo.m_lDataDim == 3)
            {
                for (long lLp = 0; lLp < lOutputDataNum; lLp++)
                {   // 出力する伝送データ数分繰り返します。
                    csSndCellData3 = csOutputCellData[lLp].PrepareSendCellD3();
                    for (long lP1 = 0; lP1 < m_csMargeInfo.m_lDim1Num; lP1++)
                    {
                        for (long lP2 = 0; lP2 < m_csMargeInfo.m_lDim2Num; lP2++)
                        {
                            for (long lP3 = 0; lP3 < m_csMargeInfo.m_lDim3Num; lP3++)
                            {
                                for (long lValIdx = 0; lValIdx < m_csMargeInfo.m_lValNumInCell; lValIdx++)
                                {
                                    csSndCellData3[lP1, lP2, lP3].m_dData[lValIdx] = m_csMargeInfo.m_csD3RcvCellData[lP1, lP2, lP3].m_dData[lValIdx];
                                }
                            }
                        }
                    }
                }   // end of for(伝送データ数)
            }
            
            return 0;
        }


        //====================
        // その他必要なメソッド
        //====================

        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetProperty(csCellMdlPropertyInfo)</para>
        /// </example>
        /// <param name="csCellMdlPropertyInfo">セル型プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SetProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            bool bRtn = true;
            // 使用しやすいようにキャストしておく
            m_csMargeInfo = (McDataMergeModelCalInfo)m_csCalInfo;

            // プロパティ設定
            McDataMergePropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McDataMergePropertyInfo;
            if (csPrptyInfo != null)
            {
                // 演算ステップ時刻設定
                this.m_csDltTime = new HySTime(csPrptyInfo.GetStepTime());

                // 接続情報
                McDataMergePropertyInfo.McMergeConnection csCellCnct = csPrptyInfo.GetMergeConnection();
                if (csCellCnct != null)
                {
                    m_csMargeInfo.m_csConnectionData = new McDataMergePropertyInfo.McMergeConnection(csCellCnct);
                    m_csMargeInfo.m_lValNumInCell = m_csMargeInfo.m_csConnectionData.GetIdxNum();
                }
                else
                {
                    bRtn = false;
                }

                this.m_eInterpolateType = csPrptyInfo.GetInputInterpolateType();
                this.m_csInElementID = csPrptyInfo.GetInputElementID();
            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>演算実行中断中のプロパティ等情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SetOnlineProperty(csCellMdlPropertyInfo)</para>
        /// </example>
        /// <param name="csCellMdlPropertyInfo">プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>演算中断中にプロパティ、初期値等を変更して動作させ場合等に使用する</para>
        /// </remarks>
        public override bool SetOnlineProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            // プロパティ設定
            McDataMergePropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McDataMergePropertyInfo;
            if (csPrptyInfo != null)
            {
                // 演算ステップ時刻設定
                this.m_csDltTime = new HySTime(csPrptyInfo.GetStepTime());
            }
            return true;
        }
        /// <summary><para>method outline:</para>
        /// <para>計算開始時に動作する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReadyCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>計算開始の　最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public override bool ReadyCalculation()
        {
            // Do Nothing
            return true;
        }
        /// <summary><para>method outline:</para>
        /// <para>計算中断時に動作する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SuspendCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>オペレーター操作等により計算中断時に　コールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public override bool SuspendCalculation()
        {
            // Do Nothing
            return true;
        }
        /// <summary><para>method outline:</para>
        /// <para>計算終了時に動作する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = CompleteCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>計算終了時　最後の最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public override bool CompleteCalculation()
        {
            // Do Nothing
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>演算用刻み時間を自動的に変更する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ChangeDeltaTimeAutomatically()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void ChangeDeltaTimeAutomatically()
        {
            // Do Nothing
        }
        //
    }
}
