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.Interface.HSViewer;

using CommonMP.HYSSOP.CoreImpl;
using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;
using CommonMP.HYMCO.CoreImpl.Controller;
using CommonMP.HYMCO.Interface.Viewer;

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

using CommonMP.HYMCO.CoreImpl.Model;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYSSOP.CoreImpl.HSController;


using CommonMP.HYMCO.Ocean.McOceanBaseModel;

using CommonMP.HYMCO._SYSTEM_;

namespace CommonMP.HYMCO._SYSTEM_
{
    /// <summary><para>class outline:</para>
    /// <para>海洋モデルファクトリ生成</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][2021/12/31][新規作成]</para>
    /// </remarks>
    public class HYMCO_MODEL_FACTORY_CREATOR_IMPLE : HYMCO_MODEL_FACTORY_CREATOR
    {
        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HYMCO_MODEL_FACTORY_CREATOR_IMPLE csFactCrt = new HYMCO_MODEL_FACTORY_CREATOR_IMPLE( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HYMCO_MODEL_FACTORY_CREATOR_IMPLE()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>演算モデルファクトリクラス生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McModelFactory csCalModelFactory = CreateFactory( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>演算モデルファクトリクラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public CommonMP.HYMCO.Interface.Model.McModelFactory CreateFactory()
        {
            return new CommonMP.HYMCO.Ocean.McOceanModelTemplate.MzMyOceanSmplFactory();
        }
   
    }

}


namespace CommonMP.HYMCO.Ocean.McOceanModelTemplate
{

