// <summary>ソースコード：河川横断面図形状表示スクリーン</summary>
// <author>CommonMP</author>

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

using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.Interface.HSGIS;
using CommonMP.HYSSOP.Interface.HSViewer;

using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSGIS;
using CommonMP.HYSSOP.CoreImpl.HSTools;
using CommonMP.HYSSOP.CoreImpl.HSLibraryMng;

namespace CommonMP.HYSSOP.CoreImpl.HSViewer
{
    /// <summary><para>class outline:</para>
    /// <para>河川横断面図形状表示スクリーン</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/05/01][新規作成]</para>
    /// </remarks>
    public class HySRiverCrossSectionScreen : HySScreenBase
    {
        /// <summary>イベント応答識別子「検索(メタデータのみ)」</summary>
        private static readonly HySID METADATA_ONLY = new HySID("METADATA_ONLY");

        /// <summary>ログ出力用クラス名称</summary>
        private static readonly string CLASS_NAME = "HySRiverCrossSectionScreen";


        /// <summary>対応する表示フォーム</summary>
        HySRiverCrossSectionFormIF m_csForm = null;

        /// <summary><para>method outline:</para>
        /// <para>ビュー種別取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySKind csKind = GetViewKind()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySKind ＧＩＳビュー種別</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override HySKind GetViewKind()
        { return HySDefine.DISP_FORM_RIVER_CROSSSECTION; }
        /// <summary><para>method outline:</para>
        /// <para>ＧＩＳビュー種別比較</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = EqualViewKind(csViewKindID)</para>
        /// </example>
        /// <param name="csViewKindID">ビュー種別</param>
        /// <returns>Boolean true:同じ、false:異なる</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override Boolean EqualViewKind(HySKind csViewKindID)
        { return HySDefine.DISP_FORM_RIVER_CROSSSECTION.Equals(csViewKindID); }

