// <summary>ソースコード：ＨＹＭＣＯサンプルモデルファクトリクラス</summary>
// <author>CommonMP</author>

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

using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.Interface.HSViewer;
using CommonMP.HYSSOP.CoreImpl;
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.Model;
using CommonMP.HYMCO.CoreImpl.Data;

using CommonMP.HYMCO._SYSTEM_;

namespace CommonMP.HYMCO._SYSTEM_
{
    /// <summary><para>class outline:</para>
    /// <para>ＨＹＭＣＯモデルファクトリ生成</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/10/01][新規作成]</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.OptionImpl.McConvergenceSample.McConvergenceModelFactory();
        }
    }
}

// ToDo namespace は　モデル開発者が変更して、ユニークな名称にして下さい
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 McConvergenceModelFactory : McBasicModelFactoryBase
    {
        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McConvergenceModelFactory csFactory = new McConvergenceModelFactory()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McConvergenceModelFactory( )
        {
        }

        /// <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 McConvergenceSampleDefine.SAMPLE_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 == McConvergenceSampleDefine.TEST_CNV_ELM_MODEL)
            {
                csCalModel = new McCnvElmSampleTestModel();
            }
            else if (csModelKind == McConvergenceSampleDefine.TEST_CONVERGENCE_KIND)
            {
                csCalModel = new McSampleCnvrgncIteration();
            }
            else
            {
            }
            
            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 == McConvergenceSampleDefine.TEST_CNV_ELM_MODEL)
            {
                csCalInfoData = new McCnvElmSampleTestCalInfo();
            }
            else if (csModelKind == McConvergenceSampleDefine.TEST_CONVERGENCE_KIND)
            {
                csCalInfoData = new McSampleCnvrgncIterationCalInfo();
            }
            else
            {
            }

            return csCalInfoData;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデルプロパティ表示／設定情報クラス生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McModelPropertyInfoRoot 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 McPropertyInfoRoot CreateModelPropertyInfo(HySID csLibraryID, HySObjectKind csModelKind)
        {
            if (this.EqualFactory(csLibraryID) == false)
            {
                return null;
            }
            McPropertyInfoRoot csRtnDt = null;
            if (csModelKind == McConvergenceSampleDefine.TEST_CONVERGENCE_KIND)
            {   // 収束演算Grのプロパティは　通常のモデルのプロパティとは異なる
                csRtnDt = new McGroupPropertyInfo(csLibraryID, csModelKind);
                //csRtnDt = new McModelPropertyInfo(csLibraryID, csModelKind);
                /*
                csRtnDt.AddInfoType("m_dDltStp", "変数増分値", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("m_dDltStp", 1.0);
                csRtnDt.AddInfoType("m_dEps", "収束判別条件値", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("m_dEps", 0.0001);
                */
                ((McPropertyInfo)csRtnDt).AddInfoType("m_dMaxVal", "最小値", McDefine.ValKind.DOUBLE);
                ((McPropertyInfo)csRtnDt).SetInfo("m_dMaxVal", -9.0E32);
            }
            else
            {   // 通常のモデル
                csRtnDt = this.CreateModelProperty(csLibraryID, csModelKind);
            }
            return csRtnDt;
        }

        /// <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 == McConvergenceSampleDefine.TEST_CNV_ELM_MODEL)
            {
                csRtnCellPrptyDt = new McCellModelPropertyInfo(csLibraryID, csModelKind);
                csRtnCellPrptyDt.SetStepTime(60.0); // δT設定

                csRtnCellPrptyDt.AddInfoType("m_sObjID", "Who are you? (X or Y)", McDefine.ValKind.STRING);
                csRtnCellPrptyDt.SetInfo("m_sObjID", "X");

                csRtnCellPrptyDt.AddInfoType("m_dA", "係数：A", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("m_dA", 100.0);
                csRtnCellPrptyDt.AddInfoType("m_dB", "係数：B", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("m_dB", 100.0);

                csRtnCellPrptyDt.AddInfoType("m_dTtlLimit", "制限値", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("m_dTtlLimit", 1000.0);

                // 受信可能なパターン
                {
                    // 第１パターン
                    McTranInfoPattern csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(
                        new HySID("入力"),
                        McTranInfoDefine.SINGLE_CELL_SERIAL,
                        "入力") as McTranInfoPattern;
                    {
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(1);
                        {
                            csCellChara.SetDataKind(0, "入力値", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "無次元"); // 最初の変数は流量
                        }
                        csTrnPtn.SetCellDataCharacteristic(csCellChara);
                        csTrnPtn.SetInterpolateType(HySDefine.InterpolateType.LINEAR); // 内挿方法設定
                    }
                    csRtnCellPrptyDt.AddReceivePattern(csTrnPtn);    // 受信可能パターンの追加
                    // 第２パターン
                    csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(
                        new HySID("非時系列入力"),
                        McTranInfoDefine.D1_CELL,
                        "入力") as McTranInfoPattern;
                    {
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(1);
                        {
                            csCellChara.SetDataKind(0, "入力値", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "無次元"); // 最初の変数は流量
                        }
                        csTrnPtn.SetCellDataCharacteristic(csCellChara);
                        csTrnPtn.SetInterpolateType(HySDefine.InterpolateType.LINEAR); // 内挿方法設定
                    }
                    csRtnCellPrptyDt.AddReceivePattern(csTrnPtn);    // 受信可能パターンの追加
                }
                // 送信パターンの設定
                {
                    // 第１パターン
                    McTranInfoPattern csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(
                        new HySID("出力"),
                        McTranInfoDefine.SINGLE_CELL_SERIAL,
                        "出力") as McTranInfoPattern;
                    {
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(1);
                        {
                            csCellChara.SetDataKind(0, "出力値", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "無次元");
                        }
                        csTrnPtn.SetCellDataCharacteristic(csCellChara);
                    }
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn);
                    // 第２パターン
                    csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(
                        new HySID("非時系列出力"),
                        McTranInfoDefine.D1_CELL,
                        "出力") as McTranInfoPattern;
                    {
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(1);
                        {
                            csCellChara.SetDataKind(0, "出力値", HySDataCharacteristicInCell.DATA_KIND.ANY_VALUE, "無次元");
                        }
                        csTrnPtn.SetCellDataCharacteristic(csCellChara);
                    }
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn);
                }
            }
            else
            {
                // Do nothing
            }

            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 == McConvergenceSampleDefine.TEST_CNV_ELM_MODEL)
            {
                csRtnDt = new McInitialInfo(csLibraryID, csModelKind);

                csRtnDt.AddInfoType("m_dOutDt", "初期値", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("m_dOutDt", 0.5);
                //csRtnDt.AddInfoType("m_dTtlLimit", "総量制限値", McDefine.ValKind.DOUBLE);
                //csRtnDt.SetInfo("m_dTtlLimit", 1000.0 / 1.2);
            }

            else if (csModelKind == McConvergenceSampleDefine.TEST_CONVERGENCE_KIND)
            {
                csRtnDt = new McInitialInfo(csLibraryID, csModelKind);

                csRtnDt.AddInfoType("m_dDltStp", "変数増分値", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("m_dDltStp", 1.0);
                csRtnDt.AddInfoType("m_dEps", "収束判別条件値", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("m_dEps", 0.0001);

            }
            else
            {
                // Do Nothing
            }

            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に記述されている）
                    McModelLibraryDefine.MODEL_CLASSIFICATION_CAL_MODEL_SAMPLE,
                    McConvergenceSampleDefine.TEST_CNV_ELM_MODEL,
                    McConvergenceSampleDefine.TEST_CNV_ELM_MODEL_NAME);
            csModelInfo.SetVersionInf("Ver0.1");
            csModelInfo.SetSummaryInf("収束演算確認用に使用するサンプル要素です。単なる数値を扱っているのみで物理的意味はありません。");
            csModelInfo.SetCreatorInf("CommonMP　モデル開発者");
            csModelInfo.SetIconName("DefaultModel");
            csModelInfo.SetManualFileName(".\\Sample\\McConvergenceSample.pdf");
            m_csCalModelInforList.AddLast(csModelInfo);

            csModelInfo = new McModelInfo(
                    (HySID)this.GetFactoryID(),
                    McModelLibraryDefine.MODEL_CLASSIFICATION_CAL_MODEL_CTL,
                    McConvergenceSampleDefine.TEST_CONVERGENCE_KIND,
                    McConvergenceSampleDefine.TEST_CONVERGENCE_NAME,
                    McDefine.MODEL_TYPE_GROUP);
            csModelInfo.SetVersionInf("Ver0.1");
            csModelInfo.SetSummaryInf("収束演算制御制御確認用　サンプル制御モデル　　ａＸ＋ｂＹ＝Ｃの条件の元で　ＸＹ＝αが最大となるＸ，Ｙを求める");
            csModelInfo.SetCreatorInf("CommonMP　モデル開発者");
            csModelInfo.SetManualFileName(".\\Sample\\McConvergenceSample.pdf");
            csModelInfo.SetIconName("DefaultModel");
            m_csCalModelInforList.AddLast(csModelInfo);

            return m_csCalModelInforList;
        }

    }
}