    /// <summary><para>class outline:</para>
    /// <para>モデルファクトリクラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[2021/12/31][新規作成]</para>
    /// </remarks>
    public class MzMyOceanSmplFactory : McBasicModelFactoryBase  // MzOceanModelBaseFactory
    {

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McSampleModelFactory csFactory = new McSampleModelFactory()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public MzMyOceanSmplFactory()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>ファクトリ識別子を生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySID csFactID = CreateFactoryID( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>ファクトリ識別子</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override HySID CreateFactoryID()
        {
            // ★　CommonMPで使用する全ファクトリーでユニークな名称とする
            return MzMyOceanDefine.OCEANBASE_TEMPLATE_MODEL_LIB;
        }

        /// <summary><para>method outline:</para>
        /// <para>演算モデルクラス生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McCalModel csCalModel = CreateCalModel(csModelKind) </para>
        /// </example>
        /// <param name="csModelKind">モデル種別識別子</param>
        /// <returns>演算モデルクラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McCalModel CreateCalModel(HySObjectKind csModelKind)
        {
            McCalModel csCalModel = null;

            // 引数で与えられたモデル種別識別子に対応するモデルを生成する
            if (csModelKind == MzMyOceanDefine.T_XXX_MODEL_KIND)
            {
                csCalModel = new MzOceanXXXMdl();
            }
            //else if (csModelKind == MzOceanBaseDefine.COPEPODS_KIND)
            //{
            //    csCalModel = new MzOceanCopepods();
            //}
            //else if (csModelKind == MzOceanBaseDefine.ZOOPLANKTONS_KIND)
            //{
            //    csCalModel = new MzOceanZpoplanktons();
            //}
            //--------------- 経済モデル ------------
            //else if (csModelKind == MzOceanBaseDefine.HUMAN_JPN_SOCIETY_KIND)
            //{
            //    csCalModel = new MzEcJapanSociety();
            //}
            ////--------------- ＣＳＶ出力モデル ------------
            //else if (csModelKind == MzOceanBaseDefine.DEBUG_CSV_OUT_KIND)
            //{
            //    csCalModel = new MzOceanOutCSV();
            //}
            return csCalModel;
        }

        /// <summary><para>method outline:</para>
        /// <para>要素内演算中データクラス生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McCalInfo csCalModel = CreateCalInfo( csModelKind ) </para>
        /// </example>
        /// <param name="csModelKind">モデル種別識別子</param>
        /// <returns>要素内演算中データクラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McCalInfo CreateCalInfo(HySObjectKind csModelKind)
        {
            McCalInfo csCalInfoData = null;

            // 引数で与えられたモデル種別識別子に対応する算中データを生成する
            if (csModelKind == MzMyOceanDefine.T_XXX_MODEL_KIND)
            {
                csCalInfoData = new MzOceanXXXMdlCalInfo();
            }
            //else if (csModelKind == MzOceanBaseDefine.COPEPODS_KIND)
            //{
            //    csCalInfoData = new MzOceanCopepodsCalInfo();
            //}
            //else if (csModelKind == MzOceanBaseDefine.ZOOPLANKTONS_KIND)
            //{
            //    csCalInfoData = new MzOceanZpoplanktonsCalInfo();
            //}
            ////--------------- 経済モデル ------------
            //else if (csModelKind == MzOceanBaseDefine.HUMAN_JPN_SOCIETY_KIND)
            //{
            //    csCalInfoData = new MzEcJapanSocietyCalInfo();
            //}
            ////--------------- ＣＳＶ出力モデル ------------
            //else if (csModelKind == MzOceanBaseDefine.DEBUG_CSV_OUT_KIND)
            //{
            //    csCalInfoData = new MzOceanOutCSVCalInfo();
            //}
            return csCalInfoData;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデルプロパティ表示／設定情報クラス生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McPropertyInfoRoot csPropertyInf = CreateModelPropertyInfo(csLibraryID, csModelKind ) </para>
        /// </example>
        /// <param name="csLibraryID">ライブラリー識別子</param>
        /// <param name="csModelKind">モデル種別識別子</param>
        /// <returns>モデルプロパティ表示／設定情報クラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McCellModelPropertyIF CreateModelProperty(HySID csLibraryID, HySObjectKind csModelKind)
        {
            if (this.EqualFactory(csLibraryID) == false)
            {
                return null;
            }

            McCellModelPropertyInfo csRtnCellPrptyDt = new McCellModelPropertyInfo(csLibraryID, csModelKind);
            //　共通設定:  計算　δT設定
            csRtnCellPrptyDt.SetStepTime((double)4 * 3600); // δT設定　sec ＝４時間

            // 引数で与えられたモデル種別識別子に対応するプロパティ値を設定する
            if (csModelKind == MzMyOceanDefine.T_XXX_MODEL_KIND)
            {   // 自作モデル

                //csRtnCellPrptyDt.AddInfoType("m_CapturedRatio", "捕まり易さ：確率", McDefine.ValKind.DOUBLE);
                //csRtnCellPrptyDt.SetInfo("m_CapturedRatio", 0.0025);

                //// 層設定
                //this.SetLayer(ref csRtnCellPrptyDt, 7, 6000); //, 10 * 10);
                // 受信可能なパターン
                {
                    /*
                    // 呼吸
                    McTranInfoPattern csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.BREATHING, csModelKind);
                    csRtnCellPrptyDt.AddReceivePattern(csTrnPtn);    // 受信可能パターンの追加

                    // 捕食
                    csTrnPtn = csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.PREDATION, csModelKind);
                    csRtnCellPrptyDt.AddReceivePattern(csTrnPtn);    // 受信可能パターンの追加
                    */
                }
                // 送信パターンの設定
                {
                    /*
                    // 被捕食(漁獲)
                    McTranInfoPattern csTrnPtn = csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.PREDATION, csModelKind);
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn);  // 送信可能パターンの追加

                    // 排泄 or 死
                    csTrnPtn = csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.EXCRETION_DEATH, csModelKind);
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn);    // 送信可能パターンの追加

                    // ===== start of for Debug =====
                    csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(MzOceanBaseDefine.DEBUG_OUT, McTranInfoDefine.D1_CELL_SERIAL, "ディバッグ情報出力") as McTranInfoPattern;
                    {
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(3);
                        {
                            csCellChara.SetDataKind(0, "m_TotalSelfMass", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "t/m3"); // ｇ/(立方ｍ)
                            csCellChara.SetDataKind(1, "O2", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "g/m3"); // ｇ/(立方ｍ)
                            csCellChara.SetDataKind(2, "CO2", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "g/m3"); // ｇ/(立方ｍ)
                        }
                        csTrnPtn.SetCellDataCharacteristic(csCellChara);
                        csTrnPtn.SetInterpolateType(HySDefine.InterpolateType.LINEAR); // 内挿方法設定
                    }
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn);    // 送信可能パターンの追加
                    // ===== end of for Debug =====
                    */
                }
            }
            //else if (csModelKind == MzOceanBaseDefine.COPEPODS_KIND)
            //{   // カイアシ類クラス
            //    // 層設定
            //    this.SetLayer(ref csRtnCellPrptyDt, 7, 6000); //, 10 * 10);
            //    // 代謝関係
            //    this.SetMetabolism(ref csRtnCellPrptyDt, 1.0, 0.02, 1.03, 0.1, 0.02, 1.03);
            //    this.SetMetabolism2(ref csRtnCellPrptyDt, 16E-3, 28E-3, 1.5);
            //    this.SetEexcretion(ref csRtnCellPrptyDt, 0.95, 0.1);
            //    csRtnCellPrptyDt.AddInfoType("m_CapturedRatio", "捕まり易さ：確率", McDefine.ValKind.DOUBLE);
            //    csRtnCellPrptyDt.SetInfo("m_CapturedRatio", 0.05);

            //    // 受信可能なパターン
            //    {
            //        // 呼吸
            //        McTranInfoPattern csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.BREATHING, csModelKind);
            //        csRtnCellPrptyDt.AddReceivePattern(csTrnPtn);    // 受信可能パターンの追加

            //        // 捕食
            //        csTrnPtn = csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.PREDATION, csModelKind);
            //        csRtnCellPrptyDt.AddReceivePattern(csTrnPtn);    // 受信可能パターンの追加
            //    }
            //    // 送信パターンの設定
            //    {
            //        // 被捕食
            //        McTranInfoPattern csTrnPtn = csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.PREDATION, csModelKind);
            //        csRtnCellPrptyDt.AddSendPattern(csTrnPtn);  // 送信可能パターンの追加

            //        // 排泄 or 死
            //        csTrnPtn = csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.EXCRETION_DEATH, csModelKind);
            //        csRtnCellPrptyDt.AddSendPattern(csTrnPtn);    // 送信可能パターンの追加

            //        // ===== start of for Debug =====
            //        csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(MzOceanBaseDefine.DEBUG_OUT, McTranInfoDefine.D1_CELL_SERIAL, "ディバッグ情報出力") as McTranInfoPattern;
            //        {
            //            // セル内変数設定
            //            HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(3);
            //            {
            //                csCellChara.SetDataKind(0, "m_TotalSelfMass", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "t/m3"); // ｇ/(立方ｍ)
            //                csCellChara.SetDataKind(1, "O2", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "g/m3"); // ｇ/(立方ｍ)
            //                csCellChara.SetDataKind(2, "CO2", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "g/m3"); // ｇ/(立方ｍ)
            //            }
            //            csTrnPtn.SetCellDataCharacteristic(csCellChara);
            //            csTrnPtn.SetInterpolateType(HySDefine.InterpolateType.LINEAR); // 内挿方法設定
            //        }
            //        csRtnCellPrptyDt.AddSendPattern(csTrnPtn);    // 送信可能パターンの追加
            //        // ===== end of for Debug =====
            //    }
            //}
            //else
            //{
            //    csRtnCellPrptyDt = null;
            //}

            return csRtnCellPrptyDt;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル初期化表示／設定情報生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McPropertyInfoRoot csInitialInf = CreateModelInitialInfo(csLibraryID, csModelKind ) </para>
        /// </example>
        /// <param name="csLibraryID">ライブラリー識別子</param>
        /// <param name="csModelKind">モデル種別識別子</param>
        /// <returns>初期情報クラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McPropertyInfoRoot CreateModelInitialInfo(HySID csLibraryID, HySObjectKind csModelKind)
        {
            if (this.EqualFactory(csLibraryID) == false)
            {
                return null;
            }

            McInitialInfo csRtnDt = null;

            // 引数で与えられたモデル種別識別子に対応する初期設定値を設定する
            if (csModelKind == MzMyOceanDefine.T_XXX_MODEL_KIND)
            {   // 自作モデル
                csRtnDt = new McInitialInfo(csLibraryID, csModelKind);
            }
            //else if (csModelKind == MzOceanBaseDefine.COPEPODS_KIND)
            //{
            //    csRtnDt = new McInitialInfo(csLibraryID, csModelKind);
            //    this.SetInitMass(ref csRtnDt, 1, 1, 1, 1, 1, 1, 1);
            //}
            //else
            //{ }
            return csRtnDt;
        }


        /// <summary><para>method outline:</para>
        /// <para>モデル情報提供：ライブラリ管理画面へ表示する情報のリストを作成する</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>HySDataLinkedList csModelInfoList = GetCalModelInfoList();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>モデル情報のリスト</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>モデル情報(McModelInfo)をリスト形式で返却する</para>
        /// </remarks>
        public override HySDataLinkedList GetCalModelInfoList()
        {
            McModelInfo csModelInfo = null;

            // ライブラリ管理画面へ表示する情報のリストを作成する

            csModelInfo = new McModelInfo(
                    (HySID)this.GetFactoryID(),
                    McModelLibraryDefine.DIVISION_CALCULATION_MODEL, // <-- 演算モデルは、必ずこの値にして下さい（LibraryCategoryXML.xmlに記述されている）
                    new HySObjectKind("CAL_OCEAN_MODELS"), // LibraryCategoryXML.xmlに記述されている <Category>タグ内のＩＤに対応します。 
                    MzMyOceanDefine.T_XXX_MODEL_KIND, // LibraryCategoryXML.xmlに記述されている <Category>タグ内のＩＤに対応します。 
                    MzMyOceanDefine.T_XXX_MODEL_NAME  // モデルの識別子
                                           );
            csModelInfo.SetVersionInf("Ver1.0");
            csModelInfo.SetSummaryInf("型紙：簡単な解説");
            csModelInfo.SetCreatorInf("制作者名");
            csModelInfo.SetIconName(@"Ocean\Nekton02");  // アイコン名
            csModelInfo.SetManualFileName(@".\Ocean\SampleModelExplanation.pdf"); // <-- モデル詳細解説書PDF

            //m_csCalModelInforList.AddLast(csModelInfo);   // <-- リリース時には、このコメントを外す（ライブラリ寛喜画面に表示する）


            // ―――　別のモデル　―――
            //csModelInfo = new McModelInfo(
            //            (HySID)this.GetFactoryID(),
            //            McModelLibraryDefine.DIVISION_CALCULATION_MODEL, // <-- 演算モデルは、必ずこの値にして下さい（LibraryCategoryXML.xmlに記述されている）
            //            new HySObjectKind("CAL_OCEAN_MODELS"), // LibraryCategoryXML.xmlに記述されている <Category>タグ内のＩＤに対応します。 
            //            MzOceanBaseDefine.COPEPODS_KIND, // モデルの識別子
            //            MzOceanBaseDefine.COPEPODS_NAME  // モデルの名称
            //                     );

            //csModelInfo.SetVersionInf("Ver1.0");
            //csModelInfo.SetSummaryInf("カイアシ類（Copepods)  動物プランクトンの一種");
            //csModelInfo.SetCreatorInf("S.H.");
            //csModelInfo.SetIconName(@"Ocean\Copepods");
            //csModelInfo.SetManualFileName(@".\Ocean\SampleModelExplanation.pdf"); // <-- モデル解説書

            //m_csCalModelInforList.AddLast(csModelInfo);

            // ―――　――――――　―――
            return m_csCalModelInforList;
        }
  
    }    // end of class

}
