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._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.CoreOptionl.HymcoExpansionModel.McExpansionModelFactory();
        }

    }

}


namespace CommonMP.HYMCO.CoreOptionl.HymcoExpansionModel
{
    /// <summary><para>class outline:</para>
    /// <para>モデルファクトリクラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[2021/12/31][新規作成]</para>
    /// </remarks>
    public class McExpansionModelFactory : McBasicModelFactoryBase
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="LibIDo"></param>
        /// <param name="CnnctID"></param>
        /// <param name="CnnctTypeKind"></param>
        /// <param name="sName"></param>
        /// <param name="DownName"></param>
        /// <param name="UpName"></param>
        /// <returns></returns>
        static public McMutualTranInfoPattern CreateMutualTranInfo(
            string sCnnctLabelName ,
            HySID CnnctID,
            HySObjectKind CnnctTypeKind,
            string DownLabelName ,
            string UpLabelName )
        {
            McMutualTranInfoPattern csMutualTrnPtn = null;
            McTranInfoPattern csDownTrnPtn = null;
            McTranInfoPattern csUppTrnPtn = null;

           HySID csFwdObjID = new HySID("F)_" + CnnctID.ToString());
            HySID csBckObjID = new HySID("B)_" + CnnctID.ToString());

            if (CnnctTypeKind == McTranInfoDefine.MUTUAL_SINGLE_TRAN_SERIAL)
            {             /// <summary>相互結合要素間伝送データ</summary>
                csMutualTrnPtn = new McMutualTranInfoPattern(CnnctID, CnnctTypeKind, sCnnctLabelName);

            }
            else if (CnnctTypeKind == McTranInfoDefine.MUTUAL_D1_TRAN_SERIAL)
            {            /// <summary>相互結合要素間伝送データ</summary>
                csMutualTrnPtn = new McMutualTranInfoPattern(CnnctID, CnnctTypeKind, sCnnctLabelName);
                // Downstream
                csDownTrnPtn = new McTranInfoPattern(csFwdObjID, McTranInfoDefine.D1_CELL_SERIAL, DownLabelName);
                // Upstream
                csUppTrnPtn = new McTranInfoPattern(csBckObjID, McTranInfoDefine.D1_CELL_SERIAL, UpLabelName);
            }
            else if (CnnctTypeKind == McTranInfoDefine.MUTUAL_D2_TRAN_SERIAL)
            {            /// <summary>相互結合要素間伝送データ</summary>
                csMutualTrnPtn = new McMutualTranInfoPattern(CnnctID, CnnctTypeKind, sCnnctLabelName);

            }
            else if (CnnctTypeKind == McTranInfoDefine.MUTUAL_D3_TRAN_SERIAL)
            {            /// <summary>相互結合要素間伝送データ</summary>
                csMutualTrnPtn = new McMutualTranInfoPattern(CnnctID, CnnctTypeKind, sCnnctLabelName);

            }

            // ----------------
            if(csDownTrnPtn != null)
            {
                csDownTrnPtn.SetInterpolateType(HySDefine.InterpolateType.LINEAR); // 内挿方法設定
                csMutualTrnPtn.SetDownTranInfoPattern(csDownTrnPtn);

            }
            if(csUppTrnPtn != null)
            {
                csMutualTrnPtn.SetUpTranInfoPattern(csUppTrnPtn);
                csUppTrnPtn.SetInterpolateType(HySDefine.InterpolateType.LINEAR); // 内挿方法設定

            }
            //---------------------
            /*
                    {
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csDownTrnPtn.CreateCellDataCharacteristic(4);
                        {
                            csCellChara.SetDataKind(0, "捕食した有機物", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "t"); // ｇ/(立方ｍ)
                            csCellChara.SetDataKind(1, "捕食した有機物中の炭素量", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "t"); // ｇ/(立方ｍ)
                            csCellChara.SetDataKind(2, "捕食した無機物", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "t"); // ｇ/(立方ｍ)
                            csCellChara.SetDataKind(3, "現在の全有機物量", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "t"); // ｇ/(立方ｍ)
                        }
                        csDownTrnPtn.SetCellDataCharacteristic(csCellChara);
                        
                    }

                    {
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csUppTrnPtn.CreateCellDataCharacteristic(1);
                        {
                            csCellChara.SetDataKind(0, "要求する有機物量", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "t"); // ｇ/(立方ｍ)
                        }
                        csUppTrnPtn.SetCellDataCharacteristic(csCellChara);
                    }
            */
            return csMutualTrnPtn;
        }

