// <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>マージ出力要素モデル(csv)</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.4.0][2013/12/10][新規作成]</para>
    /// <para>remarks:</para>
    /// <para>無し</para>
    /// </remarks>
    public class McCSVFileOutMergeMdl : McBasicFileOutCtl
    {
        /// <summary> 内部変数 </summary>
        protected McCSVFileOutMergeMdlInfo 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_MERGE_KIND,
                    Properties.HymcoStandardModelPrjResources.STATEMENT_NO_REC_PORT);
               // csErrorInf.AddCheckErrorData(this.m_csElement.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_MERGE_KIND, "No Receive Port");
                bRtn = false;
            }
            else
            {
                HySObjectKind csStandTranKind = null;
                long lStandD1 = 0;
                HySObjectKind csTranKind = null;
                long lD1 = 0;
                long lD2 = 0;
                long lD3 = 0;
                long lCellDataNum = 0;
                long lCellDim = 0;
                for (long lP = 0; lP < lInputDataNum; lP++)
                {
                    csTranKind = csInputCellData[lP].GetTranInfoKind();
                    lCellDim = csInputCellData[lP].GetDimension(ref lD1, ref lD2, ref lD3, ref lCellDataNum);
                    if (lP == 0)
                    {
                        csStandTranKind = csTranKind;
                        lStandD1 = lD1;
                    }
                    else if (csStandTranKind.Equals(csTranKind) == false)
                    {
                        // ◆入力データが全て同じ伝送情報(ポイント時系列 or 1次元時系列)であるか
                       // ver1.5 エラートレース日本語対応
                        csErrorInf.AddCheckErrorData(this.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_MERGE_KIND,
                                   Properties.HymcoStandardModelPrjResources.STATEMENT_REC_DATA_DIFF_INFO );
                       // csErrorInf.AddCheckErrorData(this.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_MERGE_KIND,
                       // "Receive data is different from Others. (Transmitting Infomation Type)");
                        bRtn = false;
                    }
                    else if (lStandD1.Equals(lD1) == false)
                    {
                        // ◆入力データが全て同じ配列数であるか
                       // ver1.5 エラートレース日本語対応
                        csErrorInf.AddCheckErrorData(this.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_MERGE_KIND,
                                   Properties.HymcoStandardModelPrjResources.STATEMENT_REC_DATA_DIFF_CELL );
                       // csErrorInf.AddCheckErrorData(this.GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_MERGE_KIND,
                       // "Receive data is different from Others. (The Number of Cells)");
                        bRtn = false;
                    }
                }
                m_csOutFileInfo.m_lDimNum = lCellDim;
                m_csOutFileInfo.m_lDtDim1 = lD1;
            }

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

            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();
            for (int iLP = 0; iLP < m_csOutFileInfo.m_csCSVExportOrderList.Count; iLP++)
            {
                m_csOutFileInfo.m_csLastINTimeTbl[m_csOutFileInfo.m_csCSVExportOrderList[iLP]] = HySTime.DEFAULT_TIME.Clone();
            }
            for (int iLP = 0; iLP < m_csOutFileInfo.m_csCSVExportOrderList.Count; iLP++)
            {
                m_csOutFileInfo.m_csLastOutTimeTbl[m_csOutFileInfo.m_csCSVExportOrderList[iLP]] = HySTime.DEFAULT_TIME.Clone();
            }

            McTimeSeriesD1CellArrayTranInfo csCellD1Trn = null;
            McTimeSeriesSingleCellTranInfo  csSinglCellTrn = null;

            csSinglCellTrn = csInputCellData[0].GetTranInfo() as McTimeSeriesSingleCellTranInfo;
            csCellD1Trn = csInputCellData[0].GetTranInfo() as McTimeSeriesD1CellArrayTranInfo;

            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
            {
                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で既に、ゴミファイルは消去済み）

                // 入力されるデータ種別情報の管理（要素IDをkeyとしてハッシュ管理）
                for (long lLp = 0; lLp < m_lInputDataNum; lLp++)
                {
                    HySString csCntID = (HySString)this.m_csInputData[lLp].GetCommonInf().GetUpperElementID().GetString();// 上流側要素ID
                    if (csCntID.ToString().IndexOf('-') != -1)
                    {// 分割出来る場合
                        csCntID = new HySString(csCntID.ToString().Substring(0, csCntID.ToString().IndexOf('-')));
                    }
                    McTranInfoPattern csTranInfoPatternProperty = this.m_csInputData[lLp].GetCommonInf().GetReceiveCellData().GetReceiveTranInfoPattern() as McTranInfoPattern;
                    HySCellDataGetter csCellDataGetter = this.m_csInputData[lLp].GetCommonInf().GetReceiveCellData().GetCellDataGetter();
                    HySDataCharacteristicInCell csSDataCharacteristicInCell = csTranInfoPatternProperty.GetCellDataCharacteristic();
                    long lDim = csSDataCharacteristicInCell.m_lDim;
                    long lIdx = csCellDataGetter.GetIdx(lDim - 1);
                    // ファクトリクラスで定義されている種別文字列
                    string sName = this.m_csInputData[lLp].GetCommonInf().GetSendCellData().GetTranInfoPattern().GetCellDataCharacteristic().m_csDataKind[lIdx].ToString();

                    m_csOutFileInfo.m_csDataKindTbl[csCntID.ToString()] = sName;
                }

                // 出力ファイル初期生成
                if (m_csOutFile.Open(HySFile.OPEN_MODE.CREATE_NEW, HySFile.READ_WRITE_MODE.WRITE, HySFile.DIRECTORY_MODE.MK_DIR) == 0)
                {
                    // ヘッダーを作成
                    if (m_csOutFileInfo.m_lDimNum == 1)
                    {   // １次元時系列データならば
                        m_csOutFile.WriteText("HySCSVFileData,Ver1.0");  // ヘッダー
                        m_csOutFile.WriteText("DataDivision, TimeSeries");  // ヘッダー
                        String sWString = "Time";
                        for (int iLp = 0; iLp < (int)m_csOutFileInfo.m_lDtDim1; iLp++)
                        {// 1レコード中のデータ(配列)数分ループ
                            for (int iLp2 = 0; iLp2 < m_csOutFileInfo.m_csCSVExportOrderList.Count; iLp2++)
                            {// 入力数分ループ
                                string sElmID = m_csOutFileInfo.m_csCSVExportOrderList[iLp2];
                                string sKindName = (string)m_csOutFileInfo.m_csDataKindTbl[sElmID];
                                sWString += ", Data" + iLp.ToString() + ":" + sElmID + "-" + sKindName;
                            }
                        }
                        m_csOutFile.WriteText(sWString);
                    }
                    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) 
        {
            // 内挿処理に現在時刻を設定
            for (long lP = 0; lP < m_lInputDataNum; lP++)
            {   // 入力データ数分
                if (m_InputCellData[lP] != null)
                {
                    m_InputCellData[lP].SetCurrentTime(this.m_csSimTime);
                }
            }

            // データ取得
            this.ReadData( );

            // 出力処理
            //string sStr = "";
            // 時系列データ数分（初回は複数時刻分リストに追加される為）
            for (int iTimeLp = 0; iTimeLp < m_csOutFileInfo.m_csINTimeList.Count; iTimeLp++)
            {
                string sStr = "";
                LinkedList<McMergeOutRecordBase> csDataList = null;
                HySTime csTm = null;
                for (int iLp = 0; iLp < (int)m_csOutFileInfo.m_lDtDim1; iLp++)
                {// 1レコード中のデータ(配列)数分ループ
                    for (int iLp2 = 0; iLp2 < m_csOutFileInfo.m_csCSVExportOrderList.Count; iLp2++)
                    {// 入力数分ループ
                        // 出力順序で処理を進める
                        string sElmID = m_csOutFileInfo.m_csCSVExportOrderList[iLp2];
                        csDataList = (LinkedList<McMergeOutRecordBase>)m_csOutFileInfo.m_csDataListTbl[sElmID];
                        // 保管情報を１レコードづつ取り出す
                        LinkedListNode<McMergeOutRecordBase> csDtNode = csDataList.First;
                        if (csDtNode == null)
                        {
                            //return 0;
                            sStr += ",";
                        }
                        McMergeOutRecordBase csData = csDtNode.Value;
                        csTm = csData.m_csTime; // レコードの時刻
                        if (((HySTime)m_csOutFileInfo.m_csLastOutTimeTbl[sElmID] + m_csOutFileInfo.m_csOutTimeLag).After(csTm) == false)
                        {   // 出力すべきレコード時刻か確認
                            if (m_csOutFileInfo.m_lDimNum == 1)
                            {   // １次元データならば
                                McMergeOutD1Record csD1Data = csData as McMergeOutD1Record;
                                if (sStr == "")
                                {
                                    // 初回のみレコードの先頭に時刻を付与する
                                    sStr = HySCalendar.GetString(csData.m_csTime, HySCalendar.FORMAT.lSW_YEAR).ToString();
                                }
                                sStr += "," + (csD1Data.m_dDT[iLp]).ToString();
                                //m_csOutFile.WriteText(sStr);
                            }
                            if (m_csOutFileInfo.m_lDtDim1 == 1)
                            {
                                m_csOutFileInfo.m_csLastOutTimeTbl[sElmID] = csTm;
                            }
                        }
                        // 読み出した情報は一時保管情報から削除する
                        if (m_csOutFileInfo.m_lDtDim1 == 1)
                        {
                            csDataList.RemoveFirst();
                        }
                    }
                }
                if (m_csOutFileInfo.m_lDtDim1 != 1)
                {
                    for (int iLp = 0; iLp < m_csOutFileInfo.m_csCSVExportOrderList.Count; iLp++)
                    {
                        m_csOutFileInfo.m_csLastOutTimeTbl[m_csOutFileInfo.m_csCSVExportOrderList[iLp]] = csTm;
                        csDataList = (LinkedList<McMergeOutRecordBase>)m_csOutFileInfo.m_csDataListTbl[m_csOutFileInfo.m_csCSVExportOrderList[iLp]];
                        csDataList.RemoveFirst();
                    }
                    //csDataList.RemoveFirst();
                }
                if (sStr != "")
                {
                    if (m_csOutFile.Open(HySFile.OPEN_MODE.APPEND, HySFile.READ_WRITE_MODE.WRITE, HySFile.DIRECTORY_MODE.NOT_MK_DIR) == 0)
                    {   // 出力ファイルオープン
                        m_csOutFile.WriteText(sStr);// ファイルへ書き込み
                    }
                    // 出力ファイルを閉じる
                    m_csOutFile.Close();
                }
            }
            // 管理リストクリア
            m_csOutFileInfo.m_csINTimeList.Clear();
            //if (sStr != "")
            //{
            //    if (m_csOutFile.Open(HySFile.OPEN_MODE.APPEND, HySFile.READ_WRITE_MODE.WRITE, HySFile.DIRECTORY_MODE.NOT_MK_DIR) == 0)
            //    {   // 出力ファイルオープン
            //        m_csOutFile.WriteText(sStr);// ファイルへ書き込み
            //    }
            //    // 出力ファイルを閉じる
            //    m_csOutFile.Close();
            //}
            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;
            McTimeSeriesSingleCellTranInfo csSinglCellTrn = null;

            // 入力数分の処理
            for (long lP = 0; lP < m_lInputDataNum; lP++)
            {
                csCellD1Trn = m_csInputData[lP] as McTimeSeriesD1CellArrayTranInfo;
                csSinglCellTrn = m_csInputData[lP] as McTimeSeriesSingleCellTranInfo;

                // 入力された伝送情報を読み出す
                if (csCellD1Trn != null)
                {   // １次元の場合
                    // ◆上流側要素IDを取得
                    HySString csCntID = null;
                    LinkedList<McMergeOutRecordBase> csDataList = null;
                    csCntID = (HySString)csCellD1Trn.GetUpperElementID().GetString();
                    if (csCntID.ToString().IndexOf('-') != -1)
                    {// 分割出来る場合
                        csCntID = new HySString(csCntID.ToString().Substring(0, csCntID.ToString().IndexOf('-')));
                    }
                    // ◆ハッシュ管理
                    if (m_csOutFileInfo.m_csDataListTbl[csCntID.ToString()] == null)
                    {
                        csDataList = new LinkedList<McMergeOutRecordBase>();
                        m_csOutFileInfo.m_csDataListTbl[csCntID.ToString()] = csDataList;// 追加
                    }
                    else
                    {
                        csDataList = (LinkedList<McMergeOutRecordBase>)m_csOutFileInfo.m_csDataListTbl[csCntID.ToString()];
                    }

                    McD1CellArrayTranInfo csDtRcd = null;
                    HySCellData[] csCells = null;
                    McReceiveCellDataIF csInputCellData = m_InputCellData[lP];
                    McMergeOutD1Record csRcd = null;  // １レコード分のデータ

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

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

                        csDtRcd = (McD1CellArrayTranInfo)csCellD1Trn.GetCursorData();
                        csCells = csDtRcd.GetCellData();
                        HySCellData[] csInterpoCells = csInputCellData.GetInterpolatedCellD1();
                        csRcd = new McMergeOutD1Record(lDim);  // １レコード情報格納クラスの生成
                        if (((HySTime)(m_csOutFileInfo.m_csLastINTimeTbl[csCntID.ToString()])).GetTime() == HySTime.DEFAULT_TIME.GetTime())
                        {// 初回のみ
                            for (long lDt = 0; lDt < lDim; lDt++)
                            {   // １レコード分の情報を　設定する
                                csRcd.m_dDT[lDt] = csInputCellData.Data(csCells[lDt], m_csOutFileInfo.m_lOutDataIdx);
                            }
                            csRcd.m_csTime = csDtRcd.GetLastTime().Clone();
                        }
                        else
                        {
                            for (long lDt = 0; lDt < lDim; lDt++)
                            {   // １レコード分の情報を　設定する
                                csRcd.m_dDT[lDt] = csInputCellData.Data(csInterpoCells[lDt], m_csOutFileInfo.m_lOutDataIdx);
                            }
                            csRcd.m_csTime = this.m_csSimTime.Clone();
                        }
                        // 読み出した情報を一時保管しておく
                        //m_csOutFileInfo.m_csDataList.AddLast(csRcd);
                        csDataList.AddLast(csRcd);// 出力レコードの時系列を入力(要素ID)毎に管理
                        m_csOutFileInfo.m_csLastINTimeTbl[csCntID.ToString()] = csRcd.m_csTime;
                        if (m_csOutFileInfo.m_bListAddFlg != true)
                        {
                            m_csOutFileInfo.m_csINTimeList.Add(csRcd.m_csTime);// 出力時の時系列データ数分反復処理に使う
                        }
                        csCellD1Trn.MoveCursorNext();
                    }
                    // フラグON
                    m_csOutFileInfo.m_bListAddFlg = true;
                }
                else if (csSinglCellTrn != null)
                {   // 単一セルの場合
                    // ◆上流側要素IDを取得
                    HySString csCntID = null;
                    LinkedList<McMergeOutRecordBase> csDataList = null;
                    csCntID = (HySString)csSinglCellTrn.GetUpperElementID().GetString();
                    if (csCntID.ToString().IndexOf('-') != -1)
                    {// 分割出来る場合
                        csCntID = new HySString(csCntID.ToString().Substring(0, csCntID.ToString().IndexOf('-')));
                    }
                    // ◆ハッシュ管理
                    if (m_csOutFileInfo.m_csDataListTbl[csCntID.ToString()] == null)
                    {
                        csDataList = new LinkedList<McMergeOutRecordBase>();
                        m_csOutFileInfo.m_csDataListTbl[csCntID.ToString()] = csDataList;// 追加
                    }
                    else
                    {
                        csDataList = (LinkedList<McMergeOutRecordBase>)m_csOutFileInfo.m_csDataListTbl[csCntID.ToString()];
                    }

                    HySCellData csSingleCells = null;
                    //McD1CellArrayTranInfo csDtRcd = null;

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

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

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

                        csSingleCells = (HySCellData)csSinglCellTrn.GetCursorData();
                        HySCellData[] csInterpoCells = csInputCellData.GetInterpolatedCellD1();
                        csRcd = new McMergeOutD1Record(lDim);  // １レコード情報格納クラスの生成
                        // １レコード分の情報を　設定する
                        if (((HySTime)(m_csOutFileInfo.m_csLastINTimeTbl[csCntID.ToString()])).GetTime() == HySTime.DEFAULT_TIME.GetTime())
                        {// 初回のみ
                            csRcd.m_dDT[0] = csInputCellData.Data(csSingleCells, m_csOutFileInfo.m_lOutDataIdx);
                            csRcd.m_csTime = csSinglCellTrn.GetCursorTime().Clone();
                        }
                        else
                        {
                            csRcd.m_dDT[0] = csInputCellData.Data(csInterpoCells[0], m_csOutFileInfo.m_lOutDataIdx);
                            csRcd.m_csTime = this.m_csSimTime.Clone();
                        }
                        // 読み出した情報を一時保管しておく
                        //m_csOutFileInfo.m_csDataList.AddLast(csRcd);
                        csDataList.AddLast(csRcd);// 出力レコードの時系列を入力(要素ID)毎に管理
                        m_csOutFileInfo.m_csLastINTimeTbl[csCntID.ToString()] = csRcd.m_csTime;
                        if (m_csOutFileInfo.m_bListAddFlg != true)
                        {
                            m_csOutFileInfo.m_csINTimeList.Add(csRcd.m_csTime);// 出力時の時系列データ数分反復処理に使う
                        }
                        csSinglCellTrn.MoveCursorNext();
                    }
                    // フラグON
                    m_csOutFileInfo.m_bListAddFlg = true;
                }
                else
                {
                }
            }
            // フラグ解除
            m_csOutFileInfo.m_bListAddFlg = false;
            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 = (McCSVFileOutMergeMdlInfo)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;
        }

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

            McModelPropertyInfo csPropInf = csCellMdlPropertyInfo as McModelPropertyInfo;
            if (csPropInf != null)
            {   // プロパティ情報あり
                // ＣＳＶ出力順序に関するチェック
                HySDataLinkedList csInputInfoList = ((McCellModelPropertyInfo)csPropInf).GetInputConnectionInfoList();
                string sVal = "";
                if (csPropInf.GetInfo(HymcoStandardModelDefine.INPUT_LINE_NUM, ref sVal) == true)
                {
                    if (csInputInfoList.GetCount().ToString().Equals(sVal) == false)
                    {
                        //◆ プロパティ情報の入力線の数が正しいかチェック
                        // 再設定を促すメッセージを通知
                       // ver1.5 エラートレース日本語対応
                        string sMsg = Properties.HymcoStandardModelPrjResources.STATEMENT_CSVFILE_EXPORT_AGEIN ;
                       // string sMsg = "Project was changed. Please set CSVFile export order again.";
                        csErrorInfo.AddCheckErrorData(GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_MERGE_KIND, sMsg);
                        bRtn = false;
                    }
                    else
                    {
                        //◆ プロパティ情報で管理されている要素ID以外がないかチェック
                        int iNum = (int)csInputInfoList.GetCount();
                        for (int iLp = 0; iLp < iNum; iLp++)
                        {
                            HySString csKey = new HySString(iLp.ToString());
                            if (((McModelPropertyInfo)csPropInf).GetInfo(csKey, ref sVal) == true)
                            {
                                // 要素が置き換わってないかチェック
                                bool bChk = this.CheckElementID(csPropInf, sVal);
                                if (bChk == false)
                                {
                                    // 再設定を促すメッセージを通知
                                   // ver1.5 エラートレース日本語対応
                                    string sMsg = Properties.HymcoStandardModelPrjResources.STATEMENT_CSVFILE_EXPORT_AGEIN ;
                                   // string sMsg = "Project was changed. Please set CSVFile export order again.";
                                    csErrorInfo.AddCheckErrorData(GetID(), HymcoStandardModelDefine.CSV_FILE_OUT_MERGE_KIND, sMsg);
                                    bRtn = false;
                                    break;
                                }
                            }
                        }
                    }
                    // ＣＳＶ出力順序情報の作成
                    for (int iLp = 0; iLp < (int)csInputInfoList.GetCount(); iLp++)
                    {
                        HySString csKey = new HySString(iLp.ToString());
                        if (((McModelPropertyInfo)csPropInf).GetInfo(csKey, ref sVal) == true)
                        {
                            // Start of 要素名称対応
                            if (sVal.IndexOf('[') != -1)
                            {// 此処で[要素名称]があればトリミングする(内部処理としては不要な為)
                                sVal = sVal.Substring(0, sVal.IndexOf('['));
                            }
                            // End of 要素名称対応
                            m_csOutFileInfo.m_csCSVExportOrderList.Add(sVal);
                        }
                    }
                    //// 入力されるデータ種別情報の管理（要素IDをkeyとしてハッシュ管理）
                    //for (int iLp = 0; iLp < (int)csInputInfoList.GetCount(); iLp++)
                    //{
                    //    HySString csKey = new HySString(iLp.ToString());
                    //    if (((McModelPropertyInfo)csPropInf).GetInfo(csKey, ref sVal) == true)
                    //    {
                    //        McTranInfoPattern csTranInfoPatternProperty = this.m_csInputData[iLp].GetCommonInf().GetReceiveCellData().GetReceiveTranInfoPattern() as McTranInfoPattern;
                    //        HySCellDataGetter csCellDataGetter = this.m_csInputData[iLp].GetCommonInf().GetReceiveCellData().GetCellDataGetter();
                    //        HySDataCharacteristicInCell csSDataCharacteristicInCell = csTranInfoPatternProperty.GetCellDataCharacteristic();
                    //        long lDim = csSDataCharacteristicInCell.m_lDim;
                    //        long lIdx = csCellDataGetter.GetIdx(lDim - 1);
                    //        // ファクトリクラスで定義されている種別文字列
                    //        string sName = this.m_csInputData[iLp].GetCommonInf().GetSendCellData().GetTranInfoPattern().GetCellDataCharacteristic().m_csDataKind[lIdx].ToString();

                    //        m_csOutFileInfo.m_csDataKindTbl[sVal] = sName;
                    //    }
                    //}
                }
                else
                {
                    // モデルライブラリ設定後、プロパティ設定画面の設定ボタンを押下していないケース
                    long lInputInfoNum = csInputInfoList.GetCount();
                    if (lInputInfoNum != 0)
                    {
                        HySString csKey = new HySString(HymcoStandardModelDefine.INPUT_LINE_NUM);
                        string sNewVal = lInputInfoNum.ToString();
                        ((McModelPropertyInfo)csPropInf).AddInfoType(csKey, new HySString("Line"), McDefine.ValKind.STRING);
                        ((McModelPropertyInfo)csPropInf).SetInfo(csKey, sNewVal);// 入力線の数を追加

                        HySString csCntID = null;
                        for (long lLp = 0; lLp < lInputInfoNum; lLp++)
                        {
                            McModelInfo csModelInfo = csInputInfoList.GetData(lLp) as McModelInfo;
                            if (csModelInfo != null)
                            {
                                McCellArrayTranInfoPropertyInfo csTranInfoPro = csModelInfo.GetPropertyInfo() as McCellArrayTranInfoPropertyInfo;
                                if (csTranInfoPro != null)
                                {
                                    csCntID = (HySString)csTranInfoPro.GetUpperModelInfo().GetElementID().GetString();
                                    if (csCntID.ToString().IndexOf('-') != -1)
                                    {// 分割出来る場合
                                        csCntID = new HySString(csCntID.ToString().Substring(0, csCntID.ToString().IndexOf('-')));
                                        csKey = new HySString(lLp.ToString());
                                        sNewVal = csCntID.ToString();
                                        ((McModelPropertyInfo)csPropInf).AddInfoType(csKey, new HySString("Item"), McDefine.ValKind.STRING);
                                        ((McModelPropertyInfo)csPropInf).SetInfo(csKey, sNewVal);// リストのインデックスと要素IDの文字列を追加
                                        // ＣＳＶ出力順序情報の作成
                                        m_csOutFileInfo.m_csCSVExportOrderList.Add(sNewVal);
                                    }
                                }
                            }
                        }
                    }
                }

                double dDt = 0.0D;
                csPropInf.GetInfo("OUTTIME_LAG", ref dDt);
                m_csOutFileInfo.m_csOutTimeLag = new HySTime(dDt * 1.0D);
                this.m_csDltTime = new HySTime(dDt * 1.0D);
                this.m_bDltTimeSetFlg = true;

                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 bRtn;
        }

        /// <summary>
        /// <para>method outline:</para>
        /// <para>ID存在チェック処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>CheckElementID(csModelPropertyInfo, sID);</para>
        /// </example>
        /// <param name="csModelPropertyInfo">プロパティ情報</param>
        /// <param name="sID">要素ID</param>
        /// <returns>true:IDが存在、false:IDが存在しない</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private bool CheckElementID(McModelPropertyInfo csModelPropertyInfo, string sID)
        {
            // 1.プロパティ情報から上流側要素ID
            HySDataLinkedList csInputInfoList = ((McCellModelPropertyInfo)csModelPropertyInfo).GetInputConnectionInfoList();
            HySString csCntID = null;
            for (long lLp = 0; lLp < csInputInfoList.GetCount(); lLp++)
            {
                McModelInfo csModelInfo = csInputInfoList.GetData(lLp) as McModelInfo;
                if (csModelInfo != null)
                {
                    McCellArrayTranInfoPropertyInfo csTranInfoPro = csModelInfo.GetPropertyInfo() as McCellArrayTranInfoPropertyInfo;
                    if (csTranInfoPro != null)
                    {
                        csCntID = (HySString)csTranInfoPro.GetUpperModelInfo().GetElementID().GetString();
                        if (csCntID.ToString().IndexOf('-') != -1)
                        {// 分割出来る場合
                            csCntID = new HySString(csCntID.ToString().Substring(0, csCntID.ToString().IndexOf('-')));
                            // Start of 要素名称対応
                            HySString csUserName = csTranInfoPro.GetUpperModelInfo().GetUserName();
                            if (csUserName != "")
                            {
                                csUserName = new HySString("[") + csUserName + new HySString("]");
                                csCntID += csUserName;
                            }
                            // End of 要素名称対応
                            if (sID.Equals(csCntID.ToString()) == true)
                            {
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        }
  
    }
}
