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

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

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

namespace CommonMP.HYMCO.OptionImpl.McConvergenceSample
{
    /// <summary><para>class outline:</para>
    /// <para>テスト用演算モデルクラス（入力値を累積する）</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// </remarks>
    public class McCnvElmSampleTestModel : McForecastModelBase //McStateCalModelBase
    {  
        /// <summary> キャストして使用する </summary>
        McCnvElmSampleTestCalInfo m_csTestInf;

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDebugTestModel csObj = new McDebugTestModel()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McCnvElmSampleTestModel()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;
            if (lInputDataNum == 0)
            {
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckErrorData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL, 
                    Properties.Resources.STATEMENT_NO_REC_DATA );
               // csErrorInf.AddCheckErrorData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL, "No receive data.");
                bRtn = false;
            }
            for (long lP = 0; lP < lInputDataNum; lP++)
            {   // 入力データ数分
                if( McTranInfoDefine.SINGLE_CELL_SERIAL.Equals(csInputCellData[lP].GetTranInfoKind())==true )
                {
                }
                else
                {
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL,
                        Properties.Resources.STATEMENT_UNEXPECT_REC_DATA_TYPE_R + csInputCellData[lP].GetUpperElementID().ToString() + ")");
                   // csErrorInf.AddCheckErrorData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL,
                   //     //"Unexpected receive data type. (Received from " + csInDt.GetUpperElementID().ToString() + ")");
                   //     "Unexpected receive data type. (Received from " + csInputCellData[lP].GetUpperElementID().ToString() + ")");
                    bRtn = false;
                }
            }
            return bRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>出力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SendConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lOutputDataNum">出力情報数</param>
        /// <param name="csOutputCellData">出力情報配列</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>送信端子に設定されている伝送データが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool SendConnectionCheck(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)
        {
            bool bRtn = true;
            if (lOutputDataNum == 0)
            {
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckWarningData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL, 
                    Properties.Resources.STATEMENT_NO_SND_PORT );
               // csErrorInf.AddCheckWarningData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL, "No send port.");
            }
            for (long lP = 0; lP < lOutputDataNum; lP++)
            {
                if (McTranInfoDefine.SINGLE_CELL_SERIAL.Equals(csOutputCellData[lP].GetTranInfoKind() ) == true)
                {
                }
                else
                {
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL,
                        Properties.Resources.STATEMENT_UNEXPECT_DATA_TYPE );
                   // csErrorInf.AddCheckErrorData(this.GetID(), McConvergenceSampleDefine.TEST_CNV_ELM_MODEL, "Unexpected send data type.");
                    bRtn = false;
                }
            }
            return bRtn;
        }

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

        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize(csInitialData)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override bool Initialize(ref McPropertyInfoRoot csInitialData, long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            McInitialInfo csInDt = csInitialData as McInitialInfo;
            if (csInDt != null)
            {   // 初期化情報有り
                csInDt.GetInfo("m_dOutDt", ref m_csTestInf.m_dOutDt);
            }
            return true;
        }
   

        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate(ref InputCellData)</para>
        /// </example>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override long Calculate(long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            double dTotalIn = 0.0;
            HySCellData csCellDt = null;
            for (long lP = 0; lP < lInputDataNum; lP++)
            {
                csInputCellData[lP].SetLastTime();  // 最新時刻の情報が欲しい

                csCellDt = csInputCellData[lP].GetInterpolatedCell(0);
                dTotalIn += csInputCellData[lP].Data(csCellDt, 0);
            }

            if (m_csTestInf.m_sObjID == "X")
            {
                m_csTestInf.m_Y = dTotalIn;
                m_csTestInf.m_X = (m_csTestInf.m_dTtlLimit - m_csTestInf.m_dB * m_csTestInf.m_Y) / m_csTestInf.m_dA;
                m_csTestInf.m_dOutDt = m_csTestInf.m_X;
            }
            else
            {
                m_csTestInf.m_X = dTotalIn;
                m_csTestInf.m_Y = (m_csTestInf.m_dTtlLimit - m_csTestInf.m_dA * m_csTestInf.m_X) / m_csTestInf.m_dB;
                m_csTestInf.m_dOutDt = m_csTestInf.m_Y;
            }
            m_csTestInf.m_dTtlVal = m_csTestInf.m_X * m_csTestInf.m_Y;

            McLog.DebugOut(GetSimulationTime(), GetID(), "McCnvElmDebugTestModel", "Calculate",
                 "(" + m_csTestInf.m_sObjID + ")m_dTtlVal=" + m_csTestInf.m_dTtlVal.ToString());

            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)
        {
            HySCellData[] csSndDt = null;
            for (long lP = 0; lP < m_lOutputDataNum; lP++)
            {
                csSndDt = csOutputCellData[lP].PrepareSendCellD1();
                csSndDt[0].m_dData[0] = m_csTestInf.m_dOutDt;

                McLog.DebugOut(this.m_csSimTime, GetID(), "McCnvElmDebugTestModel", "DataFusion", "(" + m_csTestInf.m_sObjID + ")m_dData=" + m_csTestInf.m_dOutDt.ToString());
            }
            return 0;
        }


        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetProperty(csCellMdlPropertyInfo)</para>
        /// </example>
        /// <param name="csCellMdlPropertyInfo">セル型プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SetProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            m_csTestInf = (McCnvElmSampleTestCalInfo)m_csCalInfo;

            McModelPropertyInfo csInDt = csCellMdlPropertyInfo as McModelPropertyInfo;
            if (csInDt != null)
            {
                this.m_csDltTime = new HySTime(csInDt.GetStepTime());
                csInDt.GetInfo("m_sObjID", ref m_csTestInf.m_sObjID);
                csInDt.GetInfo("m_dA", ref m_csTestInf.m_dA);
                csInDt.GetInfo("m_dB", ref m_csTestInf.m_dB);
                csInDt.GetInfo("m_dTtlLimit", ref m_csTestInf.m_dTtlLimit);
            }

            return true;
        }
 

    }
}
