// <summary>ソースコード：システム全体制御クラス</summary>
// <author>CommonMP</author>

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

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

namespace CommonMP.HYSSOP.CoreImpl.HSController
{
    /// <summary><para>class outline:</para>
    /// <para>システム全体制御クラス</para>
    /// </summary>
    /// <remarks><para>remarks:</para>
    /// <para>無し</para>
    /// </remarks>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// </remarks>
    public class HySSystemController : HySControllerRoot
    {
        /// <summary>環境情報管理</summary>
        protected HySEnvInf m_csEnvInf;

        /// <summary>ファクトリ管理</summary>
        protected HySFactoryMng m_csFactoryMng;

        /// <summary>イベント管理</summary>
        protected HySEventManager m_csEventManager;

        /// <summary>システムコントローラー</summary>
        protected HySSystemController m_csSystemCtl;

        /// <summary>ビューアコントローラー</summary>
        protected HySViewerController m_csViewerCtl;

        /// <summary>演算制御</summary>
        protected HySSimulationController m_csSimCtl;

        /// <summary>ライブラリ管理制御</summary>
        protected HySLibraryController m_csLibraryCtl;

        /// <summary>業務処理</summary>
        protected HySBusiController m_csBusiCtl;

        /// <summary>GIS制御</summary>
        protected HySGISController m_csGISCtl;

        /// <summary>イベントキュー（Wait有り）</summary>
        protected HySQueue m_csEventQueue;

        /// <summary>定義データファイル定義名称</summary>
        protected HySString m_csConfigFileDefName;

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSystemController =csController = new HySSystemController( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySSystemController()
        {
            m_csEventQueue = new HySQueue(32);
        }

        /// <summary><para>method outline:</para>
        /// <para>定義データ管理クラス取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetConfigureFileName(csName)</para>
        /// </example>
        /// <param name="csName">定義データファイル定義名称</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetConfigureFileName(HySString csName)
        {
            m_csConfigFileDefName = csName;
        }

        /// <summary><para>method outline:</para>
        /// <para>初期化処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Initialize( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true : 正常、false : 異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean Initialize()
        {
            //HySString csEnvInfName = new HySString("CommonMP.cfg");
            
            // 環境情報管理クラス生成
            m_csEnvInf = new HySEnvInf(m_csConfigFileDefName);
            if (m_csEnvInf.Initialize() != 0) { return false; }

            // ===== start of 各種制御クラス生成 ====
            try
            {
                // システム全体制御
                m_csSystemCtl = this;

                // イベント管理生成
                m_csEventManager = new HySEventManager();

                // システム全体制御
                m_csEventManager.AddSysController(m_csSystemCtl);

                // ＧＩＳ制御生成
                m_csGISCtl = new HySGISController();
                m_csEventManager.AddSysController(m_csGISCtl);
                // ライブラリ管理制御生成
                m_csLibraryCtl = new HySLibraryController();
                m_csEventManager.AddSysController(m_csLibraryCtl);
                // 演算制御生成
                m_csSimCtl = new HySSimulationController();
                m_csEventManager.AddSysController(m_csSimCtl);
                // 業務管理制御生成
                m_csBusiCtl = new HySBusiController();
                m_csEventManager.AddSysController(m_csBusiCtl);
                // 画面制御生成
                m_csViewerCtl = new HySViewerController();
                m_csEventManager.AddSysController(m_csViewerCtl);
                // ===== end  of 各種制御クラス生成 ====


                // === start of ファクトリ管理関係処理
                // ファクトリ管理生成
                m_csFactoryMng = new HySFactoryManager();
                // ＤＩコンテナ生成
                HySSystemDIContainer csSystemDIContainer = new HySSystemDIContainer();
                // 定義データ管理取得
                HySConfigDataManager csDataManager = csSystemDIContainer.GetConfigDataManager((HySFactoryManager)m_csFactoryMng);
                // 定義データ読込
                csDataManager.ConfigDataLoad();
                // 全ファクトリクラス生成
                csDataManager.CreateFactoryClassAll();
                // === end of ファクトリ管理関係処理


                // === start of ファクトリから各種インスタンスを生成し管理クラスに設定する

                // 画面制御
                m_csViewerCtl.SetConfigDataMng(csDataManager);

                // ＧＩＳ制御にファクトリ管理を教える
                m_csGISCtl.SetFactoryManager(m_csFactoryMng);
                // ＧＩＳ初期化処理（インスタンス等生成）
                m_csGISCtl.Initialize();

                // ライブラリ制御にファクトリ管理を教える
                m_csLibraryCtl.SetFactoryManager(m_csFactoryMng);
                // ライブラリ初期化処理（インスタンス等生成）
                m_csLibraryCtl.Initialize();

                // シミュレーター制御にファクトリ管理を教える
                m_csSimCtl.SetFactoryManager(m_csFactoryMng);
                // シミュレーター制御初期化処理（インスタンス等生成）
                m_csSimCtl.Initialize();

                // 業務制御にファクトリ管理を教える
                m_csBusiCtl.SetFactoryManager(m_csFactoryMng);
                // 業務制御初期化処理（インスタンス等生成）
                m_csBusiCtl.Initialize();

                // 画面制御にファクトリ管理を教える
                m_csViewerCtl.SetFactoryMng(m_csFactoryMng);
                // 初期初期化処理（インスタンス等生成）
                m_csViewerCtl.Initialize();
                return true;
            }
            catch (Exception ex)
            {
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, "HySSystemController.Initialize", 
                    Properties.HysMsgResources.STATEMENT_ABEND + "(" + Properties.HysMsgResources.STATEMENT_CATCH_EXCEPTION +  ex.Message + ")");
               // HySLog.LogOut(HySLog.ONLINE, "HySSystemController.Initialize", "Abend  (catch exception  " + ex.Message + ")");
                return false;
            }
            // === end of ファクトリから各種インスタンスを生成し管理クラスに設定する
        }

