// <summary>ソースコード：演算中のスケジュールを構成するクラス</summary>
// <author>CommonMP</author>

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

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

namespace CommonMP.HYSSOP.CoreImpl.HSController
{
    /// <summary><para>class outline:</para>
    /// <para>演算中のスケジュールの構成クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// <para>Remarks</para>
    /// <para>本クラスは、フレームワークの将来拡張用</para>
    /// </remarks>
    public class HySSimScheduleUnit : HySRoot
    {
        /// <summary>自分を保持しているスケジュール </summary>
        protected HySSimSchedule m_csSchedule;

        /// <summary>識別子</summary>
        protected HySID m_csID;

        /// <summary>演算目標時刻</summary>
        protected HySTime m_csGoalTime;
        /// <summary>演算時刻</summary>
        protected HySTime m_csSimuTime;
        ///// <summary>演算刻み幅</summary>
        //protected HySTime m_csDltTime;

        /// <summary>含まれるシミュレーターのリスト</summary>
        protected List<HySSimThreadController> m_csSimulatorList;

        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSimScheduleUnit csUnit = new HySSimScheduleUnit(csSchedule) </para>
        /// </example>
        /// <param name="csSchedule">演算スケジュール</param>
        /// <returns>生成されたインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySSimScheduleUnit(HySSimSchedule csSchedule)
        {
            m_csSchedule = csSchedule;
            m_csSimulatorList = new List<HySSimThreadController>();
        }

        /// <summary><para>method outline:</para>
        /// <para>演算目標時刻設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetGoalTime( csGoalTIme ) </para>
        /// </example>
        /// <param name="csGoalTime">演算目標時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetGoalTime(HySTime csGoalTime)
        {
            m_csGoalTime = csGoalTime;
        }
        /// <summary><para>method outline:</para>
        /// <para>演算目標時刻取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySTime csGoalTime　GetGoalTime( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>演算目標時刻</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySTime GetGoalTime()
        {
            return m_csGoalTime;
        }
        /// <summary><para>method outline:</para>
        /// <para>演算時刻設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetSimuTime( csSimuTime ) </para>
        /// </example>
        /// <param name="csSimuTime">演算時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSimuTime(HySTime csSimuTime)
        {
            m_csSimuTime = csSimuTime;
        }
        /// <summary><para>method outline:</para>
        /// <para>演算時刻取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySTime csDltTime　GetSimuTime( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>演算時刻取得幅</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySTime GetSimuTime()
        {
            return m_csSimuTime;
        }

        /// <summary><para>method outline:</para>
        /// <para>識別子設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetID( csID ) </para>
        /// </example>
        /// <param name="csID">識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetID(HySIdentifier csID)
        {
            m_csID = (CommonMP.HYSSOP.CoreImpl.HSData.HySID)csID;
        }
        /// <summary><para>method outline:</para>
        /// <para>識別子取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySIdentifier csID = GetID( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>識別子</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySIdentifier GetID()
        {
            return m_csID;
        }
        /// <summary><para>method outline:</para>
        /// <para>識別子による同一比較</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = Equal( sID ) </para>
        /// </example>
        /// <param name="sID">比較する種別識別子</param>
        /// <returns>  true :＝ , false:≠</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public Boolean Equal(HySIdentifier sID)
        {
            return m_csID.Equals(sID);
        }

        /// <summary><para>method outline:</para>
        /// <para>登録シミュレータークリア</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ClearSimulator( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void ClearSimulator()
        {
            m_csSimulatorList.Clear();
        }
        /// <summary><para>method outline:</para>
        /// <para>シミュレーターの追加</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> AddSimulator( csSimlator ) </para>
        /// </example>
        /// <param name="csSimlator">追加するシミュレーター</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void AddSimulator(HySSimThreadController csSimlator)
        {
            m_csSimulatorList.Add(csSimlator);
        }
        /// <summary><para>method outline:</para>
        /// <para>シミュレーターの取り外し</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> RemoveSimulator( sID ) </para>
        /// </example>
        /// <param name="csID">取り外すシミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void RemoveSimulator(HySIdentifier csID)
        {
            HySSimulatorRoot csSimulator;
            int iSimuCnt = m_csSimulatorList.Count;
            for (int iLp = 0; iLp < iSimuCnt; iLp++)
            {
                csSimulator = m_csSimulatorList[iLp].GetSimulator();
                if (csSimulator.Equal(csID) == true)
                {
                    m_csSimulatorList.RemoveAt(iLp);
                    break;
                }
            }//end for()
        }

