using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

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

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

using CommonMP.HYMCO.CoreOptionl.HymcoExpansionModel;
using CommonMP.HYMCO.Ocean.McOceanBaseModel;

namespace CommonMP.HYMCO.Ocean.McOceanSampleModels
{
    /// <summary>
    /// CO2観測
    /// </summary>
    public class MzOcnResearchCO2 : MzOcnECHmnAction
    {
        /// <summary> 演算データ（キャスト用） </summary>
        protected MzOcnResearchCO2CalInfo m_csRschCO2Inf = null; // 便利の為、キャスト用に定義しておく

        // CO2調査
        protected McPatternRdvSndTranInfoPair m_csRcvResearchCO2Cnnct = new McPatternRdvSndTranInfoPair();
        protected McPatternRdvSndTranInfoPair m_csSndResearchCO2Cnnct = new McPatternRdvSndTranInfoPair();

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

        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = CheckReceiveDataConnection(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 CheckReceiveDataConnection(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            // チェック処理を入れる
            bool bRtn = base.CheckReceiveDataConnection(ref csErrorInf, lInputDataNum, csInputCellData);

            // CO2吸収調査結果
            m_csRcvResearchCO2Cnnct = this.PrepareRcvPattern(MzOceanBaseDefine.RESEARCH_CO2_ABSORPTION);
            m_csSndResearchCO2Cnnct = this.PrepareSndPattern(MzOceanBaseDefine.RESEARCH_CO2_ABSORPTION);

            // ディバッグ用送信データ
            m_csDebugSendCnnct = this.PrepareSndPattern(MzOceanBaseDefine.DEBUG_OUT);
            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)
        {
            bool bRtn = base.Initialize(ref csInitialData, lInputDataNum, ref csInputCellData);
            McInitialInfo csInDt = csInitialData as McInitialInfo;
            if (csInDt != null)
            {   // 初期化情報有り
            }
            return true;
        }
  
        //=======================
        // 演算実行処理関連メソッド
        //=======================

        /// <summary>
        /// 受信
        /// </summary>
        protected override void ReceiveData()
        {
            base.ReceiveData();
            ReceiveResearchCO2();
            return;
        }
        /// <summary>
        /// 送信例
        /// </summary>
        protected override void SendData()
        {
            SendDEBUG();
            base.SendData();
            SendResearchCO2();
            return;
        }

        /// <summary>
        ///　CO2調査
        /// </summary>
        protected virtual void ReceiveResearchCO2()
        {
            m_csRschCO2Inf.m_meanCO2Absorption = 0;
            m_csRschCO2Inf.m_meanCO2Emission = 0;
            m_csRschCO2Inf.m_meanO2Emission = 0.0;
            for (int i = 0; i < m_csRcvResearchCO2Cnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csCell = m_csRcvResearchCO2Cnnct.m_csRcvInfArry[i].GetInterpolatedCellD1();
                if (csCell != null)
                {
                    // CO2
                    m_csRschCO2Inf.m_meanCO2Absorption += csCell[0].m_dData[0];
                    m_csRschCO2Inf.m_meanCO2Emission += csCell[0].m_dData[1];
                    // O2
                    m_csRschCO2Inf.m_meanO2Emission += csCell[0].m_dData[2];
                }
            }
        }
        protected virtual void SendResearchCO2()
        {
            for (int i = 0; i < m_csSndResearchCO2Cnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csSndDt = m_csSndResearchCO2Cnnct.m_csSndInfArry[i].PrepareSendCellD1();
                if (csSndDt == null) { break; }

                csSndDt[0].m_dData[0] = m_csRschCO2Inf.m_meanCO2Absorption;
                csSndDt[0].m_dData[1] = m_csRschCO2Inf.m_meanCO2Emission;
                csSndDt[0].m_dData[2] = m_csRschCO2Inf.m_meanO2Emission;
            }
        }
        /// <summary>
        /// ディバッグ出力
        /// </summary>
        protected override void SendDEBUG()
        {
            for (int i = 0; i < m_csDebugSendCnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csCell = m_csDebugSendCnnct.m_csSndInfArry[i].PrepareSendCellD1();

                csCell[0].m_dData[0] = m_csRschCO2Inf.m_meanCO2Emission;
                csCell[0].m_dData[1] = m_csRschCO2Inf.m_meanCO2Absorption;
                csCell[0].m_dData[2] = m_csRschCO2Inf.m_meanO2Emission;
                csCell[0].m_dData[3] = m_csRschCO2Inf.m_Chash;
                csCell[0].m_dData[4] = m_csRschCO2Inf.m_NonMaterial_Val;
                csCell[0].m_dData[5] = m_csRschCO2Inf.m_OrdersPlaced;
                csCell[0].m_dData[6] = m_csRschCO2Inf.m_Payment;
                csCell[0].m_dData[7] = m_csRschCO2Inf.m_Claimed;
                csCell[0].m_dData[8] = m_csRschCO2Inf.m_EstimatedCost;
            }
        }

        ///// <summary>
        ///// 人間の行為
        ///// </summary>
        ///// <returns></returns>
        //protected override long HumanAction()
        //{
        //    //double dT = m_csDltTime.GetTime() / (3600.0 * 24.0);
        //    double dACT_Day = m_csOcCashInf.m_HmnActTimeSpan / (3600.0 * 24.0);

        //    //m_csOcCashInf.m_EstimatedCost の計算がされていない
        //    //利益や、変動コストを計算していない
        //    // コストを引く
        //    double dDriftCost = m_csOcCashInf.m_Payment * 0.9;  // 仮
        //    m_csOcCashInf.CalConstCost(dACT_Day, dDriftCost);

        //    // 売り手側の計算
        //    m_csOcCashInf.SellerCalClaimedPayment();

        //    //SendDEBUG();
        //    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)
        {
            base.SetProperty(csCellMdlPropertyInfo);

            // 使用しやすいようにキャストしておく
            m_csRschCO2Inf = (MzOcnResearchCO2CalInfo)m_csCalInfo;

            // プロパティ設定
            McCellModelPropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McCellModelPropertyInfo;
            if (csPrptyInfo != null)
            {
            }
            return true;
        }
    }
}
