// <summary>ソースコード：ＨＹＭＣＯファイル入力用制御クラス</summary>
// <author>CommonMP</author>

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

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

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Controller;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.CoreImpl.Data.FileIO;
using CommonMP.HYMCO.CoreImpl.Data.StructInfo;

namespace CommonMP.HYMCO.CoreImpl.Model
{
    /// <summary><para>class outline:</para>
    /// <para>ＨＹＭＣＯファイル入力制御クラス（抽象クラス）</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// </remarks>
    public abstract class McBasicFileInCtl : McBasicIOCtlModelBase, McOutModelCtlIF
    {
        //// <summary>入力データ</summary>
        //protected McCalInfo m_csCalInfo = null;

        /// <summary>入力ファイル名称</summary>
        protected HySString m_csInFileNameWithFullPath = new HySString("..\\temp\\Input.csv"); //HySEnvInf.GetHomeDirectory() + new HySString("\\temp\\Input.csv");
        /// <summary>入力ファイルインスタンス</summary>
        protected HySFile m_csInFile = null;
        ///// <summary>入力ファイル形式</summary>
        //protected HySDefine.FileType  m_csOutType = HySDefine.FileType.CSV_TYPE;


        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            if (lInputDataNum > 0)
            {
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckWarningData(this.m_csElement.GetID(), new HySObjectKind("McBasicFileInCtl"),
                      Properties.HymcoImplResources.STATEMENT_ELEMENT_NEED_HAVE_NO );
               // csErrorInf.AddCheckWarningData(this.m_csElement.GetID(), new HySObjectKind("McBasicFileInCtl"), "McBasicFileInCtl Element need have no Receive Port.");
            }
            return true;
        }

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

        /// <summary><para>method outline:</para>
        /// <para>モデル演算結果を外部のエレメントに対して公開する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = DataFusion(ref csOutputDataList)</para>
        /// </example>
        /// <param name="csOutputDataList">演算結果を公開する出力情報リスト</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override long DataFusion(ref HySDataLinkedList csOutputDataList)
        {
            long lRtn = 0;
            if (m_lCalculate_Call_Before_DataFution_Call == 0)
            {
                return lRtn;
            }
            // 各伝送データに現在時刻を指定して伝送するレコード情報を作成する <-- これを行ってはならない
            //for (long lLp = 0; lLp < m_lOutputDataNum; lLp++)
            //{
            //    if (m_OutputCellData[lLp] != null)
            //    {
            //        m_OutputCellData[lLp].SetCurrentTime(this.m_csSimTime);
            //    }
            //}
            
            // モデル側で計算した結果を設定する
            lRtn = DataFusion(m_lOutputDataNum, ref m_OutputCellData);
            // モデルがセットした伝送情報を　実際に伝送データとして流す
            for (long lLp = 0; lLp < m_lOutputDataNum; lLp++)
            {
                if (m_OutputCellData[lLp] != null)
                {
                    m_OutputCellData[lLp].SendData();
                }
            }

            m_lCalculate_Call_Before_DataFution_Call = 0;
            return lRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>計算状態復元のためのデータクラスを生成する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCmnElementOutData csElementOutData = CreateOutData()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>データクラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McCmnElementOutData CreateOutData()
        {
            return new McFileInCtlOutData();
        }

        /// <summary><para>method outline:</para>
        /// <para>ファイルにモデル内情報を全て書き出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileOUT(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>bool true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool FileOUT(HySDataRoot csData)
        {
            ((McFileInCtlOutData)(csData)).SetFileInData(m_csCalInfo);
            ((McFileInCtlOutData)(csData)).SetFileName(m_csInFileNameWithFullPath);
            ((McFileInCtlOutData)(csData)).SetInFile(m_csInFile);

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>ファイルからモデル情報を全て読み出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileIN(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>bool true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool FileIN(HySDataRoot csData)
        {
            // 演算状態の復元
            McCalInfo csCalInfo = ((McFileInCtlOutData)(csData)).GetFileInData();
            if (m_csCalInfo != null)
            {
                m_csCalInfo.CopyInfo(csCalInfo);
            }
            m_csInFileNameWithFullPath = ((McFileInCtlOutData)(csData)).GetFileName();
            m_csInFile = ((McFileInCtlOutData)(csData)).GetInFile();

            // 復元後の整合性確保
            if (m_csCalInfo != null)
            {
                if (m_csCalInfo is HySVersionManagement)
                {
                    ((HySVersionManagement)m_csCalInfo).PostDeserialize();
                }
            }

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル内部の時刻を進める</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>GainSimulationTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void GainSimulationTime()
        {
            m_csSimTime.SetTime(m_csTgtTime);
        }

        //================
        // 各種設定メソッド
        //================
        /*
        /// <summary><para>method outline:</para>
        /// <para>モデル演算中の情報格納クラスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCalInfo(csCalInfo)</para>
        /// </example>
        /// <param name="csCalInfo">演算結果格納するクラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetCalInfo(McCalInfo csCalInfo)
        {
            m_csCalInfo = csCalInfo;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル演算中の情報格納クラスを取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCalInfo csCalInfo = GetCalInfo()</para>
        /// </example>
        /// <param name=""></param>
        /// <returns>モデル演算中の情報格納クラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McCalInfo GetCalInfo()
        {
            return m_csCalInfo;
        }
        */

        // Ver1.5 追加（ファイルの有無チェック）
        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SetProperty(csPropertyInfo)</para>
        /// </example>
        /// <param name="csCellMdlPropertyInfo">セル型プロパティ情報</param>
        /// <returns>bool true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SetProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>シミュレーションデータコンテナの内容を設定する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSimDataContainerInfo( csDataContainer )</para>
        /// </example>
        /// <param name="csDataContainer">シミュレーションデータコンテナ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetSimDataContainer(HySSimulationDataContainer csDataContainer)
        {
            // 何もしない
        }

        /// <summary><para>method outline:</para>
        /// <para>現在状態の一時記憶（但し計算途中状態は除く）</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Memorize() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Memorize()とRemember()は対で使用する</para>
        /// </remarks>
        public override void Memorize()
        {
            // Do Nothing ＜＝重要
        }

        /// <summary><para>method outline:</para>
        /// <para>Memorize()した情報の復元</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Remember() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Memorize()とRemember()は対で使用する</para>
        /// </remarks>
        public override void Remember()
        {
            // Do Nothing ＜＝重要
        }


        // Ver1.5 追加（プロジェクトプロパティ画面）
        /// <summary><para>method outline:</para>
        /// <para>モデルが読み込むデータファイル名を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>csList = GetReadFiles()</para>
        /// </example>
        /// <param name="">なし</param>
        /// <returns> データファイル名</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual List<string> GetReadFiles()
        {
            return null;
        }
    }
}
