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

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;

using CommonMP.HYSSOP.Interface.HSData;
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.CoreOptionl.HymcoModelDLLWrapper;

using CommonMP.HYMCO._SYSTEM_;


namespace CommonMP.HYMCO._SYSTEM_
{
    /// <summary><para>class outline:</para>
    /// <para>ＨＹＭＣＯモデルファクトリ生成</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.3.0][2011/04/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.Hymco32FortranWrapp.Mc32BitFortranWrapperFactory();
        }
    }
}

namespace CommonMP.HYMCO.OptionImpl.Hymco32FortranWrapp
{
    /// <summary><para>class outline:</para>
    /// <para>サンプルモデルファクトリクラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.3.0][2011/04/01][新規作成]</para>
    /// </remarks>
    public class Mc32BitFortranWrapperFactory : McBasicModelFactoryBase
    {
        /// <summary> モデル情報ハッシュ管理 </summary>
        public static HySDataHashTable m_csFortranMdlInfoTable = new HySDataHashTable();

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

        }

        /// <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 Mc32BitFortranWrapperDef.FORTRAN_WRAPPER_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)
        {
            return new Mc32BitFortranWrapperModel();
        }

        /// <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)
        {
             return new Mc32BitWrapperCalInfo();
        }

        /// <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;
            }
            // csModelKind　から　m_csFortranMdlInfoTable内の対応するMcFortranModelInfo情報を取得する
            // 取得したMcFortranModelInfoの情報を元にMcFortranModelPropertyInfoに値を設定する

            McCellModelPropertyInfo csRtnCellPrptyDt = null;
            Mc32BitFortranModelInfo csFortranMdlInfo = m_csFortranMdlInfoTable.GetObject((HySString)csModelKind.GetString()) as Mc32BitFortranModelInfo;
            if (csFortranMdlInfo != null)
            {
                csRtnCellPrptyDt = csFortranMdlInfo.GetModelProperty().Clone() as McCellModelPropertyInfo;
            }

            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;
            }
            // csModelKind　から　m_csFortranMdlInfoTable内の対応するMcFortranModelInfo情報を取得する
            // 取得したMcFortranModelInfoの情報を元にMcFortranModelPropertyInfoに値を設定する

            McInitialInfo csRtnDt = new Mc32BitFortranModelInitialData(csLibraryID,csModelKind); 
            Mc32BitFortranModelInfo csFortranMdlInfo = m_csFortranMdlInfoTable.GetObject((HySString)csModelKind.GetString()) as Mc32BitFortranModelInfo;
            if (csFortranMdlInfo != null)
            {
                csRtnDt = csFortranMdlInfo.GetModelInitialInfo().Clone() as McInitialInfo;
            }

            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()
        {
            this.ImportFortranModelInfo();

            McModelInfo csModelInfo=null;
            Mc32BitFortranModelInfo csFortranMdlInfo = null;
            HySString   csMdlID = null;

            // m_csFortranMdlInfoTable内のMcFortranModelInfo情報を一つずつ調べて、
            // その内容を元に　リストに　csModelInfoを追加する。
            HySDataLinkedList csKeyList = m_csFortranMdlInfoTable.GetKeyList();

            if (csKeyList != null)
            {

                long lMdlNum = csKeyList.GetCount();
                for (long lLp = 0; lLp < lMdlNum; lLp++)
                {
                    csMdlID = csKeyList.GetData(lLp) as HySString;

                    csFortranMdlInfo = m_csFortranMdlInfoTable.GetObject(csMdlID) as Mc32BitFortranModelInfo;
                    if (csFortranMdlInfo != null)
                    {
                        csModelInfo = csFortranMdlInfo.CreateModelInfo();
                        m_csCalModelInforList.AddLast(csModelInfo);
                    }
                }
            }

            return m_csCalModelInforList;
        }


        /// <summary><para>method outline:</para>
        /// <para>Fortran要素モデル情報の取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> ImportFortranModelInfo( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual void ImportFortranModelInfo()
        {
            m_csFortranMdlInfoTable.ClearAllObject();

            // 所定のディレクトリ内の全てのFortranモデル情報を調べて　情報をm_csFortranMdlInfoTableに格納する
            //HySString csFortranMdlInfoDir = HySEnvInf.GetEnvInf(Mc32BitFortranWrapperDef.FORTRAN_MODEL_INF_FOLDER); // フォートランモデル情報格納ディレクトリを取得
            Assembly csEntryAssembly = Assembly.GetEntryAssembly();
            string sPathName = csEntryAssembly.Location;
            DirectoryInfo csInfo = Directory.GetParent(sPathName);
            string sPath = csInfo.ToString();

            HySString csDllFolder = HySEnvInf.GetEnvInf(Mc32BitFortranModelDLLImport.ENVINF_KEY_FORTRAN_MODEL_DLL_FOLDER);
            if (((object)csDllFolder) == null) { csDllFolder = new HySString(@"\FortranModelDll\"); }
            string csMdlInfoXMLFilePath = sPath + csDllFolder.ToString();           // ＤＬＬ名称

            string[] sFiles = Directory.GetFiles(csMdlInfoXMLFilePath);
            for (int iLoop = 0; iLoop < sFiles.Length; iLoop++)
            {
                string sFile = sFiles[iLoop];
                string sCut = sFile.Substring(sFile.Length - 3);
                if (sCut.Equals("xml") == true)
                {
                    Mc32BitFortranModelInfo csFortranMdlInfo = new Mc32BitFortranModelInfo();
                    csFortranMdlInfo.XmlIN(sFile);
                    string sXMLFileName = sFile.Substring(csMdlInfoXMLFilePath.Length);
                    csFortranMdlInfo.SetMdlInfoXMLFileName(new HySString(sXMLFileName));

                    m_csFortranMdlInfoTable.AddObject((HySString)csFortranMdlInfo.GetModelKind().GetString(), csFortranMdlInfo);
                }
            }
        }
    }
}
