// <summary>定義データ作成クラス</summary>
// <author>CommonMP</author>

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

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


namespace CommonMP.HYSSOP.CoreImpl.HSController.DIContainer
{
    /// <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 HySConfigDataMaker : HySRoot
    {
        /// <summary>ファクトリ管理</summary>
        protected HySFactoryManager m_csFactoryMng;

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

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySConfigDataMaker csDataMaker = new HySConfigDataMaker(csFactoryMng)</para>
        /// </example>
        /// <param name="csFactoryMng">ファクトリ管理</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySConfigDataMaker(HySFactoryManager csFactoryMng)
        {
            m_csFactoryMng = csFactoryMng;
        }

        /// <summary><para>method outline:</para>
        /// <para>ファクトリクラス生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>MakeFactoryClass(csConfigData)</para>
        /// </example>
        /// <param name="csConfigData">定義データ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void MakeFactoryClass(HySConfigData csConfigData)
        {
            Assembly csAssembly = null; // アセンブリ
            Module csModule = null;     // モジュール
            Type csType = null;         // モジュールタイプ
            String csKey;               // データ取り込み用キー
            String csDllName;           // ＤＬＬ名称
            String csKindName;          // クラス種別
            String csPackageName;       // パッケージ名称
            String csClassName;         // クラス名称
            long lLoop;                 // ループカウンタ
            HySID csID;                 // データ識別子
            HySString csKind;           // 種別
            HySString csGroup;          // グループ
            HySString csUniqueKey;      // ユニークキー

            HySFactory csFactory=null;       // ファクトリクラス
            string DispStatement = "";  // ver1.5 エラートレース日本語対応

            //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
            // Ver1.3では下記コードを追加する（diconファイルへの登録不要化） 
            //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
            // diconにも登録されている場合（特異なケース）では重複してAddFactory
            // してしまうことになる為、検討要
            this.MakeToolFactoryClass();

            // 各種スクリーンファクトリ集合体取得
            HySScreenFactorySet csScreenFactorySet = m_csFactoryMng.GetScreenFactorySet(); // システム共通
            HySViewFormFactorySet csViewFormFactorySet = m_csFactoryMng.GetViewFormFactorySet(); // 画面フォーム

            for (lLoop = 0; lLoop < csConfigData.Count; lLoop++)
            {
                csKey = csConfigData.GetKeyName((int)lLoop);            // 取り込みキー作成
                csKindName = csConfigData.GetFactoryKind(csKey);        // 種別取得
                csDllName = csConfigData.GetFactoryDll(csKey);          // ＤＬＬ名称
                csPackageName = csConfigData.GetFactoryPackage(csKey);  // パッケージ名称
                csClassName = csConfigData.GetFactoryClass(csKey);      // クラス名称
                if (File.Exists(csDllName))                             // ＤＬＬ有無
                {
                    csAssembly = Assembly.LoadFrom(@csDllName);         // アセンブリ取り込み
                    csModule = csAssembly.GetModule(csDllName);         // モジュール取得
                    csType = csModule.GetType(csPackageName + "." + csClassName);// モジュールタイプ取得

                    if (csType != null)
                    {   // 該当クラス有無
                        csFactory = null;
                        try
                        {
                            // ファクトリクラス生成
                            csFactory = (HySFactory)Activator.CreateInstance(csType);
                            // 此処でエラーを発生すると　Exceptionを発生して　終了する
                            // 従って、エラー発生時にTry：Catchが必要
                        }
                        catch
                        {
                            // ver1.5 エラートレース日本語対応
                            DispStatement = Properties.HysMsgResources.STATEMENT_EXCEPTION + " (" + csPackageName + "." + csClassName + ")" + "  " + Properties.HysMsgResources.STATEMENT_DLLNAME + csDllName;
                            HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", DispStatement);
                          //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", "catch Exception CreateInstance(" + csPackageName + "." + csClassName + ")" + "  DLL_NAME=" + csDllName);
                            continue;
                        }


                        if (csFactory != null)
                        {
                            HySLog.LogOut(HySLog.DEBUG, "HySConfigDataMaker::MakeFactoryClass", "*** CreateInstance(" + csPackageName + "." + csClassName + ")");

                            // データ識別子格納
                            csKind = new HySString(csKindName);
                            csGroup = new HySString(csPackageName);
                            csUniqueKey = new HySString(csClassName);
                            if (csFactory.GetFactoryID() == null)
                            {
                                csID = new HySID(csKind + csGroup + csUniqueKey);
                                csFactory.SetFactoryID((HySIdentifier)csID);
                            }

                            if (csKind == HySDefine.COMMONMP_SCREEN)  // スクリーンファクトリ
                            {   // スクリーンは特別
                                csScreenFactorySet.AddFactory(csFactory);
                            }
                            else if (csKind == HySDefine.COMMONMP_VIEWRFORM)  // フォームファクトリ
                            {   // フォームのファクトリ
                                csViewFormFactorySet.AddFactory(csFactory);
                            }
                            else
                            {   // ファクトリ管理に追加
                                m_csFactoryMng.AddFactory(csFactory);
                            }

                            // ファクトリ初期処理実行
                            csFactory.Init(m_csFactoryMng);
                        }
                        else
                        {
                            // ver1.5 エラートレース日本語対応
                            DispStatement = Properties.HysMsgResources.STATEMENT_FAILED_CREATE + " (" + csPackageName + "." + csClassName + ")";
                            HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", DispStatement); // ログへ書き込む
                          //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", "Cannot CreateInstance(" + csPackageName + "." + csClassName + ")"); // ログへ書き込む
                        }
                    }
                    else
                    {
                        // ver1.5 エラートレース日本語対応
                        DispStatement = Properties.HysMsgResources.STATEMENT_MODULE_NOTFOUND + " (" + csPackageName + "." + csClassName + ")";
                        HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", DispStatement); // ログへ書き込む
                      //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", "Cannot be found " + csPackageName + "." + csClassName ); // ログへ書き込む
                    }
                }
                else
                {
                    // ver1.5 エラートレース日本語対応
                    DispStatement = Properties.HysMsgResources.STATEMENT_MODULE_NOTFOUND + " (" + csDllName + ")";
                    HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", DispStatement); // ログへ書き込む
                  //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeFactoryClass", "Cannot be found " + csDllName ); // ログへ書き込む
                }
            } // end of for()
        }

        //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
        // Ver1.3では下記コードを追加する（diconファイルへの登録不要化） 
        //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
        /// <summary><para>method outline:</para>
        /// <para>ツールファクトリクラス生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>MakeToolFactoryClass()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void MakeToolFactoryClass()
        {
            Assembly csAssembly = null; // アセンブリ
            Module csModule = null;     // モジュール
            Type csType = null;         // モジュールタイプ
            String csDllName;           // ＤＬＬ名称
            String csPackageName;       // パッケージ名称
            String csClassName;         // クラス名称
            HySID csID;                 // データ識別子
            HySString csKind;           // 種別
            HySString csGroup;          // グループ
            HySString csUniqueKey;      // ユニークキー

            HySFactory csFactory = null;       // ファクトリクラス
            string DispStatement = "";  // ver1.5 エラートレース日本語対応

            // 各種スクリーンファクトリ集合体取得
            HySScreenFactorySet csScreenFactorySet = m_csFactoryMng.GetScreenFactorySet(); // システム共通
            HySViewFormFactorySet csViewFormFactorySet = m_csFactoryMng.GetViewFormFactorySet(); // 画面フォーム

            // 実行パスを取得する
            Assembly csEntryAssembly = Assembly.GetEntryAssembly();
            if (csEntryAssembly == null) { return; }

            string sPathName = csEntryAssembly.Location;
            DirectoryInfo csInfo = Directory.GetParent(sPathName);
            string sPath = csInfo.ToString();
            string[] sFiles = Directory.GetFiles(sPath);
            for (int iLoop = 0; iLoop < sFiles.Length; iLoop++)
            {
                string sFile = sFiles[iLoop];
                string sCut = sFile.Substring(sFile.Length - 3);
                if (sCut.Equals("dll") == true)
                {
                    int iIndex = sFile.LastIndexOf("\\");
                    csDllName = sFile.Substring(iIndex + 1, sFile.Length - (iIndex + 1));
                    try
                    {
                        csAssembly = Assembly.LoadFrom(@csDllName);         // アセンブリ取り込み
                    }
                    catch
                    {
                        continue;
                    }
                    csModule = csAssembly.GetModule(csDllName);         // モジュール取得
                    if (csModule != null)
                    {
                        // スクリーンファクトリー
                        csClassName = "HYSSOP_USRSCREEN_FACTORY_CREATOR_IMPLE";// ←Defineクラスに定義のこと
                        csPackageName = "CommonMP.HYSSOP._SYSTEM_";　　　　　　// ←Defineクラスに定義のこと
                        csType = csModule.GetType(csPackageName + "." + csClassName);// モジュールタイプ取得
                        if (csType != null)
                        {
                            //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "HySConfigDataMaker::MakeToolFactoryClass", "Get Class(" + csPackageName + "." + csClassName + ")" + "  DLL_NAME=" + csDllName);
                            // 該当クラス有無
                            CommonMP.HYSSOP._SYSTEM_.HYSSOP_USRSCREEN_FACTORY_CREATOR csFctCreator = null;
                            try
                            {
                                // ファクトリクリエータクラス生成
                                csFctCreator = Activator.CreateInstance(csType) as CommonMP.HYSSOP._SYSTEM_.HYSSOP_USRSCREEN_FACTORY_CREATOR;
                                // 此処でエラーを発生するとExceptionを発生して終了する
                                // 従って、エラー発生時にTry：Catchが必要
                            }
                            catch
                            {
                                // ver1.5 エラートレース日本語対応
                                DispStatement = Properties.HysMsgResources.STATEMENT_EXCEPTION + " (" + csPackageName + "." + csClassName + ")" + "  " + Properties.HysMsgResources.STATEMENT_DLLNAME + csDllName;
                                HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", DispStatement);
                              //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", "catch Exception CreateInstance(" + csPackageName + "." + csClassName + ")" + "  DLL_NAME=" + csDllName);
                                continue;
                            }
                            if (csFctCreator != null)
                            {
                                csFactory = csFctCreator.CreateFactory();
                                if (csFactory != null)
                                {
                                    // データ識別子格納
                                    csKind = new HySString(HySDefine.COMMONMP_SCREEN);
                                    csGroup = new HySString(csType.FullName);
                                    csUniqueKey = new HySString(csType.Name);
                                    if (csFactory.GetFactoryID() == null)
                                    {
                                        csID = new HySID(csKind + csGroup + csUniqueKey);
                                        csFactory.SetFactoryID((HySIdentifier)csID);
                                    }
                                    // スクリーンファクトリ追加
                                    csScreenFactorySet.AddFactory(csFactory);
                                    // ファクトリ初期処理実行
                                    csFactory.Init(m_csFactoryMng);
                                }
                                else
                                {
                                    // ver1.5 エラートレース日本語対応
                                    DispStatement = Properties.HysMsgResources.STATEMENT_FAILED_CREATE + " (" + csPackageName + "." + csClassName + ")";
                                    HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", DispStatement); // ログへ書き込む
                                  //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", "Cannot CreateInstance(" + csPackageName + "." + csClassName + ")"); // ログへ書き込む
                                }
                            }
                        }
                        else
                        {
                            // Do Nothing
                            //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "HySConfigDataMaker::MakeToolFactoryClass", "Cannot Get Class(" + csPackageName + "." + csClassName + ")" + "  DLL_NAME=" + csDllName);
                        }
                        // ビューア内処理ファクトリー
                        csClassName = "HYSSOP_USRVIEWERJOB_FACTORY_CREATOR_IMPLE";// ←Defineクラスに定義のこと
                        csPackageName = "CommonMP.HYSSOP._SYSTEM_";　　　　　　　 // ←Defineクラスに定義のこと
                        csType = csModule.GetType(csPackageName + "." + csClassName);// モジュールタイプ取得
                        if (csType != null)
                        {
                            HySLog.LogOut(HySLog.DEBUG, "HySConfigDataMaker::MakeToolFactoryClass", "Get Class(" + csPackageName + "." + csClassName + ")" + "  DLL_NAME=" + csDllName);
                            // 該当クラス有無
                            CommonMP.HYSSOP._SYSTEM_.HYSSOP_USRVIEWERJOB_FACTORY_CREATOR csFctCreator = null;
                            try
                            {
                                // ファクトリクリエータクラス生成
                                csFctCreator = Activator.CreateInstance(csType) as CommonMP.HYSSOP._SYSTEM_.HYSSOP_USRVIEWERJOB_FACTORY_CREATOR;
                                // 此処でエラーを発生するとExceptionを発生して終了する
                                // 従って、エラー発生時にTry：Catchが必要
                            }
                            catch
                            {
                                // ver1.5 エラートレース日本語対応
                                DispStatement = Properties.HysMsgResources.STATEMENT_EXCEPTION + " (" + csPackageName + "." + csClassName + ")" + "  " + Properties.HysMsgResources.STATEMENT_DLLNAME + csDllName;
                                HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", DispStatement);
                              //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", "catch Exception CreateInstance(" + csPackageName + "." + csClassName + ")" + "  DLL_NAME=" + csDllName);
                                continue;
                            }
                            if (csFctCreator != null)
                            {
                                csFactory = csFctCreator.CreateFactory();
                                if (csFactory != null)
                                {
                                    // データ識別子格納
                                    csKind = new HySString(HySDefine.COMMONMP_VIEWRJOB);
                                    csGroup = new HySString(csType.FullName);
                                    csUniqueKey = new HySString(csType.Name);
                                    if (csFactory.GetFactoryID() == null)
                                    {
                                        csID = new HySID(csKind + csGroup + csUniqueKey);
                                        csFactory.SetFactoryID((HySIdentifier)csID);
                                    }
                                    // ビューア内処理ファクトリ追加
                                    m_csFactoryMng.AddFactory(csFactory);
                                    // ファクトリ初期処理実行
                                    csFactory.Init(m_csFactoryMng);
                                }
                                else
                                {
                                    // ver1.5 エラートレース日本語対応
                                    DispStatement = Properties.HysMsgResources.STATEMENT_FAILED_CREATE + " (" + csPackageName + "." + csClassName + ")";
                                    HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", DispStatement); // ログへ書き込む
                                  //HySLog.LogOut(HySLog.ONLINE, "HySConfigDataMaker::MakeToolFactoryClass", "Cannot CreateInstance(" + csPackageName + "." + csClassName + ")"); // ログへ書き込む
                                }
                            }
                        }
                        else
                        {
                            // Do Nothing
                            //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "HySConfigDataMaker::MakeToolFactoryClass", "Cannot Get Class(" + csPackageName + "." + csClassName + ")" + "  DLL_NAME=" + csDllName);
                        }
                    }
                }
            } // end of for()
        }

        //
    }
}