        /// <summary>
        /// 相互伝送情報内の順方向／逆方向の伝送かを判断
        /// </summary>
        /// <param name="csTrnPtn"></param>
        /// <returns> ==-1:相互伝送の親、 == 1:相互伝送内の順方向、== 2:相互伝送内の逆方向、 ==0:単独伝送</returns>
        static public int CheckMutualElmTran(McTranInfoPattern csTrnPtn)
        {
            int iRtn = 0;
            if (csTrnPtn != null)
            {
                if (csTrnPtn is McMutualTranInfoPattern)
                {
                    iRtn = -1;
                }
                else
                {
                    string sPtnID = csTrnPtn.GetPatternID().ToString();
                    string prFix = sPtnID.Substring(0, 3);
                    if (prFix == "F)_") { iRtn = 1; }
                    else if (prFix == "B)_") { iRtn = 2; }
                }
            }
            else
            {
                iRtn = - 99;
            }
            return iRtn;
        }

        /// <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 McExpansionModelFactory()
        {
            McStructErrorInfo csChkInf = new McStructCheckData();
        }

        /// <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()
        {
            return McExpansionModelDefine.EXPANSION_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 == McOceanBaseDefine.NEKTONS_KIND)
            {
                csCalModel = new MzOceanNektons();
            }
            else if (csModelKind == McOceanBaseDefine.HUMAN_ACTION_KIND)
            {
                csCalModel = new MzOceanHumanAct();
            }
            */
            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 == McOceanBaseDefine.NEKTONS_KIND)
            {
                csCalInfoData = new MzOceanNektonsCalInfo();
            }
            else if (csModelKind == McOceanBaseDefine.HUMAN_ACTION_KIND)
            {
                csCalInfoData = new MzOceanHumanActCalInfo();
            }
            */
            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 = null;
            /*
            if (csModelKind == McOceanBaseDefine.InO_PARTICULATES_KIND)
            {   // 粒子状無機物（Inorganic_Particulates_Mdl）クラス
                csRtnCellPrptyDt = new McCellModelPropertyInfo(csLibraryID, csModelKind);

                csRtnCellPrptyDt.SetStepTime((double)4 * 3600); // δT設定　sec ＝４時間

                csRtnCellPrptyDt.AddInfoType("m_lCelNumber", "モデル内鉛直方向 セル分割数", McDefine.ValKind.LONG);
                csRtnCellPrptyDt.SetInfo("m_lCelNumber", 5);
                csRtnCellPrptyDt.AddInfoType("m_dLength", "海洋震度 [m]", McDefine.ValKind.LONG);
                csRtnCellPrptyDt.SetInfo("m_dLength", 6000);
                csRtnCellPrptyDt.AddInfoType("m_dFace", "セルの広さ[Km2]", McDefine.ValKind.LONG);
                csRtnCellPrptyDt.SetInfo("m_dFace", 20 * 20);

                // 受信可能なパターン
                {
                    // 腐敗・消化 
                    McTranInfoPattern csTrnPtn = McFlowObjFactory.CreateFlow(McOceanBaseDefine.DECOMPOSE, csModelKind);
                    csRtnCellPrptyDt.AddReceivePattern(csTrnPtn);  // 受信可能パターンの追加
                }
                // 送信パターンの設定
                {
                    //  
                    McTranInfoPattern csTrnPtn = McFlowObjFactory.CreateFlow(McOceanBaseDefine.PREDATION, csModelKind);
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn);    // 送信可能パターンの追加                                                                  

                    // 海洋肥料
                    csTrnPtn = McFlowObjFactory.CreateFlow(McOceanBaseDefine.FERTILIZER, csModelKind);
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn);    // 送信可能パターンの追加
                }
            }
            */
            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 == McOceanBaseDefine.NEKTONS_KIND)
            {
                csRtnDt = new McInitialInfo(csLibraryID, csModelKind);

                //csRtnDt.AddInfoType("H_Initial", "初期水位", McDefine.ValKind.DOUBLE);
                //csRtnDt.SetInfo("H_Initial", 1.0);
            }
            else if (csModelKind == McOceanBaseDefine.HUMAN_ACTION_KIND)
            {
                csRtnDt = new McInitialInfo(csLibraryID, csModelKind);
            }
            */
            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>タグ内のＩＤに対応します。 
                    McOceanBaseDefine.NEKTONS_KIND, // モデルの識別子
                    McOceanBaseDefine.NEKTONS_NAME  // モデルの名称
                                           );
            csModelInfo.SetVersionInf("Ver1.0");
            csModelInfo.SetSummaryInf("ネクトン類（Nekton) （魚類含む）モデル");
            csModelInfo.SetCreatorInf("S.H.");
            csModelInfo.SetIconName(@"Ocean\Nekton2");
            csModelInfo.SetManualFileName(@".\Ocean\SampleModelExplanation.pdf"); // <-- モデル解説書

            //csModelInfo.SetLibraryDispMode(false);  // ライブラリーツリーは非表示
            m_csCalModelInforList.AddLast(csModelInfo);
            */
            //--
            return m_csCalModelInforList;
        }

    }    // end of class


}
