// <summary>ソースコード：ＨＹＭＣＯ標準要素モデルクラス</summary>
// <author>CommonMP</author>

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

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

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


namespace CommonMP.HYMCO.CoreOptionl.HymcoStandardModel
{
    /// <summary><para>class outline:</para>
    /// <para>ＣＳＶファイル出力</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// <para>remarks:</para>
    /// <para>１次元配列情報をＣＳＶ形式のファイルに出力する：
    /// 　　　　出力する情報は　１変数のみ</para>
    /// </remarks>
    public class McCSVFileOutCtlMdl : McBasicFileOutCtl
    {
        /// <summary> 内部変数 </summary>
        protected McCSVFileOutInfo m_csOutFileInfo = null; //new McCSVFileOutInfo();
        /// <summary>処理中断中フラグ(=true:中断中)</summary>
        protected bool m_bSuspFlg = false;

        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csErrorInf, lInputDataNum, csInputCellData)</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;

            // 入力端子数のチェック
            if (lInputDataNum == 0)
            {
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND, 
                    Properties.HymcoStandardModelPrjResources.STATEMENT_NO_REC_PORT );
               // csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND, "No Receive Port");
                bRtn = false;
            }
            else if (lInputDataNum > 1)
            {
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND, 
                    Properties.HymcoStandardModelPrjResources.STATEMENT_MULTI_REC_PORT );
               // csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND, "Too many Receive Ports. (Not support multi-Receive Ports)");
                bRtn = false;
            }
            else if (lInputDataNum == 1)
            {
                long lD1 = 0;
                long lD2 = 0;
                long lD3 = 0;
                long lCellDataNum = 0;
                long lCellDim = 0;
                if (csInputCellData != null || csInputCellData.Length > 0)
                {
                    lCellDim = csInputCellData[0].GetDimension(ref lD1, ref lD2, ref lD3, ref lCellDataNum);
                }
                m_csOutFileInfo.m_lDimNum = lCellDim;
                m_csOutFileInfo.m_lDtDim1 = lD1;
                m_csOutFileInfo.m_lDtDim2 = lD2;
                m_csOutFileInfo.m_lDtDim3 = lD3;
                //if (lCellDataNum <= 0)
                //{
                //     bRtn = false;
                //     csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                //            , "Number of variables in the received cell is ZERO.  (Received from " + m_csInputData[0].GetUpperElementID().ToString() + ")");
                //}
                if (lCellDim == 1 && lD1 >= 1)
                {   // 1次元データならば
                    //m_lOutDataIdxは、０固定であるから、下記チェックは無意味
                    //if (m_csOutFileInfo.m_lOutDataIdx >= lCellDataNum)
                    //{
                    //    // 指定した出力情報のインデックスが伝送データ内のセルの情報数より大きければエラー
                    //    bRtn = false;
                    //    csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                    //        , "Output variable's index is larger than number of variables in the received cell. (Received from " + m_csInputData[0].GetUpperElementID().ToString() + ")");
                    //}
                }
                else if (lCellDim == 2 && lD1 >= 1 && lD2 >=1 )
                {   // ２次元データならば
                    //m_lOutDataIdxは、０固定であるから、下記チェックは無意味
                    //if (m_csOutFileInfo.m_lOutDataIdx >= lCellDataNum)
                    //{
                    //    // 指定した出力情報のインデックスが伝送データ内のセルの情報数より大きければエラー
                    //    bRtn = false;
                    //    csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                    //        , "Output variable's index is larger than number of variables in the received cell. (Received from " + m_csInputData[0].GetUpperElementID().ToString() + ")");
                    //}
                }
                else if (lCellDim == 3 && lD1 >= 1 && lD2 >= 1 && lD3 >=1 )
                {   //３次元データならば
                    //m_lOutDataIdxは、０固定であるから、下記チェックは無意味
                    //if (m_csOutFileInfo.m_lOutDataIdx >= lCellDataNum)
                    //{
                    //    // 指定した出力情報のインデックスが伝送データ内のセルの情報数より大きければエラー
                    //    bRtn = false;
                    //    csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                    //        , "Output variable's index is larger than number of variables in the received cell. (Received from " + m_csInputData[0].GetUpperElementID().ToString() + ")");
                    //}
                }
                else
                {
                    bRtn = false;
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                        , Properties.HymcoStandardModelPrjResources.STATEMENT_UNEXPECT_REC_DATA_TYPE + m_csInputData[0].GetUpperElementID().ToString() + ")");
                   // csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                   //     , "Unexpected receive data type. (Received from " + m_csInputData[0].GetUpperElementID().ToString() + ")");
                }
            }

            // 上書きファイル設定
            m_csOutFileNameWithFullPath = new HySString(this.GetDataHomeDirectory().ToString() + "\\" + this.GetProjectGroupName().ToString() + "\\" + m_csOutFileInfo.m_sOverWriteFileNameWithPath);

            //if (m_csOutFileInfo.m_lOverWriteSW == 1)
            //{   // 上書きの場合
            //    // 出力ファイル設定
            //    m_csOutFile = new HySFile(m_csOutFileNameWithFullPath.ToString());
            //    // 出力ファイル初期生成
            //    if (m_csOutFile.Open(HySFile.OPEN_MODE.CREATE_NEW, HySFile.READ_WRITE_MODE.WRITE, HySFile.DIRECTORY_MODE.MK_DIR) < 0)
            //    {
            //        bRtn = false;
            //        csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
            //            , "Cannot Create CSV File.");
            //    }
            //    m_csOutFile.Close();
            //}

            return bRtn;
        }

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

        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = Initialize(ref csInitialData, lInputDataNum, ref csInputCellData)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</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 Initialize(ref McPropertyInfoRoot csInitialData, long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;
            // 初期化情報
            McInitialInfo csRtnDt = csInitialData as McInitialInfo;
            if (csRtnDt != null)
            {   // 初期化情報あり
                // 出力時間間隔を取得
                //double dDt = 0.0;
                //csRtnDt.GetInfo("OUTTIME_LAG", ref dDt);
                //m_csOutFileInfo.m_csOutTimeLag = new HySTime(dDt * 1.0);
            }

            // 情報の初期化
            m_csOutFileInfo.m_csLastINTime = HySTime.DEFAULT_TIME.Clone();
            m_csOutFileInfo.m_csLastOutTime = HySTime.DEFAULT_TIME.Clone();

            McTimeSeriesD3CellArrayTranInfo csCellD3Trn = null;
            McTimeSeriesD2CellArrayTranInfo csCellD2Trn = null;
            McTimeSeriesD1CellArrayTranInfo csCellD1Trn = null;
            McTimeSeriesSingleCellTranInfo  csSinglCellTrn = null;

            csSinglCellTrn = csInputCellData[0].GetTranInfo() as McTimeSeriesSingleCellTranInfo;
            csCellD1Trn = csInputCellData[0].GetTranInfo() as McTimeSeriesD1CellArrayTranInfo;
            csCellD2Trn = csInputCellData[0].GetTranInfo() as McTimeSeriesD2CellArrayTranInfo;
            csCellD3Trn = csInputCellData[0].GetTranInfo() as McTimeSeriesD3CellArrayTranInfo;

            if (csSinglCellTrn != null)
            {   // シングルセル情報ならば
                m_csOutFileInfo.m_lDtDim1 = 1;
                // 配列数を保持しておく

                // 配線の繋ぎ替え表を取得
                //HySCellDataGetter csGetter = csInputCellData[0].GetCellDataGetter();
                //m_csOutFileInfo.m_lOutDataIdx = csGetter.GetIdx(0); // 自分が０番目で欲しいデータの対応Index番号を取得して保持
                // ↑上記は間違い
                //  自分が０番目で欲しいデータを取得したいので、m_csOutFileInfo.m_lOutDataIdx=0 固定でなければならない
            }
            else if (csCellD1Trn != null)
            {   // セル１次元配列情報ならば
                m_csOutFileInfo.m_lDtDim1 = csCellD1Trn.GetDimension1();
                // 配列数を保持しておく

                // 配線の繋ぎ替え表を取得
                //HySCellDataGetter csGetter = csInputCellData[0].GetCellDataGetter();
                //m_csOutFileInfo.m_lOutDataIdx = csGetter.GetIdx(0); // 自分が０番目で欲しいデータの対応Index番号を取得して保持
                // ↑上記は間違い
                //  自分が０番目で欲しいデータを取得したいので、m_csOutFileInfo.m_lOutDataIdx=0 固定でなければならない
            }
            else if (csCellD2Trn != null)
            {   // セル２次元配列情報ならば
                m_csOutFileInfo.m_lDtDim1 = csCellD2Trn.GetDimension1();
                m_csOutFileInfo.m_lDtDim2 = csCellD2Trn.GetDimension2();
                // 配列数を保持しておく

                // 配線の繋ぎ替え表を取得
                //HySCellDataGetter csGetter = csInputCellData[0].GetCellDataGetter();
                //m_csOutFileInfo.m_lOutDataIdx = csGetter.GetIdx(0); // 自分が０番目で欲しいデータの対応Index番号を取得して保持
                // ↑上記は間違い
                //  自分が０番目で欲しいデータを取得したいので、m_csOutFileInfo.m_lOutDataIdx=0 固定でなければならない

            }
            else if (csCellD3Trn != null)
            {   // セル３次元配列情報ならば
                m_csOutFileInfo.m_lDtDim1 = csCellD3Trn.GetDimension1();
                m_csOutFileInfo.m_lDtDim2 = csCellD3Trn.GetDimension2();
                m_csOutFileInfo.m_lDtDim3 = csCellD3Trn.GetDimension3();
                // 配列数を保持しておく

                // 配線の繋ぎ替え表を取得
                //HySCellDataGetter csGetter = csInputCellData[0].GetCellDataGetter();
                //m_csOutFileInfo.m_lOutDataIdx = csGetter.GetIdx(0); // 自分が０番目で欲しいデータの対応Index番号を取得して保持
                // ↑上記は間違い
                //  自分が０番目で欲しいデータを取得したいので、m_csOutFileInfo.m_lOutDataIdx=0 固定でなければならない

            }
            else
            {
                m_csOutFileInfo.m_lDtDim1 = 0;
            }

            // ゴミファイルを消去しておく
            if (m_csOutFileInfo.m_lOverWriteSW != 1)
            {   // 上書きでない場合
                string sCalLot = this.GetCalculationLotName().ToString();
                // 出力ファイル設定
                m_csOutFileNameWithFullPath = new HySString(
                    this.GetDataHomeDirectory().ToString() + "\\" + this.GetProjectGroupName().ToString() + "\\" +
                    m_csOutFileInfo.m_sOutDirPath + "\\" + sCalLot + "\\" + m_csOutFileInfo.m_sOutFileName);
            }
            m_csOutFile = new HySFile(m_csOutFileNameWithFullPath.ToString());
            m_csOutFile.Delete(); // 出力ファイルを消去しておく



            m_bSuspFlg = false;
            return bRtn;
        }
        /// <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()
        {
            bool bRtn = true;

            if (m_csOutFileInfo.m_lOverWriteSW != 1)
            {   // 上書きでない場合
                string sCalLot = this.GetCalculationLotName().ToString();
                // 出力ファイル設定
                m_csOutFileNameWithFullPath = new HySString(
                    this.GetDataHomeDirectory().ToString() + "\\" + this.GetProjectGroupName().ToString() + "\\" +
                    m_csOutFileInfo.m_sOutDirPath + "\\" + sCalLot + "\\" + m_csOutFileInfo.m_sOutFileName);
            }

            // 出力ファイル設定
            m_csOutFile = new HySFile(m_csOutFileNameWithFullPath.ToString());

            if (m_csOutFile.Exist() == true)
            {   // もしファイルが存在していれば、中断からの再開なので何もしない（Initializeで既に、ゴミファイルは消去済み）
                // Do Nothing
            }
            // if( m_bSuspFlg == false )
            else
            {   // もし中断中でない（最初の開始）ならば　//ファイルが存在していなければ、最初からなのでヘッダー情報を書き込む（Initializeで既に、ゴミファイルは消去済み）

                // 出力ファイル初期生成
                if (m_csOutFile.Open(HySFile.OPEN_MODE.CREATE_NEW, HySFile.READ_WRITE_MODE.WRITE, HySFile.DIRECTORY_MODE.MK_DIR) == 0)
                {
                    // ver1.6 出力ファイル標準フォーマットの英語化
                    // [日本語タグ]   →　[英語表記タグ]
                    // ・データ区分　　→　DataType
                    // ・時系列　　　　→　TimeSeries
                    // ・配列数　　　　→　Array
                    // ・×　　　　　　→　x

                    // ヘッダーを作成
                    if (m_csOutFileInfo.m_lDimNum == 1)
                    {   // １次元時系列データならば
                        m_csOutFile.WriteText("HySCSVFileData,Ver1.0");  // ヘッダー
                        m_csOutFile.WriteText("DataType, TimeSeries");  // ヘッダー
                        String sWString = "Time";
                        for (int iLp = 0; iLp < m_csOutFileInfo.m_lDtDim1; iLp++)
                        {
                            sWString += ", Data" + iLp.ToString();
                        }
                        m_csOutFile.WriteText(sWString);
                    }
                    else if (m_csOutFileInfo.m_lDimNum == 2)
                    {   // ２次元時系列データならば
                        m_csOutFile.WriteText("HySCSVFileDim2Data,Ver1.0");  // ヘッダー
                        m_csOutFile.WriteText("DataType, TimeSeries");  // ヘッダー
                        String sWString = "Array,";
                        sWString += m_csOutFileInfo.m_lDtDim1.ToString() + ",x," + m_csOutFileInfo.m_lDtDim2.ToString();
                        m_csOutFile.WriteText(sWString);
                        m_csOutFile.WriteText("Time, Data");
                    }
                    else if (m_csOutFileInfo.m_lDimNum == 3)
                    {
                        // ３次元時系列データならば
                        m_csOutFile.WriteText("HySCSVFileDim3Data,Ver1.0");  // ヘッダー
                        m_csOutFile.WriteText("DataType, TimeSeries");  // ヘッダー

                        m_csOutFile.WriteText("Array," + m_csOutFileInfo.m_lDtDim1.ToString()
                                                        + ",x," + m_csOutFileInfo.m_lDtDim2.ToString()
                                                        + ",x," + m_csOutFileInfo.m_lDtDim3.ToString());  // ヘッダー
                        m_csOutFile.WriteText("Time, Data");  // ヘッダー
                    }
                    m_csOutFile.Close();
                }
                else
                {
                    bRtn = false;
                    McStructErrorInfo csErrorInfo = HySCommonInfoHash.GetCorrespondData(McDefine.CALCULATION_ERROR_INF, this.m_csElement.GetOwnerProjectID()) as McStructErrorInfo;
                    if (csErrorInfo != null)
                    {
                       // ver1.5 エラートレース日本語対応
                        csErrorInfo.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                            , Properties.HymcoStandardModelPrjResources.STATEMENT_NO_CREATE_CSV_FILE );
                       // csErrorInfo.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_KIND
                       //     , "Cannot Create CSV File.");
                    }
                }
            }

            return bRtn;
        }
        /// <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()
        {
            // ToDo
            // オペレーター操作等により計算中断時に　コールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。
            // メソッド自身を削除してください
            m_bSuspFlg = true;
            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()
        {
            // ToDo
            // 計算終了時　最後の最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。
            // メソッド自身を削除してください
            m_bSuspFlg = false;
            return true;
        }
        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate(ref csInputDataList)</para>
        /// </example>
        /// <param name="csInputDataList">演算に必要な入力情報リスト</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override long Calculate(ref HySDataLinkedList csInputDataList)
        {
            m_lCalculate_Call_Before_DataFution_Call += 1; // Calculate Call 回数カウントアップ
            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) 
        {
            // データ取得
            this.ReadData( );

            long lDtNum = m_csOutFileInfo.m_csDataList.Count;  // 保管中の情報の数

            LinkedListNode<McOutRecordBase> csDtNode;

            McOutRecordBase csData = null;
            McOutD1Record csD1Data = null;
            McOutD2Record csD2Data = null;
            McOutD3Record csD3Data = null;

            HySTime csTm = null;
            string sStr = "";

            for (int iLp = 0; iLp < lDtNum; iLp++)
            {   // 保管中の情報分繰り返す

                // 保管情報を１レコードづつ取り出す
                csDtNode = m_csOutFileInfo.m_csDataList.First;
                csData = csDtNode.Value;
                csTm = csData.m_csTime; // レコードの時刻
                if ((m_csOutFileInfo.m_csLastOutTime + m_csOutFileInfo.m_csOutTimeLag).After(csTm) == false)
                {   // 出力すべきレコード時刻か？

                    if (m_csOutFile.Open(HySFile.OPEN_MODE.APPEND, HySFile.READ_WRITE_MODE.WRITE, HySFile.DIRECTORY_MODE.NOT_MK_DIR) == 0)
                    {   // 出力ファイルオープン
                        // ファイルへ書き込み
                        if (m_csOutFileInfo.m_lDimNum == 1)
                        {   // １次元データならば
                            csD1Data = csData as McOutD1Record;
                            sStr = HySCalendar.GetString(csData.m_csTime, HySCalendar.FORMAT.lSW_YEAR).ToString();
                            for (int iDtLp = 0; iDtLp < m_csOutFileInfo.m_lDtDim1; iDtLp++)
                            {
                                sStr += "," + (csD1Data.m_dDT[iDtLp]).ToString();
                            }
                            m_csOutFile.WriteText(sStr);
                        }
                        else if (m_csOutFileInfo.m_lDimNum == 2)
                        {   // ２次元データならば
                            csD2Data = csData as McOutD2Record;
                            sStr = HySCalendar.GetString(csData.m_csTime, HySCalendar.FORMAT.lSW_YEAR).ToString();
                            m_csOutFile.WriteText(sStr);
                            for (int iDtP2 = 0; iDtP2 < m_csOutFileInfo.m_lDtDim2; iDtP2++)
                            {
                                sStr = "";
                                for (int iDtLp = 0; iDtLp < m_csOutFileInfo.m_lDtDim1; iDtLp++)
                                {
                                    sStr += "," + (csD2Data.m_dD2DT[iDtLp, iDtP2]).ToString();
                                }
                                m_csOutFile.WriteText(sStr);
                            }
                        }
                        else if (m_csOutFileInfo.m_lDimNum == 3)
                        {   // ３次元データならば
                            csD3Data = csData as McOutD3Record;
                            sStr = HySCalendar.GetString(csData.m_csTime, HySCalendar.FORMAT.lSW_YEAR).ToString();
                            m_csOutFile.WriteText(sStr);

                            //CSVファイルの出力形式（行と列逆転）
                            for (long l3 = 0; l3 < m_csOutFileInfo.m_lDtDim3; l3++)
                            {
                                for (long l2 = 0; l2 < m_csOutFileInfo.m_lDtDim2; l2++)
                                {
                                    sStr = ",";
                                    if (l2 == 0)
                                    {
                                        sStr += string.Format("Layer{0},", l3 + 1);
                                    }
                                    else
                                    {
                                        sStr += ",";
                                    }

                                    for (long l1 = 0; l1 < m_csOutFileInfo.m_lDtDim1; l1++)
                                    {
                                        sStr += Convert.ToString(csD3Data.m_dD3DT[l1, l2, l3]) + ",";
                                    }

                                    //文字列最後のカンマを削除
                                    sStr = sStr.Substring(0, sStr.Length - 1);
                                    m_csOutFile.WriteText(sStr);
                                }
                            }
                        }
                        
                        m_csOutFileInfo.m_csLastOutTime.SetTime(csTm);

                        //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "DataFusion", " WriteDataNum=" + lDtNum.ToString() + " LastWriteString= " + sStr);
                        
                        // 出力ファイルを閉じる
                        m_csOutFile.Close();
                    }
                }

                // 読み出した情報は一時保管情報から削除する
                m_csOutFileInfo.m_csDataList.RemoveFirst();
            } 
  
            return 0;
        }

        /// <summary><para>method outline:</para>
        /// <para>入力された伝送データの取得し一時保管しておく</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ReadData()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual long ReadData()
        {
            McTimeSeriesD1CellArrayTranInfo csCellD1Trn = null;
            McTimeSeriesD2CellArrayTranInfo csCellD2Trn = null;
            McTimeSeriesD3CellArrayTranInfo csCellD3Trn = null;
            McTimeSeriesSingleCellTranInfo csSinglCellTrn = null;

            csCellD1Trn = m_csInputData[0] as McTimeSeriesD1CellArrayTranInfo;
            csCellD2Trn = m_csInputData[0] as McTimeSeriesD2CellArrayTranInfo;
            csCellD3Trn = m_csInputData[0] as McTimeSeriesD3CellArrayTranInfo;
            csSinglCellTrn = m_csInputData[0] as McTimeSeriesSingleCellTranInfo;

            // 入力された伝送情報を読み出す
            if (csCellD1Trn != null)
            {   // １次元の場合
                McD1CellArrayTranInfo csDtRcd = null;
                HySCellData[] csCells = null;
                McReceiveCellDataIF csInputCellData = m_InputCellData[0];
                McOutD1Record csRcd = null;  // １レコード分のデータ

                long lDim = csCellD1Trn.GetDimension(); // 配列の大きさは？
                long lDtNum = csCellD1Trn.SetCursorPlus(m_csOutFileInfo.m_csLastINTime);// 最終時刻以後に情報が追加されているか？

                //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                //    "ReadDataNum=" + lDtNum.ToString() + "    LastIntime=" + (HySCalendar.GetString(m_csOutFileInfo.m_csLastINTime, HySCalendar.FORMAT.lSW_DAY)).ToString());

                for (long lDtLp = 0; lDtLp < lDtNum; lDtLp++)
                {   // 追加された情報分処理を行う

                    csDtRcd = (McD1CellArrayTranInfo)csCellD1Trn.GetCursorData();
                    csCells = csDtRcd.GetCellData();
                    csRcd = new McOutD1Record(lDim);  // １レコード情報格納クラスの生成
                    for (long lDt = 0; lDt < lDim; lDt++)
                    {   // １レコード分の情報を　設定する
                        csRcd.m_dDT[lDt] = csInputCellData.Data(csCells[lDt], m_csOutFileInfo.m_lOutDataIdx);
                    }
                    csRcd.m_csTime = csDtRcd.GetLastTime();

                    //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                    //    " ReadDataTime=" + (HySCalendar.GetString( csDtRcd.GetTime(), HySCalendar.FORMAT.lSW_DAY)).ToString() + " Dt[0]= " + csRcd.m_dDT[0].ToString());

                    // 読み出した情報を一時保管しておく
                    m_csOutFileInfo.m_csDataList.AddLast(csRcd);
                    m_csOutFileInfo.m_csLastINTime.SetTime(csRcd.m_csTime);

                    csCellD1Trn.MoveCursorNext();
                }
            }
            else if (csCellD2Trn != null)
            {   // ２次元の場合
                McD2CellArrayTranInfo csDtD2Rcd = null;
                HySCellData[,] csD2Cells = null;
                McReceiveCellDataIF csInputCellData = m_InputCellData[0];
                McOutD2Record csRcd = null;  // １レコード分のデータ

                long lDim1 = csCellD2Trn.GetDimension1(); // 配列の大きさは？
                long lDim2 = csCellD2Trn.GetDimension2(); // 配列の大きさは？
                long lDtNum = csCellD2Trn.SetCursorPlus(m_csOutFileInfo.m_csLastINTime);// 最終時刻以後に情報が追加されているか？

                //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                //    "ReadDataNum=" + lDtNum.ToString() + "    LastIntime=" + (HySCalendar.GetString(m_csOutFileInfo.m_csLastINTime, HySCalendar.FORMAT.lSW_DAY)).ToString());

                for (long lDtLp = 0; lDtLp < lDtNum; lDtLp++)
                {   // 追加された情報分処理を行う

                    csDtD2Rcd = (McD2CellArrayTranInfo)csCellD2Trn.GetCursorData();
                    csD2Cells = csDtD2Rcd.GetCellData();
                    csRcd = new McOutD2Record(lDim1,lDim2);  // １レコード情報格納クラスの生成
                    for (long lDt = 0; lDt < lDim1; lDt++)
                    {
                        for (long lDt2 = 0; lDt2 < lDim2; lDt2++)
                        {
                            // １レコード分の情報を　設定する
                            csRcd.m_dD2DT[lDt, lDt2] = csInputCellData.Data(csD2Cells[lDt, lDt2], m_csOutFileInfo.m_lOutDataIdx);
                        }
                    }
                    csRcd.m_csTime = csDtD2Rcd.GetLastTime();

                    //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                    //    " ReadDataTime=" + (HySCalendar.GetString( csDtRcd.GetTime(), HySCalendar.FORMAT.lSW_DAY)).ToString() + " Dt[0]= " + csRcd.m_dDT[0].ToString());

                    // 読み出した情報を一時保管しておく
                    m_csOutFileInfo.m_csDataList.AddLast(csRcd);
                    m_csOutFileInfo.m_csLastINTime.SetTime(csRcd.m_csTime);

                    csCellD2Trn.MoveCursorNext();
                }
            }
            else if (csCellD3Trn != null)
            {   // ３次元の場合
                McD3CellArrayTranInfo csDtD3Rcd = null;
                HySCellData[, ,] csD3Cells = null;
                McReceiveCellDataIF csInputCellData = m_InputCellData[0];
                McOutD3Record csRcd = null;  // １レコード分のデータ

                long lDim1 = csCellD3Trn.GetDimension1(); // 配列の大きさは？
                long lDim2 = csCellD3Trn.GetDimension2(); // 配列の大きさは？
                long lDim3 = csCellD3Trn.GetDimension3(); // 配列の大きさは？
                long lDtNum = csCellD3Trn.SetCursorPlus(m_csOutFileInfo.m_csLastINTime);// 最終時刻以後に情報が追加されているか？
                //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                //    "ReadDataNum=" + lDtNum.ToString() + "    LastIntime=" + (HySCalendar.GetString(m_csOutFileInfo.m_csLastINTime, HySCalendar.FORMAT.lSW_DAY)).ToString());
                for (long lDtLp = 0; lDtLp < lDtNum; lDtLp++)
                {   // 追加された情報分処理を行う

                    csDtD3Rcd = (McD3CellArrayTranInfo)csCellD3Trn.GetCursorData();
                    csD3Cells = csDtD3Rcd.GetCellData();
                    csRcd = new McOutD3Record(lDim1, lDim2, lDim3);  // １レコード情報格納クラスの生成

                    for (long l1 = 0; l1 < m_csOutFileInfo.m_lDtDim1; l1++)
                    {
                        for (long l2 = 0; l2 < m_csOutFileInfo.m_lDtDim2; l2++)
                        {
                            for (long l3 = 0; l3 < m_csOutFileInfo.m_lDtDim3; l3++)
                            {
                                csRcd.m_dD3DT[l1, l2, l3] = csInputCellData.Data(csD3Cells[l1, l2, l3], m_csOutFileInfo.m_lOutDataIdx);//セル内の値を取得
                            }
                        }
                    }
                    csRcd.m_csTime = csDtD3Rcd.GetLastTime();

                    //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                    //    " ReadDataTime=" + (HySCalendar.GetString( csDtRcd.GetTime(), HySCalendar.FORMAT.lSW_DAY)).ToString() + " Dt[0]= " + csRcd.m_dDT[0].ToString());

                    // 読み出した情報を一時保管しておく
                    m_csOutFileInfo.m_csDataList.AddLast(csRcd);
                    m_csOutFileInfo.m_csLastINTime.SetTime(csRcd.m_csTime);

                    csCellD3Trn.MoveCursorNext();
                }
            }
            else if (csSinglCellTrn != null)
            {   // 単一セルの場合
                HySCellData csSingleCells = null;
                //McD1CellArrayTranInfo csDtRcd = null;

                McReceiveCellDataIF csInputCellData = m_InputCellData[0];
                McOutD1Record csRcd = null;  // １レコード分のデータ

                long lDim = 1;// csCellD1Trn.GetDimension(); // 配列の大きさは？
                long lDtNum = csSinglCellTrn.SetCursorPlus(m_csOutFileInfo.m_csLastINTime);// 最終時刻以後に情報が追加されているか？

                //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                //    "ReadDataNum=" + lDtNum.ToString() + "    LastIntime=" + (HySCalendar.GetString(m_csOutFileInfo.m_csLastINTime, HySCalendar.FORMAT.lSW_DAY)).ToString());

                for (long lDtLp = 0; lDtLp < lDtNum; lDtLp++)
                {   // 追加された情報分処理を行う

                    csSingleCells = (HySCellData)csSinglCellTrn.GetCursorData();
                    csRcd = new McOutD1Record(lDim);  // １レコード情報格納クラスの生成
                    // １レコード分の情報を　設定する
                    csRcd.m_dDT[0] = csInputCellData.Data(csSingleCells, m_csOutFileInfo.m_lOutDataIdx);

                    csRcd.m_csTime = csSinglCellTrn.GetCursorTime().Clone();

                    //McLog.DebugOut(GetSimulationTime(), m_csElement.GetID(), "McCSVFileOutCtlMdl", "ReadData",
                    //    " ReadDataTime=" + (HySCalendar.GetString( csDtRcd.GetTime(), HySCalendar.FORMAT.lSW_DAY)).ToString() + " Dt[0]= " + csRcd.m_dDT[0].ToString());

                    // 読み出した情報を一時保管しておく
                    m_csOutFileInfo.m_csDataList.AddLast(csRcd);
                    m_csOutFileInfo.m_csLastINTime.SetTime(csRcd.m_csTime);

                    csSinglCellTrn.MoveCursorNext();
                }
            }
            else
            {
            }

            return 0;
        }

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

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

            McModelPropertyInfo csPropInf = csCellMdlPropertyInfo as McModelPropertyInfo;
            if (csPropInf != null)
            {   // プロパティ情報あり
                double dDt = 0.0D;
                csPropInf.GetInfo("OUTTIME_LAG", ref dDt);
                m_csOutFileInfo.m_csOutTimeLag = new HySTime(dDt * 1.0D);

                csPropInf.GetInfo(HymcoStandardModelDefine.OVER_WRITE_OR_OTHER_SWITCH, ref m_csOutFileInfo.m_lOverWriteSW);
                if (m_csOutFileInfo.m_lOverWriteSW == 1)
                {   // 上書き書き出し
                    //string sFileName = "";
                    //csPropInf.GetInfo(HymcoStandardModelDefine.OVER_WRITE_FILE_NAME, ref sFileName);
                    //m_csOutFileNameWithFullPath = new HySString(this.GetDataHomeDirectory().ToString() + "\\" + this.GetProjectGroupName().ToString() + "\\" + sFileName);
                    csPropInf.GetInfo(HymcoStandardModelDefine.OVER_WRITE_FILE_NAME, ref m_csOutFileInfo.m_sOverWriteFileNameWithPath);
                }
                else
                {   // 別名ファイル選択の場合
                    // パス名取得
                    csPropInf.GetInfo(HymcoStandardModelDefine.WRITE_DIRECTORY_NAME, ref m_csOutFileInfo.m_sOutDirPath);
                    // ファイル名取得
                    csPropInf.GetInfo(HymcoStandardModelDefine.WRITE_FILE_NAME, ref m_csOutFileInfo.m_sOutFileName);
                }
            }
            else
            {
                m_csOutFileNameWithFullPath = new HySString(HySEnvInf.GetHomeDirectory().ToString() + "\\temp\\TestFileDfltOut.csv");
            }
            return true;
        }
  
    }
}
