// <summary>ソースコード：ＨＹＭＣＯインポートされたＤＬＬ演算モデルＩ／Ｆ</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;

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.Interface.Controller;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Model;
using CommonMP.HYMCO.CoreOptionl.HymcoModelDLLWrapper;

namespace CommonMP.HYMCO.OptionImpl.Hymco64FortranWrapp
{
    /// <summary><para>class outline:</para>
    /// <para>FORTRAN ＤＬＬ制御クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.3.0][2011/04/01][新規作成]</para>
    /// </remarks>
    public class Mc64BitFortranModelDLLImport : McModel64BitDLLImportImpl
    {
        /// <summary>フォートランモデルDLL格納先パス　キー名称</summary>
        static public readonly String ENVINF_KEY_FORTRAN_MODEL_DLL_FOLDER = "FORTRAN_MODEL_DLL_FOLDER";

        /// <summary>DLL名称</summary>
        HySString m_csDLLName = null;

        /// <summary>シミュレーション開始時刻</summary>
        protected HySTime m_csStartTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>ワーク </summary>
        HySTime m_csWantTime = new HySTime(0);

        /// <summary>プロパティ情報を保持しておく:チェックの時に必要 </summary>
        Mc64BitFortranModelPropertyInfo m_csPrpytInfo = null;


        /// <summary> 入力（受信）情報数 </summary>
        protected long m_lInputDataNum = 0;
        /// <summary>セル型入力伝送情報 </summary>
        protected McReceiveCellDataIF[] m_InputCellData = null;
        /// <summary>上記の各入力パターンＩＤ </summary>
        protected long[] m_sInPtNo = null;

        /// <summary> 出力（送信）情報数 </summary>
        protected long m_lOutputDataNum = 0;
        /// <summary>セル型出力伝送情報 </summary>
        protected McSendCellDataIF[] m_OutputCellData = null;

        ///<summary> 出力（送信）パターンの数 </summary>
        protected long m_lSendDataPatternNo = 0;
        /// <summary>出力パターンに対応する出力接続線アイテム番号 </summary>
        protected List<long>[] m_lSndPatternMng;
        /// <summary>上記の各出力パターンＩＤ </summary>
        protected HySID[] m_csOutPtnID = null;
        /// <summary>上記の各出力パターンＩＤ番号（m_csOutPtnIDをlong変換したもの） </summary>
        protected long[] m_sOutPtNo = null;

        /// <summary>DLLハンドル </summary>
        protected IntPtr m_iModuleHandle = (IntPtr)0;


        // 以下、ＤＬＬ側とのやり取りを行うための変数
        // 制御変数
        /// <summary>δＴ</summary>
        protected IntPtr m_ipdDLLDeltaTime = (IntPtr)0;
        protected double[] m_dDLLDeltaTime = new double[1];

        /// <summary>目標時刻</summary>
        protected IntPtr m_ipdDLLTargetTime = (IntPtr)0;
        protected double[] m_dDLLTargetTime = new double[1];

        // モデルプロパティ情報等
        protected short m_sMaxParamDim = 0;
        /// <summary>long型変数の数 </summary>
        protected IntPtr m_ipsLongParaDimBuffer = (IntPtr)0;
        protected long[] m_sLongParaDim = new long[1];
        /// <summary>long型変数 </summary>
        protected IntPtr m_iplLongParaDataBuffer = (IntPtr)0;
        protected long[] m_iplLongParaData;
        /// <summary>double型変数 </summary>
        protected IntPtr m_iplDoubleParaDimBuffer = (IntPtr)0;
        protected long[] m_sDoubleParaDim = new long[1];
        /// <summary>double型変数 </summary>
        protected IntPtr m_iplDoubleParaDataBuffer = (IntPtr)0;
        protected double[] m_iplDoubleParaData;

        // モデル初期化情報
        /// <summary>long型変数の数 </summary>
        protected IntPtr m_ipsLongInitDimBuffer = (IntPtr)0;
        protected long[] m_sLongInitDim = new long[1];
        /// <summary>long型変数 </summary>
        protected IntPtr m_iplLongInitDataBuffer = (IntPtr)0;
        protected long[] m_iplLongInitData;
        /// <summary>double型変数 </summary>
        protected IntPtr m_iplDoubleInitDimBuffer = (IntPtr)0;
        protected long[] m_sDoubleInitDim = new long[1];
        /// <summary>double型変数 </summary>
        protected IntPtr m_iplDoubleInitDataBuffer = (IntPtr)0;
        protected double[] m_iplDoubleInitData;

        // モデルへの送信情報関連
        /// <summary>最大送信データ配列数 </summary>
        protected short m_sMaxPutDataDim = 0;


        protected IntPtr m_iplPutPatternNoBuffer = (IntPtr)0;
        protected long[] m_sPutPatternNo = new long[1];

        /// <summary>データ有効フラグ：＝１有効、それ以外　無効 </summary>
        protected IntPtr m_ipsPutValidFlgBuffer = (IntPtr)0;
        protected long[] m_sValidFlg = new long[1];