        /// <summary><para>method outline:</para>
        /// <para>初期処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void Initialize()
        {
            if (m_csForm != null)
            { // 画面が有効な場合
                m_csForm.SetScreen(this); // スクリーン設定
                m_csForm.Initialize(); // 画面の初期化
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>終了処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Terminate()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void Terminate()
        {
            if (m_csForm != null)
            { // 画面が有効な場合
                m_csForm.Terminate();
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>画面表示</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> ShowScreen( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void ShowScreen()
        {
            if (m_csForm != null)
            {
                m_csForm.Show();
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>画面非表示化</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HideScreen( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void HideScreen()
        {
            if (m_csForm != null)
            {
                m_csForm.Hide();
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>画面更新</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> RenewScreen( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void RenewScreen()
        {
            if (m_csForm != null)
            {
                m_csForm.Renew();
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>画面消去</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> CloseScreen( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void CloseScreen()
        {
            if (m_csForm != null)
            {
                m_csForm.Close();
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>画面初期配置表示</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> InitiateScreen( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void InitiateScreen()
        {
            if (m_csForm != null)
            {  // 画面が有効な場合
                m_csForm.InitiateScreen();
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントを受け取った時に動作するメソッド</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = EventCallback( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <returns>Boolean true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>各実装クラスは受け取ったイベント毎に処理を行う</para>
        /// </remarks>
        public override Boolean EventCallback(HySSysEvent csEvent)
        {

            Boolean bRtn = true;
            HySEventObject csHySEvent = (HySEventObject)csEvent;
            long lEventNo = csHySEvent.GetEventNo();
            long lSubEventNo = csHySEvent.GetSubEventNo();

            // DB関連一般報告(正常) 
            // DB関連一般報告(異常) 
            if ((lEventNo == HySEventObject.NOTICE_DB_OK) ||
                (lEventNo == HySEventObject.NOTICE_DB_NG) )
            {
                // イベント番号より処理成否を決定
                bool bDBResult = false;
                if (lEventNo == HySEventObject.NOTICE_DB_OK)
                {
                    bDBResult = true;
                }

                if (lSubEventNo == HySLibraryMngDefine.DB_QUERY_DATA_LIST)
                {
                    HySStockDataList csDataList = (HySStockDataList)csHySEvent.GetData();
                    HySID csResponceID = csHySEvent.GetResponseInfo();
                    // メタデータのみの応答識別子が設定されている場合はファイル出力
                    if (METADATA_ONLY.Equals(csResponceID))
                    {
                        // 横断面データ一覧検索
                        bRtn = RespondCrossSectionList(bDBResult, csDataList);
                    }
                    else
                    {
                        // 横断面データ検索(複数)
                        bRtn = RespondCrossSection(bDBResult, csDataList);
                    }
                }
                else if (lSubEventNo == HySLibraryMngDefine.DB_QUERY_DATA)
                {
                    // 横断面データ検索
                    HySGeoRiverCrossSectionData csCrossSectionData = null;
                    if (bDBResult)
                    {
                        HySStockData csStockData = (HySStockData)csHySEvent.GetData();
                        csCrossSectionData = (HySGeoRiverCrossSectionData)csStockData.GetData();
                    }
                    bRtn = m_csForm.SetCrossSection(bDBResult, csCrossSectionData);
                }
                else if (lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_UPDATE)
                {   // 横断面データ更新登録
                    bRtn = m_csForm.RespondSaveCrossSection(bDBResult);
                }
            }

            return bRtn;
        }


        /// <summary><para>method outline:</para>
        /// <para>表示に特別に必要なイベント情報の設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetDispEventData( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">イベント情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>表示に特別に必要なイベント情報があった場合のみ発行</para>
        /// </remarks>
        public override void SetDispEventData(HySSysEvent csEvent)
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>対となる画面フォームの設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetViewForm( csViewForm )</para>
        /// </example>
        /// <param name="csViewForm">画面フォーム</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetViewForm(HySViewForm csViewForm)
        {
            m_csForm = csViewForm as HySRiverCrossSectionFormIF;
        }

        /// <summary><para>method outline:</para>
        /// <para>横断面データ一覧要求</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = GetCrossSectionList(riverCode)</para>
        /// </example>
        /// <param name="riverCode">河川コード</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool GetCrossSectionList(string riverCode)
        {
            // 河川コードを検索条件としてクエリ作成
            HySQueryCtlData csQuery = CreateStrQuery(riverCode, HySGeoRiverCrossSectionQueryFieldNames.RIVER_CODE);
            // メタデータのみのフラグを設定
            csQuery.SetIsMetaDataOnly(true);

            // 横断面データ一覧検索のイベント送信(応答識別子設定)
            bool bRtn = this.PutEvent(HySSysEvent.OBJID_LIBMANAGER, HySEventObject.CMND_DB_QUERY,
                                      HySLibraryMngDefine.DB_QUERY_DATA_LIST, csQuery, METADATA_ONLY);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>横断面データ要求</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = GetCrossSection(csID)</para>
        /// </example>
        /// <param name="csID">横断面データID</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool GetCrossSection(HySGeoRiverCrossSectionID csID)
        {
            // 横断面データ検索のイベント送信
            bool bRtn = this.PutEvent(HySSysEvent.OBJID_LIBMANAGER, HySEventObject.CMND_DB_QUERY,
                                      HySLibraryMngDefine.DB_QUERY_DATA, csID, null);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>横断面データ要求</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = GetCrossSection(csIDs)</para>
        /// </example>
        /// <param name="csID">横断面データID配列</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool GetCrossSection(HySGeoRiverCrossSectionID[] csID)
        {
            // ID配列をリストに格納
            HySQueryCtlData csQuery = CreateIDQuery(csID, HySGeoRiverCrossSectionQueryFieldNames.CROSS_SEC_ID);

            // 横断面データ検索(ID配列指定)のイベント送信
            return this.PutEvent(HySSysEvent.OBJID_LIBMANAGER, HySEventObject.CMND_DB_QUERY,
                                      HySLibraryMngDefine.DB_QUERY_DATA_LIST, csQuery, null);
        }

        /// <summary><para>method outline:</para>
        /// <para>横断面データ要求</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = GetCrossSection(riverCode)</para>
        /// </example>
        /// <param name="riverCode">河川コード</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        public virtual bool GetCrossSection(string riverCode)
        {
            // 河川コードを条件としてクエリ作成
            HySQueryCtlData csQuery = CreateStrQuery(riverCode, HySGeoRiverCrossSectionQueryFieldNames.RIVER_CODE);

            // 横断面データ検索のイベント送信
            return this.PutEvent(HySSysEvent.OBJID_LIBMANAGER, HySEventObject.CMND_DB_QUERY,
                                      HySLibraryMngDefine.DB_QUERY_DATA_LIST, csQuery, null);
        }

        /// <summary><para>method outline:</para>
        /// <para>横断面データ保存要求</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = SaveCrossSection(data)</para>
        /// </example>
        /// <param name="data">河川横断面図形状データ</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool SaveCrossSection(HySGeoRiverCrossSectionData data)
        {
            // ストックデータに設定
            HySStockData csData = new HySStockData(new HySObjectKind(), new HySID(""));
            csData.SetData(data);

            // 横断面データ更新登録のイベント送信
            return this.PutEvent(HySSysEvent.OBJID_LIBMANAGER, HySEventObject.CMND_DB_REGISTER,
                                      HySLibraryMngDefine.DB_REGISTER_DATA_UPDATE, csData, null);
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントを送る</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Boolean bRtn = PutEvent( csObjID, lEventNo, lSubEventNo, csEventData ) </para>
        /// </example>
        /// <param name="lObjID">宛先識別子</param>
        /// <param name="lEventNo">イベント番号</param>
        /// <param name="lSubEventNo">サブイベント番号</param>
        /// <param name="csEventData">イベントデータ</param>
        /// <param name="csResponceID">応答識別子</param>
        /// <returns>Boolean true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>自分からイベントを送信する時に使用する</para>
        /// </remarks>
        private Boolean PutEvent(long lObjID, long lEventNo, long lSubEventNo, HySDataRoot csEventData, HySID csResponceID)
        {
            const string csMethodName = "PutEvent";
            // イベント情報設定
            HySEventObject csEvent = new HySEventObject(lObjID, lEventNo, lSubEventNo);
            csEvent.SetData(csEventData);
            //csEvent.SetSuppID(csSuppID);
            //csEvent.SetSubData(HySLibraryMngDefine.DB_KIND_RIVER_CROSS_SECTION_DATA);
            //csEvent.SetData(csSuppID);
            csEvent.SetFromSimKind(HySDefine.COMMON_DISP_BUSIPROCEDURE);
            csEvent.SetToSimKind(HySDefine.SIMULATOR_KIND);
            csEvent.SetSuppID(HySLibraryMngDefine.DB_KIND_RIVER_CROSS_SECTION_DATA);
            csEvent.SetResponseInfo(csResponceID);
            if (!base.PutEvent(csEvent))
            {
               // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, csMethodName, Properties.HysMsgResources.STATEMENT_SEND_FAILURE);
                   // HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, csMethodName, "イベント送信失敗");
                return false;
            }
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>横断面データ一覧要求応答処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Boolean bRtn = RespondCrossSectionList(bDBResult, csStockDataList)</para>
        /// </example>
        /// <param name="bDBResult">DB処理結果</param>
        /// <param name="csStockDataList">検索結果</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private Boolean RespondCrossSectionList(bool bDBResult, HySStockDataList csStockDataList) 
        {
            string csPath = null;
            bool bRtn = false;
            // DB結果が正常の場合はファイル出力実行
            if (bDBResult)
            {
                // 横断面データ一覧ファイル出力オブジェクト作成
                csPath = CreateFilePath();
                HySRiverCrossSectionListFile csFile = new HySRiverCrossSectionListFile(csPath);

                // ファイル出力
                bRtn = csFile.Write(csStockDataList);
                if (!bRtn)
                {   // ファイル出力失敗
                    csPath = null;
                    // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, "HySRiverCrossSectionScreen::RespondCrossSectionList()",
                                                 Properties.HysMsgResources.STATEMENT_RCSLF_OUT_NG );
                   // HySLog.LogOut(HySLog.ONLINE, "HySRiverCrossSectionScreen::RespondCrossSectionList()",
                   //                              "河道横断面データ一覧ファイルの出力に失敗しました。");
                }
            }
            // ビューに処理結果を通知
            return m_csForm.SetCrossSectionList(bRtn, csPath);
        }

        /// <summary><para>method outline:</para>
        /// <para>横断面データ要求応答処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Boolean bRtn = RespondCrossSection(bDBResult, csStockDataList)</para>
        /// </example>
        /// <param name="bDBResult">DB処理結果</param>
        /// <param name="csStockDataList">検索結果</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private bool RespondCrossSection(bool bDBResult, HySStockDataList csStockDataList) 
        {
            HySGeoRiverCrossSectionData[] csDataList = null;
            bool bResult = bDBResult;
            // DB結果が正常の場合はデータ配列生成処理実行
            if (bDBResult)
            {
                if (csStockDataList.GetCount() == 0)
                {
                    // DB処理正常だが結果0件
                    // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, "HySRiverCrossSectionScreen::RespondCrossSection()",
                                                 Properties.HysMsgResources.STATEMENT_NOTFOUND_SEARCH_CONDITIONS );
                   // HySLog.LogOut(HySLog.ONLINE, "HySRiverCrossSectionScreen::RespondCrossSection()",
                   //                              "指定された検索条件でデータの取得に失敗しました。");
                    bResult = false;
                }
                else
                {
                    // 検索結果から実データを取り出す
                    List<HySGeoRiverCrossSectionData> csList = new List<HySGeoRiverCrossSectionData>();
                    csStockDataList.SetCursorFirst();
                    for (int i = 0; i < csStockDataList.GetCount(); i++)
                    {
                        HySStockData csStockData = (HySStockData)csStockDataList.GetCursorData();
                        HySGeoRiverCrossSectionData csData = (HySGeoRiverCrossSectionData)csStockData.GetData();
                        csList.Add(csData);
                        csStockDataList.MoveCursorNext();
                    }

                    csDataList = csList.ToArray();
                }
            }
            // 画面側への処理通知
            return m_csForm.SetCrossSection(bResult, csDataList);
        }

        /// <summary><para>method outline:</para>
        /// <para>文字列検索条件の作成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySQueryCtlData csQuery = CreateStrQuery(strValue, csFieldName)</para>
        /// </example>
        /// <param name="strValue">検索文字列</param>
        /// <param name="csFieldName">検索条件フィールド名称</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private HySQueryCtlData CreateStrQuery(string strValue, HySString csFieldName)
        {
            HySQueryCtlData csQuery = new HySQueryCtlData();
            
            // 検索条件に追加
            HySString csString = new HySString(strValue);
            csQuery.SetQueryEntryData(
                new HySQueryEntryData(csFieldName, csString.GetType(), HySQueryCompareMode.EQUALS, csString));

            return csQuery;
        }

        /// <summary><para>method outline:</para>
        /// <para>ID検索条件の作成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySQueryCtlData csQuery = CreateIDQuery(strValue, csFieldName)</para>
        /// </example>
        /// <param name="csIDs">検索ID</param>
        /// <param name="csFieldName">検索条件フィールド名称</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private HySQueryCtlData CreateIDQuery(HySIdentifier[] csIDs, HySString csFieldName)
        {
            HySQueryCtlData csQuery = new HySQueryCtlData();

            // 検索条件に追加
            csQuery.SetQueryEntryData(
                new HySQueryEntryData(csFieldName, typeof(HySIdentifier), HySQueryCompareMode.IN, csIDs));

            return csQuery;
        }
        /// <summary><para>method outline:</para>
        /// <para>横断面データ一覧出力パス作成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>string csFilePath = CreateFilePath()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>横断面データ一覧出力パス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para></para>
        /// </remarks>
        private string CreateFilePath()
        {
            HySString csHomeDir = HySEnvInf.GetHomeDirectory();
            HySString csFilePath = csHomeDir + HySGISDefine.CROSS_SEC_LISTDIR + HySGISDefine.CROSS_SEC_LISTNAME;

            return csFilePath.ToString();
        }
    }
}