        /// <summary><para>method outline:</para>
        /// <para>システム制御クラス設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetBusiController( csController ) </para>
        /// </example>
        /// <param name="csController">システム制御クラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSystemController(HySSystemController csController)
        {
            m_csSystemCtl = csController;
        }

        /// <summary><para>method outline:</para>
        /// <para>画面制御クラス設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetBusiController( csViewerCtl ) </para>
        /// </example>
        /// <param name="csViewerCtl">画面制御クラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetViewerController(HySViewerController csViewerCtl)
        {
            m_csViewerCtl = csViewerCtl;
        }

        /// <summary><para>method outline:</para>
        /// <para>業務制御クラス設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetBusiController( csBusiCtl ) </para>
        /// </example>
        /// <param name="csBusiCtl">業務制御クラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetBusiController(HySBusiController csBusiCtl)
        {
            m_csBusiCtl = csBusiCtl;
        }

        /// <summary><para>method outline:</para>
        /// <para>画面制御クラス取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySViewerController = csVewerCtl = GetViewerController( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>画面制御クラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySViewerController GetViewerController()
        {
            return m_csViewerCtl;
        }

        /// <summary><para>method outline:</para>
        /// <para>立ち上がり処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = WakeUp( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true : 正常、false : 異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean WakeUp()
        {
            bool bRtn = true;
            // 各コンポーネントの　立ち上げ
            try
            {
                HySLog.LogOut(HySLog.SYSTEM_DEBUG, "HySSystemController.WakeUp", "start");
                // イベントマネージャー動作開始
                m_csEventManager.WakeUp();

                // ＧＩＳ管理制御起動
                m_csGISCtl.WakeUp();
                // ライブラリ管理制御起動
                m_csLibraryCtl.WakeUp();
                // シミュレーター制御起動
                m_csSimCtl.WakeUp();
                // 業務制御起動
                m_csBusiCtl.WakeUp();
                // 最後に画面を立ち上げる
                m_csViewerCtl.WakeUp();
                HySLog.LogOut(HySLog.SYSTEM_DEBUG, "HySSystemController.WakeUp", "end");
            }
            catch (Exception ex)
            {
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, "HySSystemController.WakeUp", Properties.HysMsgResources.STATEMENT_ABEND + "(" +  Properties.HysMsgResources.STATEMENT_CATCH_EXCEPTION + ex.Message +")");
               // HySLog.LogOut(HySLog.ONLINE, "HySSystemController.WakeUp", "Abend  (catch exception  " + ex.Message + ")");
                bRtn = false;
                //this.ShutDown();
            }

            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>メイン画面起動処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Run( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void Run()
        {
            m_csViewerCtl.Run();
        }

        /// <summary><para>method outline:</para>
        /// <para>終了処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = Initialize( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true : 正常、false : 異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean ShutDown()
        {
            HySLog.LogOut(HySLog.SYSTEM_DEBUG, "HySSystemController.ShutDown", "start");

            // 業務制御終了
            m_csBusiCtl.ShutDown();
            // 演算制御終了
            m_csSimCtl.ShutDown();
            // ライブラリ管理制御終了
            m_csLibraryCtl.ShutDown();
            // ＧＩＳエンジン終了
            m_csGISCtl.ShutDown();

            // 画面制御終了
            m_csViewerCtl.ShutDown();// 画面は最後とする

            // イベントマネージャー終了
            m_csEventManager.ShutDown();
            // ファクトリマネージャ終了
            m_csFactoryMng.ShutDown();

            // 環境情報終了
            HySEnvInf.Terminate();
            // ver1.6 データフォルダの履歴管理
            HySEnvInf.SaveDataHomeHistory();

            ThreadStart ThSt = new ThreadStart(this.ProcExitCtlThread);
            Thread t = new Thread(ThSt);
            t.Start();

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>システム終了準備完了判別</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = ExitOK( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true : システムExit準備OK　、false : システムExit準備NG</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean ExitOK()
        {
            Boolean bRtn = true;

            if( m_csGISCtl.ExitOK() == false )
            {   // GIS制御
                bRtn = false;
            }
            else if( m_csBusiCtl.ExitOK() == false )
            {   // 業務処理
                bRtn = false;
            }
            else if( m_csLibraryCtl.ExitOK() == false )
            {   // ライブラリ管理制御
                bRtn = false;
            }
            else if( m_csSimCtl.ExitOK() == false )
            {   // 演算制御
                bRtn = false;
            }
            else if( m_csViewerCtl.ExitOK() == false )
            {   // ビューアコントローラー
                bRtn = false;
            }
            else if (m_csEventManager.ExitOK() == false)
            {   // イベント制御
                bRtn = false;
            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>システム終了指示</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = CmndShutDown( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true : 正常、false : 異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean CmndShutDown()
        {
            return m_csEventQueue.PushNumber(HySEventObject.CMND_SHUTDOWN_SYSTEM);
        }


        /// <summary><para>method outline:</para>
        /// <para>システム構成要素を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetSysUnit( csUnit ) </para>
        /// </example>
        /// <param name="csUnit">システム構成要素</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>本クラスは何もしない</para>
        /// </remarks>
        public void SetSysUnit(HySSysUnit csUnit)
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>イベント管理クラスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetSysEventManager( csEventMng ) </para>
        /// </example>
        /// <param name="csEventMng">イベント管理クラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetEventManager(HySEventMngRoot csEventMng)
        {
            m_csEventManager = (HySEventManager)csEventMng;
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントを受け取った時に動作するメソッド</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = EventCallback( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>各実装クラスは受け取ったイベントをシステム構成要素にポストする</para>
        /// </remarks>
        public virtual Boolean EventCallback(HySSysEvent csEvent)
        {
            Boolean bRtn = true;
            long lEventNo = ((HySEventObject)csEvent).GetEventNo();
            if (lEventNo == HySEventObject.CMND_SHUTDOWN_SYSTEM)
            {
                this.ShutDown();
            }
            else
            {
                bRtn = false;
            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントをイベント管理クラスにポストする</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = PutEvent( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送るイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>送信元識別子を自分で付与する</para>
        /// </remarks>
        public virtual Boolean PutEvent(HySSysEvent csEvent)
        {
            csEvent.SetFrom(HySSysEvent.OBJID_SYSCONTROLLER);
            return m_csEventManager.PutEvent(csEvent);
        }


        /// <summary><para>method outline:</para>
        /// <para>宛先識別番号を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> long lAdressIDNo = AdressIDNo() </para>
        /// </example>
        /// <returns>宛先識別番号:(HySSysEvent.OBJID_GISCONTROLLER)</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public long AdressIDNo()
        {
            return HySSysEvent.OBJID_SYSCONTROLLER;
        }
        
        /// <summary><para>method outline:</para>
        /// <para>システムExit制御スレッド</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> ProcExitCtlThread() </para>
        /// </example>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual void ProcExitCtlThread()
        {
            for(int i=0;i<100;i++)
            {   // 最大３０秒待ち
                System.Threading.Thread.Sleep(300);
                if( this.ExitOK() == true )
                {
                    break;
                }
            }
            m_csViewerCtl.Exit();
        }
    }
}