        /// <summary>セット時刻エリア </summary>
        protected IntPtr m_ipdPutDataTimeBuffer = (IntPtr)0;
        protected double[] m_dPutDataTime = new double[1];
        
        /// <summary>セットデータ数エリア </summary>
        protected IntPtr m_iplPutDataNumBuffer = (IntPtr)0;
        protected long[] m_sPutDataNumber = new long[1];

        /// <summary>セットデータエリア </summary>
        protected IntPtr m_ipdPutDataArrayBuffer = (IntPtr)0;
        protected double[] m_dPutDataArray = null;

        // モデルからの取得データ関連
        protected short m_sMaxGetDataDim = 0;
        /// <summary>取得パターン番号エリア </summary>
        protected IntPtr m_iplGetPatternNoBuffer = (IntPtr)0;
        protected long[] m_sGetPatternNo = new long[1];    

        /// <summary>取得データ数エリア </summary>
        protected IntPtr m_iplGetDataNumBuffer = (IntPtr)0;
        protected int[] m_sGetDataNumber = new int[1];
        //protected long[] m_sGetDataNumber = new long[1];

        /// <summary>取得データエリア </summary>
        protected IntPtr m_ipdGutDataArrayBuffer = (IntPtr)0;
        protected double[] m_dGetDataArray = null;

        /// <summary>取得時刻エリア </summary>
        protected IntPtr m_ipdGetTimeNumBuffer = (IntPtr)0;
        protected double[] m_dGetDataTime = new double[1];
        protected HySTime m_csDLLSndTime = new HySTime(0);
        

        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Mc32BitFortranModelDLLImport csObj = Mc32BitFortranModelDLLImport(sDLLName)</para>
        /// </example>
        /// <param name="sDLLName">ＤＬＬファイル名</param>
        /// <returns>Mc32BitFortranModelDLLImport 生成されたインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public Mc64BitFortranModelDLLImport()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>デストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>~Mc32BitFortranModelDLLImport( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        ~Mc64BitFortranModelDLLImport()
        {
            try
            {
                if (m_iModuleHandle != (IntPtr)0)
                {
                    HySNativeDLLImport.FreeLibrary(m_iModuleHandle);
                }

                this.HGlobalFree();
            }
            catch
            {
            }
        }