        /// <summary><para>method outline:</para>
        /// <para>シミュレーターの初期化</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = CmdSimulationInitialize( csMediationData ) </para>
        /// </example>
        /// <param name="csMediationContainer">情報交換用データ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean CmdSimulationInitialize(HySSimuMediateContainer csMediationContainer)
        {
            HySSimulatorRoot csSimulator;
            HySSimThreadController csSimThreadCtl;
            int iSimuCnt = m_csSimulatorList.Count;

            HySEventObject csEvent = new HySEventObject(HySSysEvent.OBJID_SIMULATOR, HySEventObject.CMND_INITIALIZE_SIMULATION, csMediationContainer);
            for (int iLp = 0; iLp < iSimuCnt; iLp++)
            {
                csSimThreadCtl = m_csSimulatorList[iLp];
                csSimThreadCtl.SetSimScheduleUnit(this);  // <--- これが大切
                csSimulator = csSimThreadCtl.GetSimulator();

                csSimulator.InputMediateData(csMediationContainer);

                csSimulator.CmdInitializeSimulation(csEvent);
            } //end for()
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>計算開始指示</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = CmdSimulationStart( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean CmdSimulationStart()
        {
            return false;
        }
        /// <summary><para>method outline:</para>
        /// <para>計算中断指示</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = CmdSimulationPause( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean CmdSimulationPause()
        {
            return false;
        }
        /// <summary><para>method outline:</para>
        /// <para>計算再開指示</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = CmdSimulationContinue( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean CmdSimulationContinue()
        {
            return false;
        }
        /// <summary><para>method outline:</para>
        /// <para>計算強制終了指示</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = CmdSimulationStop( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean CmdSimulationStop()
        {
            return false;
        }
        /// <summary><para>method outline:</para>
        /// <para>シミュレーター間の情報交換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = CmdSimulationDataFusion( csMediationContainer ) </para>
        /// </example>
        /// <param name="csMediationContainer">情報交換用データ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean CmdSimulationDataFusion(HySSimuMediateContainer csMediationContainer)
        {
            return false;
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントを送る</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = PutEvent( csSySEvent ) </para>
        /// </example>
        /// <param name="csSySEvent">ThreadControllerからのイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>自分からイベントを送信する時に使用する</para>
        /// </remarks>
        public virtual Boolean PutEvent(HySSysEvent csSySEvent)
        {
            Boolean bRtn = false;
            HySEventObject csEvent = (HySEventObject)csSySEvent;
            long lEventNo = csEvent.GetEventNo();
            HySID csSimID = csEvent.GetSuppID();


            if ( lEventNo == HySEventObject.NOTICE_START_SIMULATION )
            {   //シミュレーション計算開始報告
                bRtn = NoticeSimulationStart(csSimID);
            }
            else if (lEventNo == HySEventObject.NOTICE_CANNOT_START_SIMULATION)
            {   //シミュレーション計算ＮＧ報告
                bRtn = NoticeUnableSimulationStart(csSimID);
            }
            else if( lEventNo == HySEventObject.NOTICE_PAUSE_SIMULATION )
            {   //シミュレーション計算中断報告
                bRtn = NoticeSimulationPause(csSimID);
            }
            //else if( lEventNo == HySEventObject.NOTICE_RESTART_SIMULATION )
            //{   // シミュレーション再開報告
            //    bRtn = NoticeSimulationRestart(csSimID);
            //}
            else if( lEventNo == HySEventObject.NOTICE_STOP_SIMULATION )
            {   // シミュレーション計算終了指示応答
                bRtn = NoticeSimulationStop(csSimID);
            }
            else if (lEventNo == HySEventObject.NOTICE_COMPLETE_SIMULATION)
            {   // シミュレーション計算完了報告
                bRtn = NoticeSimulationComplete(csSimID);
            }
            else if( lEventNo == HySEventObject.NOTICE_RENEW_SIMULATION )
            {   // シミュレーション中間結果変更報告
                bRtn = NoticeSimulationResultChange(csSimID);
            } 
            else
            {
                bRtn = m_csSchedule.PutEvent(csEvent);
            }

            return bRtn;
        }
        //  (予約イベント)シミュレーション計算開始通知
        /// <summary><para>method outline:</para>
        /// <para> (予約イベント)シミュレーション計算開始通知</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = NoticeSimulationPause( csSimID ) </para>
        /// </example>
        /// <param name="csSimID">シミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual Boolean NoticeSimulationStart(HySIdentifier csSimID)
        {
            return false;
        }
        //  (予約イベント)シミュレーション計算開始通知
        /// <summary><para>method outline:</para>
        /// <para> (予約イベント)シミュレーション計算開始出来ずを通知</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = NoticeUnableSimulationStart( csSimID ) </para>
        /// </example>
        /// <param name="csSimID">シミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual Boolean NoticeUnableSimulationStart(HySIdentifier csSimID)
        {
            return false;
        }
        //  (予約イベント)シミュレーション計算中断通知
        /// <summary><para>method outline:</para>
        /// <para> (予約イベント)シミュレーション計算中断通知</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = NoticeSimulationPause( csSimID ) </para>
        /// </example>
        /// <param name="csSimID">シミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual Boolean NoticeSimulationPause(HySIdentifier csSimID)
        {
            return false;
        }
        //  (予約イベント)シミュレーション計算再開通知
        /// <summary><para>method outline:</para>
        /// <para> (予約イベント)シミュレーション計算再開通知</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = NoticeSimulationRestart( csSimID ) </para>
        /// </example>
        /// <param name="csSimID">シミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual Boolean NoticeSimulationRestart(HySIdentifier csSimID)
        {
            return false;
        }
        //  (予約イベント)シミュレーション計算中止通知
        /// <summary><para>method outline:</para>
        /// <para> (予約イベント)シミュレーション計算中止通知</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = NoticeSimulationStop( csSimID ) </para>
        /// </example>
        /// <param name="csSimID">シミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual Boolean NoticeSimulationStop(HySIdentifier csSimID)
        {
            return false;
        }
        //  (予約イベント)シミュレーション計算完了通知
        /// <summary><para>method outline:</para>
        /// <para> (予約イベント)シミュレーション計算完了通知</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = NoticeSimulationPause( csSimID ) </para>
        /// </example>
        /// <param name="csSimID">シミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual Boolean NoticeSimulationComplete(HySIdentifier csSimID)
        {
            return false;
        }
        //  (予約イベント)シミュレーション計算結果更新通知(シミュレーション計算中に結果表示を更新していく場合等)
        /// <summary><para>method outline:</para>
        /// <para> (予約イベント)シミュレーション計算結果更新通知</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = NoticeSimulationResultChange( csSimID ) </para>
        /// </example>
        /// <param name="csSimID">シミュレーター識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual Boolean NoticeSimulationResultChange(HySIdentifier csSimID)
        {
            return false;
        }

    }
}