        // 初期設定
        /// <summary><para>method outline:</para>
        /// <para>ＤＬＬのインポート</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ImportDLL(sDLLName)</para>
        /// </example>
        /// <param name="sDLLName">ＤＬＬファイル名</param>
        /// <returns>bool =true:正常 false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool ImportDLL(string sDLLName)
        {
            bool bRtn = true;
            IntPtr iFuncHandle; // ハンドル
            m_csDLLName = new HySString(sDLLName);

            Assembly csEntryAssembly = Assembly.GetEntryAssembly();
            string sPathName = csEntryAssembly.Location;
            DirectoryInfo csInfo = Directory.GetParent(sPathName);
            string sPath = csInfo.ToString();
            HySString csDllFolder = HySEnvInf.GetEnvInf(ENVINF_KEY_FORTRAN_MODEL_DLL_FOLDER);
            if (((object)csDllFolder) == null) { csDllFolder = new HySString(@"\FortranModelDll\"); }
            string csDllName = sPath + csDllFolder.ToString() + sDLLName;           // ＤＬＬ名称

            m_iModuleHandle = HySNativeDLLImport.LoadLibrary(@csDllName);
            if (m_iModuleHandle == (IntPtr)0) { return bRtn; }

            // 必須の関数
            // ＤＬＬモデルパラメーター受信エリアの最大配列数を取得する
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.GET_MAX_PARADT_AREA);
            if (iFuncHandle != (IntPtr)0)
            {
                GetMaxParaDim = (_GET_MAX_PARADT_AREA)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_GET_MAX_PARADT_AREA));
            }
            else
            {
                bRtn = false;
            }
            // プロパティ情報設定処理
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.PROPERTY_SET);
            if (iFuncHandle != (IntPtr)0)
            {
                SetProperty = (_PRESET)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_PRESET));
            }
            else
            {
                bRtn = false;
            }
            // δＴ設定
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.SET_DELTA_TIME);
            if (iFuncHandle != (IntPtr)0)
            {
                SetDltTime = (_SET_DELTA_TIME)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_SET_DELTA_TIME));
            }
            else
            {
                bRtn = false;
            }

            // 初期化処理
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.INITIALIZE);
            if (iFuncHandle != (IntPtr)0)
            {
                Initialize = (_INITIALIZE)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_INITIALIZE));
            }
            else
            {
                bRtn = false;
            }
            // 収束判断
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.ISCONVERGEDE);
            if (iFuncHandle != (IntPtr)0)
            {
                IsConverged = (_ISCONVERGED)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_ISCONVERGED));
            }
            else
            {
                bRtn = false;
            }
            // ＤＬＬモデルへ設定するデータのエリアの最大配列数を取得する
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.GET_MAX_RCVDT_AREA);
            if (iFuncHandle != (IntPtr)0)
            {
                GetMaxReceiveDataDim = (_GET_MAX_INPUT_DIMENSION)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_GET_MAX_INPUT_DIMENSION));
            }
            else
            {
                bRtn = false;
            }
            // ＤＬＬモデルが欲しいデータの時刻を取得する
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.WANTTIME);
            if (iFuncHandle != (IntPtr)0)
            {
                WantDataTime = (_WANTTIME)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_WANTTIME));
            }
            else
            {
                bRtn = false;
            }
            // DLL側へのデータ設定
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.INPUTDATA);
            if (iFuncHandle != (IntPtr)0)
            {
                PutFMdlData = (_PUTDATA)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_PUTDATA));
            }
            else
            {
                bRtn = false;
            }
            // 計算（１ステップ）
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.CALCULATE);
            if (iFuncHandle != (IntPtr)0)
            {
                Calculate = (_CALCULATE)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_CALCULATE));
            }
            else
            {
                bRtn = false;
            }
            // ＤＬＬモデルから取得するデータのエリアの最大配列数を取得する
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.GET_MAX_SNDDT_AREA);
            if (iFuncHandle != (IntPtr)0)
            {
                GetMaxSendDataDim = (_GET_MAX_OUTPUT_DIMENSION)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_GET_MAX_OUTPUT_DIMENSION));
            }
            else
            {
                bRtn = false;
            }
            // DLL側からのデータ取得
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.DATAFUSION);
            if (iFuncHandle != (IntPtr)0)
            {
                GetFMdlData = (_GETDATA)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_GETDATA));
            }
            else
            {
                bRtn = false;
            }
            // 時刻を進める
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.GAIN_SIMULATION_TIME);
            if (iFuncHandle != (IntPtr)0)
            {
                GainSimulationTime = (_GAIN_SIMULATION_TIME)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_GAIN_SIMULATION_TIME));
            }
            else
            {
                bRtn = false;
            }
            // 目標時刻を設定する 
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.SET_TARGET_TIME);
            if (iFuncHandle != (IntPtr)0)
            {
                SetTrgtTime = (_SET_TARGET_TIME)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_SET_TARGET_TIME));
            }
            else
            {
                bRtn = false;
            }

            // 必須ではない関数
            // 計算開始時に動作する処理
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.READY_CALUCLATION);
            if (iFuncHandle != (IntPtr)0)
            {
                ReadyCalculation = (_READY_CALUCLATION)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_READY_CALUCLATION));
            }
            // 計算終了時に動作する処理
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.COMPLETE_CALCULATION);
            if (iFuncHandle != (IntPtr)0)
            {
                CompleteCalculation = (_COMPLETE_CALCULATION)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_COMPLETE_CALCULATION));
            }
            // 計算中断時に動作する処理
            iFuncHandle = HySNativeDLLImport.GetProcAddress(m_iModuleHandle, Mc64BitFortranWrapperDef.SUSPEND_CALCULATION);
            if (iFuncHandle != (IntPtr)0)
            {
                SuspendCalculation = (_SUSPEND_CALCULATION)Marshal.GetDelegateForFunctionPointer(iFuncHandle, typeof(_SUSPEND_CALCULATION));
            }

            return bRtn;
        }

        /// <summary>
        /// DLL名取得
        /// </summary>
        /// <returns></returns>
        public HySString GetDLLName()
        { return m_csDLLName; }

        /// <summary>
        /// 各種メモリ領域を確保
        /// </summary>
        /// <returns></returns>
        public override bool Prepare()
        {
            bool bRtn = true;

            m_sMaxParamDim = this.GetMaxParaDim();
            m_sMaxPutDataDim = this.GetMaxReceiveDataDim();
            m_sMaxGetDataDim = this.GetMaxSendDataDim();


            this.HGlobalAlloc();
            return bRtn;
        }

        /// <summary>
        /// アンマネージ領域確保
        /// </summary>
        protected void HGlobalAlloc()
        {
            m_ipdDLLTargetTime = McModel64BitDLLImportImpl.HmAlloc(1, typeof(double));
            m_ipdDLLDeltaTime = McModel64BitDLLImportImpl.HmAlloc(1, typeof(double));

            m_ipsLongParaDimBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_iplLongParaDataBuffer = McModel64BitDLLImportImpl.HmAlloc(m_sMaxParamDim, typeof(long));
            m_iplLongParaData = new long[m_sMaxParamDim];
            m_iplDoubleParaDimBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_iplDoubleParaDataBuffer = McModel64BitDLLImportImpl.HmAlloc(m_sMaxParamDim, typeof(double));
            m_iplDoubleParaData = new double[m_sMaxParamDim];

            m_ipsLongInitDimBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_iplLongInitDataBuffer = McModel64BitDLLImportImpl.HmAlloc(m_sMaxParamDim, typeof(long));
            m_iplLongInitData = new long[m_sMaxParamDim];
            m_iplDoubleInitDimBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_iplDoubleInitDataBuffer = McModel64BitDLLImportImpl.HmAlloc(m_sMaxParamDim, typeof(double));
            m_iplDoubleInitData = new double[m_sMaxParamDim];


            m_iplPutPatternNoBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_ipsPutValidFlgBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_ipdPutDataTimeBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(double));
            m_iplPutDataNumBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_ipdPutDataArrayBuffer = McModel64BitDLLImportImpl.HmAlloc(m_sMaxPutDataDim, typeof(double));
            m_dPutDataArray = new double[m_sMaxPutDataDim];

            m_iplGetPatternNoBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_ipdGetTimeNumBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(double));
            m_iplGetDataNumBuffer = McModel64BitDLLImportImpl.HmAlloc(1, typeof(long));
            m_ipdGutDataArrayBuffer = McModel64BitDLLImportImpl.HmAlloc(m_sMaxGetDataDim, typeof(double));
            m_dGetDataArray = new double[m_sMaxGetDataDim];

        }

        /// <summary>
        /// アンマネージ領域の開放
        /// </summary>
        protected void HGlobalFree()
        {
            // McModel32BitDLLImportImpl.HmAlloc() で確保した領域は全て　破棄する
            if (m_ipdPutDataTimeBuffer != (IntPtr)0)
            {
                m_ipdPutDataTimeBuffer = McModel64BitDLLImportImpl.HmFree(m_ipdPutDataTimeBuffer);
            }
            if (m_iplPutDataNumBuffer != (IntPtr)0)
            {
                m_iplPutDataNumBuffer = McModel64BitDLLImportImpl.HmFree(m_iplPutDataNumBuffer);
            }
            if (m_ipdPutDataArrayBuffer != (IntPtr)0)
            {
                m_ipdPutDataArrayBuffer = McModel64BitDLLImportImpl.HmFree(m_ipdPutDataArrayBuffer);
            }
            //if (iplPutDataKindNumBuffer != (IntPtr)0)
            //{
            //    iplPutDataKindNumBuffer = McModel32BitDLLImportImpl.HmFree(iplPutDataKindNumBuffer);
            //}

            if (m_ipdGetTimeNumBuffer != (IntPtr)0)
            {
                m_ipdGetTimeNumBuffer = McModel64BitDLLImportImpl.HmFree(m_ipdGetTimeNumBuffer);
            }
            if (m_iplGetDataNumBuffer != (IntPtr)0)
            {
                m_iplGetDataNumBuffer = McModel64BitDLLImportImpl.HmFree(m_iplGetDataNumBuffer);
            }
            if (m_ipdGutDataArrayBuffer != (IntPtr)0)
            {
                m_ipdGutDataArrayBuffer = McModel32BitDLLImportImpl.HmFree(m_ipdGutDataArrayBuffer);
            }
            //if (iplGutDataKindNumBuffer != (IntPtr)0)
            //{
            //    iplGutDataKindNumBuffer = McModel32BitDLLImportImpl.HmFree(iplGutDataKindNumBuffer);
            //}

            if (m_ipdDLLTargetTime != (IntPtr)0)
            {
                m_ipdDLLTargetTime = McModel64BitDLLImportImpl.HmFree(m_ipdDLLTargetTime);
            }
            if (m_ipdDLLDeltaTime != (IntPtr)0)
            {
                m_ipdDLLDeltaTime = McModel64BitDLLImportImpl.HmFree(m_ipdDLLDeltaTime);
            }

            // Free不足が無いように　全面見直しの事
        }

        // -------------------
        // 計算中動作
        // -------------------

        /// <summary>
        /// 受信情報をＤＬＬモデル側へ設定する
        /// </summary>
        /// <param name="dWantTime"></param>
        public void PutReceivedData(double dWantTime)
        {
            m_csWantTime.SetTime(m_csStartTime.GetTime() + dWantTime);
            long lDtDim = 0; long lDim1 = 0; long lDim2 = 0; long lDim3 = 0; long lDataDimInCell = 0;

            for (long lLp = 0; lLp < m_lInputDataNum; lLp++)
            {   // 入力する伝送データ数分繰り返します。

                lDtDim = m_InputCellData[lLp].GetDimension(ref lDim1, ref lDim2, ref lDim3, ref lDataDimInCell);

                if (lDtDim == 1)
                {
                    PutD1RcvData(m_csWantTime, m_InputCellData[lLp], lDim1, lDataDimInCell);
                }
                else if (lDtDim == 2)
                {
                    PutD2RcvData(m_csWantTime, m_InputCellData[lLp], lDim1, lDim2, lDataDimInCell);
                }
                else if (lDtDim == 3)
                {
                    PutD3RcvData(m_csWantTime, m_InputCellData[lLp], lDim1, lDim2, lDim3, lDataDimInCell);
                }

                m_dPutDataTime[0] = dWantTime;
                m_sPutPatternNo[0] = m_sInPtNo[lLp];

                McModel64BitDLLImportImpl.HmPutData(m_sPutDataNumber, m_iplPutDataNumBuffer, 1);
                McModel64BitDLLImportImpl.HmPutData(m_dPutDataArray, m_ipdPutDataArrayBuffer, m_sPutDataNumber[0]);
                McModel64BitDLLImportImpl.HmPutData(m_dPutDataTime, m_ipdPutDataTimeBuffer, 1);
                McModel64BitDLLImportImpl.HmPutData(m_sValidFlg, m_ipsPutValidFlgBuffer, 1);
                McModel64BitDLLImportImpl.HmPutData(m_sPutPatternNo, m_iplPutPatternNoBuffer, 1);

                this.PutFMdlData(m_iplPutDataNumBuffer, m_ipdPutDataArrayBuffer, m_ipdPutDataTimeBuffer, m_ipsPutValidFlgBuffer, m_iplPutPatternNoBuffer);

            }
        }

        /// <summary>
        /// ＤＬＬから計算結果を取得し、送信情報を設定する
        /// </summary>
        public void GetSendData()
        {
            long lDtDim = 0; long lDim1 = 0; long lDim2 = 0; long lDim3 = 0; long lDataDimInCell = 0;
            for (long lSndPtn = 0; lSndPtn < m_lSendDataPatternNo; lSndPtn++)
            {   // 設定された送信パターン数繰り返す

                // 送信パターン番号設定
                m_sGetPatternNo[0] = m_sOutPtNo[lSndPtn];
                McModel64BitDLLImportImpl.HmPutData(m_sGetPatternNo, m_iplPutPatternNoBuffer, 1); // 取得したいパターン番号設定

                // ＤＬＬモデルから送信データ受信
                this.GetFMdlData(m_iplGetDataNumBuffer, m_ipdGutDataArrayBuffer, m_ipdGetTimeNumBuffer, m_iplPutPatternNoBuffer);

                McModel64BitDLLImportImpl.HmGetData(m_iplGetDataNumBuffer, m_sGetDataNumber, 1); // データ数
                McModel64BitDLLImportImpl.HmGetData(m_ipdGutDataArrayBuffer, m_dGetDataArray, m_sGetDataNumber[0]); // データ
                McModel64BitDLLImportImpl.HmGetData(m_ipdGetTimeNumBuffer, m_dGetDataTime, 1); // 時刻
                m_csDLLSndTime.SetTime(m_csStartTime.GetTime() + m_dGetDataTime[0]);

                // 送信データへ設定
                long[] lSndOutDataNo = m_lSndPatternMng[lSndPtn].ToArray();
                for (long lLp = 0; lLp < m_lSndPatternMng[lSndPtn].Count; lLp++)
                {   // 出力する伝送データ数分繰り返します。
                    long SndOutDataNo = lSndOutDataNo[lLp];

                    lDtDim = m_OutputCellData[SndOutDataNo].GetDimension(ref lDim1, ref lDim2, ref lDim3, ref lDataDimInCell);
                    if (lDtDim == 1)
                    {
                        this.GetD1OutData(lDim1, lDataDimInCell, ref m_OutputCellData[SndOutDataNo]);
                    }
                    else if (lDtDim == 2)
                    {
                        this.GetD2OutData(lDim1, lDim2, lDataDimInCell, ref m_OutputCellData[SndOutDataNo]);
                    }
                    else if (lDtDim == 3)
                    {
                        this.GetD3OutData(lDim1, lDim2, lDim3, lDataDimInCell, ref m_OutputCellData[SndOutDataNo]);
                    }
                }
            }
        }


        // 各種設定メソッド
        /// <summary><para>method outline:</para>
        /// <para>演算目標時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetTargetTime(dTgtTime)</para>
        /// </example>
        /// <param name="dTgtTime">目標時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public override void SetTargetTime(double dTgtTime)
        {
            m_dDLLTargetTime[0] = dTgtTime;
            McModel64BitDLLImportImpl.HmPutData(m_dDLLTargetTime, m_ipdDLLTargetTime, 1);
            this.SetTrgtTime(m_ipdDLLTargetTime);
        }
        /// <summary><para>method outline:</para>
        /// <para>演算刻み時間を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetDeltaTime(dDltTime)</para>
        /// </example>
        /// <param name="dDltTime">演算刻み時間</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetDeltaTime(double dDltTime)
        {
            m_dDLLDeltaTime[0] = dDltTime;
            McModel64BitDLLImportImpl.HmPutData(m_dDLLDeltaTime, m_ipdDLLDeltaTime, 1);
            this.SetDltTime(m_ipdDLLDeltaTime);
        }

               
        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetPropertyInf(csCellMdlPropertyInfo)</para>
        /// </example>
        /// <param name="csCellMdlPropertyInfo">セル型プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SetPropertyInf(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            bool bRtn = false;
            m_csPrpytInfo = csCellMdlPropertyInfo as Mc64BitFortranModelPropertyInfo;
            if (m_csPrpytInfo != null)
            {
                double dDltT = m_csPrpytInfo.GetStepTime();
                this.SetDeltaTime(dDltT);

                // csPrptyInfから情報を取得する
                long lPara = 0; double dPara = 0.0;
                string csLabel= "";
                long lDtNum = m_csPrpytInfo.GetLongParaNum();
                m_sLongParaDim[0] = (short)lDtNum;
                for (long lLp = 0; lLp < lDtNum; lLp++)
                {
                    bRtn = m_csPrpytInfo.GetLongPara(lLp, ref lPara, ref csLabel);
                    m_iplLongParaData[lLp] = lPara;
                }

                lDtNum = m_csPrpytInfo.GetDoubleParaNum();
                m_sDoubleParaDim[0] = lDtNum;
                for (long lLp = 0; lLp < lDtNum; lLp++)
                {
                    bRtn = m_csPrpytInfo.GetDoublePara(lLp, ref dPara, ref csLabel);
                    m_iplDoubleParaData[lLp] = dPara;
                }

                // Unmanagedエリアへデータ設定
                McModel64BitDLLImportImpl.HmPutData(m_sLongParaDim, m_ipsLongParaDimBuffer, 1);
                McModel64BitDLLImportImpl.HmPutData(m_iplLongParaData, m_iplLongParaDataBuffer, m_sLongParaDim[0]);
                McModel64BitDLLImportImpl.HmPutData(m_sDoubleParaDim, m_iplDoubleParaDimBuffer, 1);
                McModel64BitDLLImportImpl.HmPutData(m_iplDoubleParaData, m_iplDoubleParaDataBuffer, m_sDoubleParaDim[0]);

                if (this.SetProperty(m_ipsLongParaDimBuffer, m_iplLongParaDataBuffer, m_iplDoubleParaDimBuffer, m_iplDoubleParaDataBuffer) == 0)
                { bRtn = true; }
            }
            return bRtn;
        }

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

            McTranInfoIFCellType csCellTrnInfo = null;
            csInputDataList.SetCursorFirst();
            for (long lP = 0; lP < m_lInputDataNum; lP++)
            {   // 入力データ数分

                csInputData = csInputDataList.GetCursorData() as McTranInfo;
                csCellTrnInfo = csInputData as McTranInfoIFCellType;
                if (csCellTrnInfo != null)
                {   // セル型データならば
                    m_InputCellData[lP] = csCellTrnInfo.GetReceiveCellData();
                    csRcvPtnID = m_InputCellData[lP].GetReceivePatternID();
                    m_sInPtNo[lP] = Convert.ToInt16( csRcvPtnID.ToString() );
                }
                csInputDataList.MoveCursorNext();            
            }
        }
        /// <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>
        public virtual bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;
            for (long lLp = 0; lLp < lInputDataNum; lLp++)
            {   // 入力する伝送データ数分繰り返します。

                // To Do
                // 

            }

            // 同一の受信パターンが複数　そんざいする時にはエラーとする（Ｆｏｒｔｒａｎの場合の制限事項）
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>出力側の接続情報設定 </para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSendConnection(ref csOutputDataList)</para>
        /// </example>
        /// <param name="csOutputDataList">出力情報リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para></para>
        /// </remarks>
        public virtual void SetSendConnection(ref HySDataLinkedList csOutputDataList)
        {
            // 出力情報の配列化
            m_lOutputDataNum = csOutputDataList.GetCount();
            m_OutputCellData = new McSendCellDataIF[m_lOutputDataNum];
            m_lSndPatternMng = new List<long>[m_lOutputDataNum];
            m_csOutPtnID = new HySID[m_lOutputDataNum];
            m_sOutPtNo = new long[m_lOutputDataNum];
            HySID csSndPtnID = null;

            m_lSendDataPatternNo = 0;
            McTranInfo csTrnInfo = null;
            csOutputDataList.SetCursorFirst();
            for (long lP = 0; lP < m_lOutputDataNum; lP++)
            {   // 出力データ数分

                csTrnInfo = csOutputDataList.GetCursorData() as McTranInfo;
                McTranInfoIFCellType csCellInfo = csTrnInfo as McTranInfoIFCellType;
                if (csCellInfo != null)
                {
                    m_OutputCellData[lP] = csCellInfo.GetSendCellData();

                    //送信パターン対応表を作成する
                    csSndPtnID = m_OutputCellData[lP].GetSendPatternID();
                    long lHit = m_lSendDataPatternNo;
                    // ループ内検索
                    for (long llp = 0; llp < m_lSendDataPatternNo; llp++)
                    {
                        if (csSndPtnID.Equals(m_csOutPtnID[llp]) == true)
                        {
                            lHit = llp;
                            break;
                        }
                    }
                    if (lHit == m_lSendDataPatternNo)
                    {   // 新パターンならば
                        m_csOutPtnID[lHit] = csSndPtnID;
                        m_sOutPtNo[lHit] = Convert.ToInt16( csSndPtnID.ToString());
                        m_lSndPatternMng[lHit] = new List<long>();
                        m_lSndPatternMng[lHit].Add(lP);
                        m_lSendDataPatternNo += 1;
                    }
                    else
                    {   // 既に見つかっているパターンならば
                        m_lSndPatternMng[lHit].Add(lP);
                    }
                }
                else
                {
                    m_OutputCellData[lP] = null;
                }



                csOutputDataList.MoveCursorNext();
            }
        }
        /// <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>
        public virtual bool SendConnectionCheck(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)
        {
            bool bRtn = true;
            for (long lLp = 0; lLp < lOutputDataNum; lLp++)
            {   // 出力する伝送データ数分繰り返します。

   

            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetInitialInf(csInitialData)</para>
        /// </example>
        /// <param name="csTime">初期時刻</param>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SetInitialInf(HySTime csTime, ref McPropertyInfoRoot csInitialData)
        {
            bool bRtn = false;
            Mc64BitFortranModelInitialData csInitDt = csInitialData as Mc64BitFortranModelInitialData;
            if (csInitDt != null)
            {
                m_csStartTime.SetTime(csTime.GetTime());

                // 初期値として、ＤＬＬ側に　時刻０の情報を送る
                //this.PutReceivedData(0);

                // csInitialDataから初期化データを取得し、ﾊﾟﾗﾒｰﾀを設定する
                long lPara = 0; double dPara = 0.0;
                string csLabel = "";
                long lDtNum = csInitDt.GetLongParaNum();
                
                m_sLongInitDim[0] = (short)lDtNum;
                for (long lLp = 0; lLp < lDtNum; lLp++)
                {
                    bRtn = csInitDt.GetLongPara(lLp, ref lPara, ref csLabel);
                    m_iplLongInitData[lLp] = lPara;
                }
                lDtNum = csInitDt.GetDoubleParaNum();
                
                m_sDoubleInitDim[0] = lDtNum;
                for (long lLp = 0; lLp < lDtNum; lLp++)
                {
                    bRtn = csInitDt.GetDoublePara(lLp, ref dPara, ref csLabel);
                    m_iplDoubleInitData[lLp] = dPara;
                }

                // Unmanagedエリアへデータ設定
                McModel64BitDLLImportImpl.HmPutData(m_sLongInitDim, m_ipsLongInitDimBuffer, 1);
                McModel64BitDLLImportImpl.HmPutData(m_iplLongInitData, m_iplLongInitDataBuffer, m_sLongInitDim[0]);
                McModel64BitDLLImportImpl.HmPutData(m_sDoubleInitDim, m_iplDoubleInitDimBuffer, 1);
                McModel64BitDLLImportImpl.HmPutData(m_iplDoubleInitData, m_iplDoubleInitDataBuffer, m_sDoubleInitDim[0]);

                if (this.Initialize(m_ipsLongInitDimBuffer, m_iplLongInitDataBuffer, m_iplDoubleInitDimBuffer, m_iplDoubleInitDataBuffer) == 0)
                { bRtn = true; }
            }
            return bRtn;
        }

        /// <summary>
        /// １次元セル配列をFORTRAN型１次元配列に変換する。
        /// </summary>
        /// <param name="csTm"></param>
        /// <param name="csInputCellData"></param>
        /// <param name="lDim1"></param>
        /// <param name="lDataDimInCell"></param>
        protected virtual void PutD1RcvData(HySTime csTm, McReceiveCellDataIF csInputCellData, long lDim1, long lDataDimInCell)
        {
            csInputCellData.SetCurrentTime(csTm);
            HySCellData[] csCellArry = csInputCellData.GetInterpolatedCellD1();
            m_sPutDataNumber[0] = 0;
            //Fortran 側のサブルーチィンとの整合性を取る必要がある
            for (long lDimLp = 0; lDimLp < lDim1; lDimLp++)
            {
                for (long lCllLp = 0; lCllLp < lDataDimInCell; lCllLp++)
                {
                    if (m_sPutDataNumber[0] >= m_sMaxPutDataDim) { break; }
                    m_dPutDataArray[m_sPutDataNumber[0]] = csCellArry[lDimLp].m_dData[lCllLp];
                    m_sPutDataNumber[0] += 1;
                }
            }
            m_sValidFlg[0] = 1;
        }
        /// <summary>
        /// ２次元セル配列をFORTRAN型１次元配列に変換する。
        /// </summary>
        /// <param name="csTm"></param>
        /// <param name="csInputCellData"></param>
        /// <param name="lDim1"></param>
        /// <param name="lDim2"></param>
        /// <param name="lDataDimInCell"></param>
        protected virtual void PutD2RcvData(HySTime csTm, McReceiveCellDataIF csInputCellData, long lDim1, long lDim2, long lDataDimInCell)
        {
            csInputCellData.SetCurrentTime(csTm);
            HySCellData[,] csCellArry = csInputCellData.GetInterpolatedCellD2();

            m_sPutDataNumber[0] = 0;
            //Fortran 側のサブルーチィンとの整合性を取る必要がある
            for (long lDimLp2 = 0; lDimLp2 < lDim2; lDimLp2++)
            {
                for (long lDimLp1 = 0; lDimLp1 < lDim1; lDimLp1++)
                {
                    for (long lCllLp = 0; lCllLp < lDataDimInCell; lCllLp++)
                    {
                        if (m_sPutDataNumber[0] >= m_sMaxPutDataDim) { break; }
                        m_dPutDataArray[m_sPutDataNumber[0]] = csCellArry[lDimLp1,lDimLp2].m_dData[lCllLp];
                        m_sPutDataNumber[0] += 1;
                    }
                }
            }
            m_sValidFlg[0] = 1;
        }
        /// <summary>
        /// ３次元セル配列をFORTRAN型１次元配列に変換する。
        /// </summary>
        /// <param name="csTm"></param>
        /// <param name="csInputCellData"></param>
        /// <param name="lDim1"></param>
        /// <param name="lDim2"></param>
        /// <param name="lDim3"></param>
        /// <param name="lDataDimInCell"></param>
        protected virtual void PutD3RcvData(HySTime csTm, McReceiveCellDataIF csInputCellData, long lDim1, long lDim2, long lDim3, long lDataDimInCell)
        {
            csInputCellData.SetCurrentTime(csTm);
            HySCellData[,,] csCellArry = csInputCellData.GetInterpolatedCellD3();

            m_sPutDataNumber[0] = 0;
            //Fortran 側のサブルーチィンとの整合性を取る必要がある
            for (long lDimLp3 = 0; lDimLp3 < lDim3; lDimLp3++)
            {
                for (long lDimLp2 = 0; lDimLp2 < lDim1; lDimLp2++)
                {
                    for (long lDimLp1 = 0; lDimLp1 < lDim2; lDimLp1++)
                    {
                        for (long lCllLp = 0; lCllLp < lDataDimInCell; lCllLp++)
                        {
                            if (m_sPutDataNumber[0] >= m_sMaxPutDataDim) { break; }
                            m_dPutDataArray[m_sPutDataNumber[0]] = csCellArry[lDimLp1, lDimLp2, lDimLp3].m_dData[lCllLp];
                            m_sPutDataNumber[0] += 1;
                        }
                    }
                }
            }
            m_sValidFlg[0] = 1;
        }

        /// <summary>
        /// FORTRAN１次元配列を１次元セル配列に変換する
        /// </summary>
        /// <param name="lDim1"></param>
        /// <param name="lDataDimInCell"></param>
        /// <param name="csOutputCellData"></param>
        protected virtual void GetD1OutData(long lDim1, long lDataDimInCell, ref McSendCellDataIF csOutputCellData)
        {
            //Fortran 側のサブルーチィンとの整合性を取る必要がある
            csOutputCellData.SetCurrentTime(m_csDLLSndTime);
            HySCellData[] csCellArry = csOutputCellData.PrepareSendCellD1();
            long lDtCnt = 0;
            for (long lCllDm1 = 0; lCllDm1 < lDim1; lCllDm1++)
            {
                for (long lCellDt = 0; lCellDt < lDataDimInCell; lCellDt++)
                {
                    if (lDtCnt >= m_sMaxGetDataDim ) { break; }
                    csCellArry[lCllDm1].m_dData[lCellDt] = m_dGetDataArray[lDtCnt];
                    lDtCnt += 1;
                }
            }
        }
        /// <summary>
        /// FORTRAN１次元配列を２次元セル配列に変換する
        /// </summary>
        /// <param name="lDim1"></param>
        /// <param name="lDim2"></param>
        /// <param name="lDataDimInCell"></param>
        /// <param name="csOutputCellData"></param>
        protected virtual void GetD2OutData(long lDim1, long lDim2, long lDataDimInCell, ref McSendCellDataIF csOutputCellData)
        {
            //Fortran 側のサブルーチィンとの整合性を取る必要がある
            csOutputCellData.SetCurrentTime(m_csDLLSndTime);
            HySCellData[,] csCellArry = csOutputCellData.PrepareSendCellD2();
            long lDtCnt = 0;
            for (long lCllDm2 = 0; lCllDm2 < lDim2; lCllDm2++)
            {
                for (long lCllDm1 = 0; lCllDm1 < lDim1; lCllDm1++)
                {
                    for (long lCellDt = 0; lCellDt < lDataDimInCell; lCellDt++)
                    {
                        if (lDtCnt >= m_sMaxGetDataDim) { break; }
                        csCellArry[lCllDm1, lCllDm2].m_dData[lCellDt] = m_dGetDataArray[lDtCnt];
                        lDtCnt += 1;
                    }
                }
            }
        }
        /// <summary>
        /// FORTRAN１次元配列を２次元セル配列に変換する
        /// </summary>
        /// <param name="lDim1"></param>
        /// <param name="lDim2"></param>
        /// <param name="lDim3"></param>
        /// <param name="lDataDimInCell"></param>
        /// <param name="csOutputCellData"></param>
        protected virtual void GetD3OutData(long lDim1, long lDim2, long lDim3, long lDataDimInCell, ref McSendCellDataIF csOutputCellData)
        {
            //Fortran 側のサブルーチィンとの整合性を取る必要がある
            csOutputCellData.SetCurrentTime(m_csDLLSndTime);
            HySCellData[,,] csCellArry = csOutputCellData.PrepareSendCellD3();
            long lDtCnt = 0;
            for (long lCllDm3 = 0; lCllDm3 < lDim3; lCllDm3++)
            {
                for (long lCllDm2 = 0; lCllDm2 < lDim2; lCllDm2++)
                {
                    for (long lCllDm1 = 0; lCllDm1 < lDim1; lCllDm1++)
                    {
                        for (long lCellDt = 0; lCellDt < lDataDimInCell; lCellDt++)
                        {
                            if (lDtCnt >= m_sMaxGetDataDim) { break; }
                            csCellArry[lCllDm1, lCllDm2, lDim3].m_dData[lCellDt] = m_dGetDataArray[lDtCnt];
                            lDtCnt += 1;
                        }
                    }
                }
            }
        }
        //
        //
        //
    }
}
