// <summary>ソースコード：２次元メッシュスクリーンクラス</summary>
// <author>CommonMP</author>

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

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

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


namespace CommonMP.HYSSOP.CoreImpl.HSViewer
{
    /// <summary><para>class outline:</para>
    /// <para>２次元メッシュスクリーンクラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// </remarks>
    /// <remarks><para>Remarks</para>
    /// <para>インスタンス複数存在有り（複数のメッシュ情報をオーバーレイ表示する）</para>
    /// </remarks>
    public class HySGISDim2MeshScreen : HySGISScreenBase
    {
        /// <summary>データコンテナ</summary>
        protected HySContainer m_csContainer = null;

        /// <summary>データ保存クラスリスト</summary>
        protected HySStockDataList m_csStockDataList = null;

        /// <summary>データ保存クラス</summary>
        protected HySStockData m_csStockData = null;

        /// <summary>表示業務管理データ</summary>
        protected HySDispBusiProcedureCtlInfo m_csDBPCtlInfo = null;

        /// <summary>選択データ識別キー管理リスト</summary>
        protected ArrayList m_csIDList = null;

        /// <summary>ＫＭＬ出力データ</summary>
        protected HySDataRoot m_csKMLData = null;
        /// <summary>ＫＭＬファイル名称</summary>
        protected HySString m_csKMLOutFile = null;

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

        /// <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()
        {
            HySString csTrue = new HySString("true");
            HySStockDataList csStockDataList = null;
            HySDataRoot csData = null;

            if (m_csGISView != null)
            {  // Viewerが有効な場合
                if (m_csStockDataList is HySStockDataList)
                {  // データ保存クラスリストが有る場合
                    long lCnt = m_csStockDataList.GetCount();
                    m_csStockDataList.SetCursorFirst();
                    for (int iLp1 = 0; iLp1 < (int)lCnt; iLp1++)
                    {  // リスト数分繰り返す
                        m_csStockData = m_csStockDataList.GetCursorData() as HySStockData;
                        if (m_csStockData is HySStockData)
                        {  // データ保存クラスの場合
                            if (m_csIDList is ArrayList)
                            {  // 選択データ識別キーリストが有る場合
                                if (((HySString)m_csIDList[iLp1]).Equal(csTrue) == true)
                                {  // 対象データの場合
                                    if (m_csStockData.GetData() is HySDataRoot)
                                    {  // データが有効な場合
                                        if (csStockDataList == null)
                                        {  // 初回の場合
                                            csStockDataList = new HySStockDataList();
                                        }
                                        csStockDataList.AddLast(m_csStockData.GetData()); // 対象データ追加
                                    }
                                }
                            }
                        }
                        m_csStockDataList.MoveCursorNext(); // 次へ
                    }
                    if (csStockDataList is HySStockDataList)
                    {  // 要求データが有る場合
                        if (m_csDBPCtlInfo is HySDispBusiProcedureCtlInfo)
                        {  // 表示業務管理データが有る場合
                            HySString csOutFile = m_csDBPCtlInfo.GetTemporaryDataList(HySDefine.DISP_FORM_GIS2D_MESH) as HySString;
                            if (csOutFile is HySString)
                            {  // KMLファイル出力の場合
                                m_csKMLData = csStockDataList; // データインスタンス設定
                                m_csKMLOutFile = csOutFile; // 出力名称設定
                                // 別スレッドを立てて実行
                                ThreadStart ThSt = new ThreadStart(this.PutKMLFile);
                                Thread t = new Thread(ThSt);
                                t.Start();
                            }
                            else
                            {  // 地図表示の場合
                                if (csStockDataList.GetCount() > 1)
                                {  // セルデータのマージが必要な場合
                                    m_csStockData = CellDataMerge(csStockDataList); // セルデータのマージ
                                    if (m_csStockData is HySStockData)
                                    {
                                        csData = m_csStockData.GetData();
                                    }
                                }
                                else
                                {  // セルデータのマージが必要ない場合
                                    csData = csStockDataList.GetFirstData() as HySDataRoot;
                                }
                                if (csData is HySDataRoot)
                                {  // 要求データが有効な場合
                                    if (csData is HySGeoDim2MeshSerialData)
                                    {   // 時系列の２次元メッシュデータの場合
                                        ((HySGISDim2MeshView)m_csGISView).SetDispMeshData((HySGeoDim2MeshSerialData)csData);
                                        ((HySGISDim2MeshView)m_csGISView).StartAnimation();
                                    }
                                    else if (csData is HySGeoDim2MeshData)
                                    {   // ２次元メッシュデータの場合
                                        ((HySGISDim2MeshView)m_csGISView).SetDispMeshData((HySGeoDim2MeshData)csData);
                                        m_csGISView.Renew();
                                    }
                                }
                            }
                        }
                        csStockDataList = null;
                    }
                }
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>ＫＭＬ出力処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> PutKMLFile( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void PutKMLFile()
        {
            long lCnt = ((HySStockDataList)m_csKMLData).GetCount();
            for (long lP = 0; lP < lCnt; lP++)
            {  // データ件数分繰り返す
                HySDataRoot csData = ((HySStockDataList)m_csKMLData).GetData(lP);
                if (csData is HySDataRoot)
                {  // 要求データが有効な場合
                    HySString csKMLOutFile = m_csKMLOutFile;
                    if (lP >= 1)
                    {  // マルチデータの場合
                        string sWk = m_csKMLOutFile.ToString();
                        int iIndex = sWk.LastIndexOf(".");
                        if (iIndex >= 0)
                        {  // 識別子が有る場合
                            sWk = sWk.Insert(iIndex, "_" + (lP + 1).ToString());
                        }
                        else
                        {  // 識別子が無い場合
                            sWk += "_" + (lP + 1).ToString();
                        }
                        csKMLOutFile = new HySString(sWk);
                    }
                    
                    //HySGoogleEarthComApi csApi = new HySGoogleEarthComApi();
                    //csApi.CreateKmlFileFromDim2Mesh((HySGeoDim2MeshSerialData)csData, csKMLOutFile);
                    HySCreateKmlFile csKmlFile = null;
                    // ＫＭＬ作成クラス
                    csKmlFile = new HySCreateKmlFile();
                    // ２次元メッシュクラスからＫＭＬファイル作成
                    csKmlFile.CreateKmlFileFromDim2Mesh((HySGeoDim2MeshSerialData)csData, csKMLOutFile);


                    m_csDBPCtlInfo.RemoveTemporaryDataList(HySDefine.DISP_FORM_GIS2D_MESH); //  KMLファイル出力名削除
                }
            }
            // ＫＭＬ出力完了通知
            HySEventObject csEventObj = new HySEventObject(HySSysEvent.OBJID_BUSIPROCEDURE, HySEventObject.CMND_DISPLY_COMMON);
            csEventObj.SetToSimKind(m_csSimKindID);
            csEventObj.SetSuppID(m_csID);
            csEventObj.SetData(this.GetViewKind());
            csEventObj.SetSubEventNo(HySDispDefine.NOTICE_KML_OUTPUT_COMPLET);
            this.PutEvent(csEventObj);
        }

        /// <summary><para>method outline:</para>
        /// <para>セルデータマージ処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> CellDataMerge(csStockDataList) </para>
        /// </example>
        /// <param name="csStockDataList">マージ対象セルデータリスト</param>
        /// <returns>HySStockData セルマージ後のデータ。マージできない場合、nullを返す。</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySStockData CellDataMerge(HySStockDataList csStockDataList)
        {
            HySStockData csMergedStockData = null;

            //
            // 事前チェック
            //
            try
            {
                // 先頭の時系列データを取得する
                HySTimeSeriesBase csFirstTimeSeriesData = csStockDataList.GetFirstData() as HySTimeSeriesBase;
                long lFirstTimeSeriesCount = csFirstTimeSeriesData.GetCount();

                //
                // ループ１：StockDataListのループ
                //
                long lStockDataCount = csStockDataList.GetCount();
                csStockDataList.SetCursorFirst();
                csStockDataList.MoveCursorNext();
                for (long lIdx = 1; lIdx < lStockDataCount; ++lIdx)
                {
                    HySTimeSeriesBase csTimeSeriesData = csStockDataList.GetCursorData() as HySTimeSeriesBase;
                    csStockDataList.MoveCursorNext();

                    long lTimeSeriesCount = csTimeSeriesData.GetCount();
                    if (lTimeSeriesCount != lFirstTimeSeriesCount)
                    {
                        // 時刻数が異なるのでマージできない
                        //System.Diagnostics.Debug.Print("time count unmatch, cannot merge");
                        return null;
                    }

                    //
                    // ループ２：　時系列データのループ
                    //
                    csFirstTimeSeriesData.SetCursorFirst();
                    csTimeSeriesData.SetCursorFirst();
                    for (long lTimeIdx = 0; lTimeIdx < lTimeSeriesCount; ++lTimeIdx)
                    {
                        HySTimeRecordIF csFirstTimeRecordData = csFirstTimeSeriesData.GetCursorData();
                        csFirstTimeSeriesData.MoveCursorNext();
                        HySTimeRecordIF csTimeRecordData = csTimeSeriesData.GetCursorData();
                        csTimeSeriesData.MoveCursorNext();

                        HySTime csFirstTime = csFirstTimeRecordData.GetLastTime();
                        HySTime csTime = csTimeRecordData.GetLastTime();

                        if (!csFirstTime.Equals(csTime))
                        {
                            // 同じ位置にあるが時刻が異なるのでマージできない
                            //System.Diagnostics.Debug.Print("time value unmatch, cannot merge");
                            return null;
                        }
                        //
                        // メッシュ数を調べる
                        //
                        HySGeoDim2MeshData csFirstGeoDim2MeshData = csFirstTimeRecordData as HySGeoDim2MeshData;
                        HySD2CellArrayData csFirstD2CellArrayData = csFirstGeoDim2MeshData.GetCellArray() as HySD2CellArrayData;
                        HySGeoDim2MeshData csGeoDim2MeshData = csTimeRecordData as HySGeoDim2MeshData;
                        HySD2CellArrayData csD2CellArrayData = csGeoDim2MeshData.GetCellArray() as HySD2CellArrayData;
                        if (csFirstD2CellArrayData.GetDimension1() != csD2CellArrayData.GetDimension1() ||
                            csFirstD2CellArrayData.GetDimension2() != csD2CellArrayData.GetDimension2() ||
                            csFirstD2CellArrayData.GetDimension3() != csD2CellArrayData.GetDimension3())
                        {
                            // メッシュ数が異なるのでマージできない
                            //System.Diagnostics.Debug.Print("mesh dimension unmatch, cannot merge");
                            return null;
                        }
                    }
                }
            }
            catch
            {
                // 予期しない例外が発生した
                //System.Diagnostics.Debug.Print("exception: {0}", ex);
            }

            //
            // マージ処理
            //
            try
            {
                //
                // セル内データ種別数の合計を求める
                //
                long lTotalDataCharacteristicNum = 0;   // セル内データ種別数の合計

                long lStockDataCount = csStockDataList.GetCount();
                csStockDataList.SetCursorFirst();
                for (long lStockDataIdx = 0; lStockDataIdx < lStockDataCount; ++lStockDataIdx)
                {
                    HySTimeSeriesBase csTimeSeriesData = csStockDataList.GetCursorData() as HySTimeSeriesBase;
                    csStockDataList.MoveCursorNext();

                    HySGeoMeshSerial csGeoDim2MeshSeriesData = csTimeSeriesData as HySGeoMeshSerial;
                    HySDataCharacteristicInCell csDataCharacteristic = csGeoDim2MeshSeriesData.GetCellDataCharacteristic();
                    long lDtChNum = csDataCharacteristic.GetDataNumber();

                    lTotalDataCharacteristicNum += lDtChNum;
                }
                System.Diagnostics.Debug.Print("lTotalDataCharacteristicNum = {0}", lTotalDataCharacteristicNum);

                //
                // セル内データ種別数を拡張したマージ用２次元地理メッシュ情報時系列データを作成する
                //
                HySGeoDim2MeshSerialData csFirstGeoDim2MeshSerialData = csStockDataList.GetFirstData() as HySGeoDim2MeshSerialData;
                HySGeoDim2MeshSerialData csMergedGeoDim2MeshSerialData = new HySGeoDim2MeshSerialData(
                    csFirstGeoDim2MeshSerialData.GetDataMeshKind(),
                    csFirstGeoDim2MeshSerialData.GetLonDimension(),
                    csFirstGeoDim2MeshSerialData.GetLatDimension(),
                    lTotalDataCharacteristicNum);

                {
                    double dUpAlt = 0;
                    double dLwAlt = 0;
                    double dSWLat = 0;
                    double dSWLon = 0;
                    double dNELat = 0;
                    double dNELon = 0;
                    csFirstGeoDim2MeshSerialData.GetAltitude(ref dUpAlt, ref dLwAlt);
                    csFirstGeoDim2MeshSerialData.GetLocation(ref dSWLat, ref dSWLon, ref dNELat, ref dNELon);
                    csMergedGeoDim2MeshSerialData.SetAltitude(dUpAlt, dLwAlt);
                    csMergedGeoDim2MeshSerialData.SetCellDataCharacteristic(csFirstGeoDim2MeshSerialData.GetCellDataCharacteristic());
                    csMergedGeoDim2MeshSerialData.SetCellIDMngData(csFirstGeoDim2MeshSerialData.GetCellIDMngData());
                    csMergedGeoDim2MeshSerialData.SetLocation(dSWLat, dSWLon, dNELat, dNELon);
                    long lPatternNum = csFirstGeoDim2MeshSerialData.GetPatternNumber();
                    csMergedGeoDim2MeshSerialData.SetPatternNumber(lPatternNum);
                    for (long lPatternIdx = 0; lPatternIdx < lPatternNum; ++lPatternIdx)
                    {
                        csMergedGeoDim2MeshSerialData.SetPattern(lPatternIdx, csFirstGeoDim2MeshSerialData.GetPattern(lPatternIdx));
                    }
                }
                //
                // セル内データ種別をマージする
                //
                HySDataCharacteristicInCell csMergedDataCharacteristicInCell = new HySDataCharacteristicInCell(lTotalDataCharacteristicNum);
                long lMergedDataCharacteristicInCellIdx = 0;
                csStockDataList.SetCursorFirst();
                for (long lStockDataIdx = 0; lStockDataIdx < lStockDataCount; ++lStockDataIdx)
                {
                    HySGeoMeshSerial csGeoDim2MeshSeriesData = csStockDataList.GetCursorData() as HySGeoMeshSerial;
                    csStockDataList.MoveCursorNext();

                    HySDataCharacteristicInCell csDataCharacteristic = csGeoDim2MeshSeriesData.GetCellDataCharacteristic();
                    long lDtChNum = csDataCharacteristic.GetDataNumber();
                    for (long lDtChIdx = 0; lDtChIdx < lDtChNum; ++lDtChIdx)
                    {
                        csMergedDataCharacteristicInCell.m_csDataKind[lMergedDataCharacteristicInCellIdx] = csDataCharacteristic.m_csDataKind[lDtChIdx];
                        csMergedDataCharacteristicInCell.m_csLabel[lMergedDataCharacteristicInCellIdx] = csDataCharacteristic.m_csLabel[lDtChIdx];
                        csMergedDataCharacteristicInCell.m_csUnit[lMergedDataCharacteristicInCellIdx] = csDataCharacteristic.m_csUnit[lDtChIdx];
                        ++lMergedDataCharacteristicInCellIdx;
                    }
                }
                csMergedGeoDim2MeshSerialData.SetCellDataCharacteristic(csMergedDataCharacteristicInCell);

                //
                // データ本体をマージ
                // １．最初のデータ種別の時系列データをコピーする
                //
                long lTimeSerialNum = csFirstGeoDim2MeshSerialData.GetCount();
                csFirstGeoDim2MeshSerialData.SetCursorFirst();
                for (long lTimeSerialIdx = 0; lTimeSerialIdx < lTimeSerialNum; ++lTimeSerialIdx)
                {
                    HySGeoDim2MeshData csGeoDim2MeshData = csFirstGeoDim2MeshSerialData.GetCursorData() as HySGeoDim2MeshData;
                    csFirstGeoDim2MeshSerialData.MoveCursorNext();

                    // データ配列数を拡張したマージ用メッシュデータを作成する
                    long lLonDim = csGeoDim2MeshData.GetLonDimension();
                    long lLatDim = csGeoDim2MeshData.GetLatDimension();
                    HySGeoDim2MeshData csMergedGeoDim2MeshData = new HySGeoDim2MeshData(
                        csGeoDim2MeshData.GetDataMeshKind(),
                        lLonDim,
                        lLatDim,
                        lTotalDataCharacteristicNum);


                    // メッシュデータをコピーする
                    HySD2CellArrayData csD2MergedCellArrayData = csMergedGeoDim2MeshData.GetCellArray() as HySD2CellArrayData;
                    HySCellData[,] csMergedCellDataArray = csD2MergedCellArrayData.GetCellData();

                    HySD2CellArrayData csD2CellArrayData = csGeoDim2MeshData.GetCellArray() as HySD2CellArrayData;
                    HySCellData[,] csCellDataArray = csD2CellArrayData.GetCellData();
                    for (long lLonDimIdx = 0; lLonDimIdx < lLonDim; ++lLonDimIdx)
                    {
                        for (long lLatDimIdx = 0; lLatDimIdx < lLatDim; ++lLatDimIdx)
                        {
                            // オリジナルのデータをコピーする
                            HySCellData csMergedCellData = csMergedCellDataArray[lLonDimIdx, lLatDimIdx];
                            HySCellData csCellData = csCellDataArray[lLonDimIdx, lLatDimIdx];

                            long lDim = csCellData.m_lDim;
                            for (long lDimIdx = 0; lDimIdx < lDim; ++lDimIdx)
                            {
                                csMergedCellData.m_dData[lDimIdx] = csCellData.m_dData[lDimIdx];
                            }
                        }
                    }

                    double dUpAlt = 0;
                    double dLwAlt = 0;
                    double dSWLat = 0;
                    double dSWLon = 0;
                    double dNELat = 0;
                    double dNELon = 0;
                    csGeoDim2MeshData.GetAltitude(ref dUpAlt, ref dLwAlt);
                    csGeoDim2MeshData.GetLocation(ref dSWLat, ref dSWLon, ref dNELat, ref dNELon);
                    csMergedGeoDim2MeshData.SetAltitude(dUpAlt, dLwAlt);
                    csMergedGeoDim2MeshData.SetCellDataCharacteristic(csGeoDim2MeshData.GetCellDataCharacteristic());
                    csMergedGeoDim2MeshData.SetCellIDMngData(csGeoDim2MeshData.GetCellIDMngData());
                    csMergedGeoDim2MeshData.SetLocation(dSWLat, dSWLon, dNELat, dNELon);
                    long lPatternNum = csGeoDim2MeshData.GetPatternNumber();
                    csMergedGeoDim2MeshData.SetPatternNumber(lPatternNum);
                    csMergedGeoDim2MeshData.SetPatternDispAlt(csGeoDim2MeshData.GetPatternDispAlt());
                    for (long lPatternIdx = 0; lPatternIdx < lPatternNum; ++lPatternIdx)
                    {
                        csMergedGeoDim2MeshData.SetPattern(lPatternIdx, csGeoDim2MeshData.GetPattern(lPatternIdx));
                    }
                    csMergedGeoDim2MeshData.SetTime(csGeoDim2MeshData.GetLastTime());

                    // 時系列データをマージ先に追加する
                    csMergedGeoDim2MeshSerialData.AddData(csMergedGeoDim2MeshData);
                }

                //
                // ２．2番目以降の時系列データをマージする
                //
                csStockDataList.SetCursorFirst();
                csStockDataList.MoveCursorNext();
                long lDimOfCellOffset = csFirstGeoDim2MeshSerialData.GetCellDataCharacteristic().m_lDim;
                for (long lStockDataIdx = 1; lStockDataIdx < lStockDataCount; ++lStockDataIdx)
                {
                    HySGeoMeshSerial csGeoDim2MeshSeriesData = csStockDataList.GetCursorData() as HySGeoMeshSerial;
                    csStockDataList.MoveCursorNext();

                    csMergedGeoDim2MeshSerialData.SetCursorFirst();
                    csGeoDim2MeshSeriesData.SetCursorFirst();
                    for (long lTimeSerialIdx = 0; lTimeSerialIdx < lTimeSerialNum; ++lTimeSerialIdx)
                    {
                        HySGeoDim2MeshData csGeoDim2MeshData = csGeoDim2MeshSeriesData.GetCursorData() as HySGeoDim2MeshData;
                        csGeoDim2MeshSeriesData.MoveCursorNext();

                        HySGeoDim2MeshData csMergedGeoDim2MeshData = csMergedGeoDim2MeshSerialData.GetCursorData() as HySGeoDim2MeshData;
                        csMergedGeoDim2MeshSerialData.MoveCursorNext();


                        // メッシュデータをマージする
                        HySD2CellArrayData csD2MergedCellArrayData = csMergedGeoDim2MeshData.GetCellArray() as HySD2CellArrayData;
                        HySCellData[,] csMergedCellDataArray = csD2MergedCellArrayData.GetCellData();

                        HySD2CellArrayData csD2CellArrayData = csGeoDim2MeshData.GetCellArray() as HySD2CellArrayData;
                        HySCellData[,] csCellDataArray = csD2CellArrayData.GetCellData();
                        long lLonDim = csGeoDim2MeshData.GetLonDimension();
                        long lLatDim = csGeoDim2MeshData.GetLatDimension();
                        for (long lLonDimIdx = 0; lLonDimIdx < lLonDim; ++lLonDimIdx)
                        {
                            for (long lLatDimIdx = 0; lLatDimIdx < lLatDim; ++lLatDimIdx)
                            {
                                // オリジナルのデータをコピーする
                                HySCellData csMergedCellData = csMergedCellDataArray[lLonDimIdx, lLatDimIdx];
                                HySCellData csCellData = csCellDataArray[lLonDimIdx, lLatDimIdx];

                                long lDim = csCellData.m_lDim;
                                for (long lDimIdx = 0; lDimIdx < lDim; ++lDimIdx)
                                {
                                    csMergedCellData.m_dData[lDimIdx + lDimOfCellOffset] = csCellData.m_dData[lDimIdx];
                                }
                            }
                        }
                    }
                    // マージ先データ配列オフセットを更新する
                    lDimOfCellOffset += csGeoDim2MeshSeriesData.GetCellDataCharacteristic().m_lDim;

                }

                // 出力データを設定する
                csMergedStockData = new HySStockData(new HySObjectKind(), new HySID(""));
                csMergedStockData.SetData(csMergedGeoDim2MeshSerialData);

            }
            catch
            {
                // 予期しない例外が発生した
                //System.Diagnostics.Debug.Print("exception: {0}", ex);
            }

            //// デバッグダンプ(激重注意)
            //DumpGeoDim2MeshSerialData((HySGeoDim2MeshSerialData)csData);

            return csMergedStockData;
        }

        /// <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()
        {
            HySEventObject csEventObj = new HySEventObject(HySSysEvent.OBJID_VIEWER, HySEventObject.CMND_CLOSE_SCREEN);
            csEventObj.SetToSimKind(m_csSimKindID);
            csEventObj.SetSuppID(m_csID);
            csEventObj.SetData(this.GetViewKind());
            csEventObj.SetSubEventNo(HySDispDefine.NOTICE_SCREEN_CLOSE);
            this.PutEvent(csEventObj);
        }

        /// <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 override Boolean EventCallback(HySSysEvent csEvent)
        {
            Boolean bRtn = true;
            HySEventObject csHySEvent = (HySEventObject)csEvent;
            long lEventNo = csHySEvent.GetEventNo();
            HySID csID = csHySEvent.GetSuppID();
            HySObjectKind csSimKind = (HySObjectKind)csHySEvent.GetToSimKind();
            long lEventSubNo = ((HySEventObject)csEvent).GetSubEventNo();
            if (lEventNo == HySEventObject.CMND_DISP_SCREEN)
            {  // 画面表示指示の場合
                m_csContainer = ((HySEventObject)csEvent).GetSubData() as HySContainer;
                if (m_csContainer is HySDataContainer)
                {  // データコンテナが有る場合
                    m_csDBPCtlInfo = m_csContainer.GetData(HySDispDefine.DISPCTL_INFO_KEYS) as HySDispBusiProcedureCtlInfo;
                }
            }
            else if (lEventNo == HySEventObject.CMND_DISPLY_COMMON)
            {  // 画面一般指示（表示更新、検索）の場合
                if (lEventSubNo == HySDispDefine.NOTICE_SCREEN_UPDATE)
                {  // 再表示要求の場合
                    HySContainer csContainer = ((HySEventObject)csEvent).GetSubData() as HySContainer;
                    if (csContainer is HySContainer)
                    {  // データコンテナが添付されていた場合
                        m_csContainer = csContainer;
                    }
                    if (m_csContainer is HySDataContainer)
                    {  // データコンテナが有る場合
                        m_csDBPCtlInfo = m_csContainer.GetData(HySDispDefine.DISPCTL_INFO_KEYS) as HySDispBusiProcedureCtlInfo;
                        if (m_csDBPCtlInfo is HySDispBusiProcedureCtlInfo)
                        {  // 表示業務管理データが有る場合
                            m_csIDList = m_csDBPCtlInfo.GetIDList() as ArrayList;
                        }
                        m_csStockDataList = m_csContainer.GetData(HySDispDefine.STOCKDATALIST_KEYS) as HySStockDataList;
                    }
                    this.RenewScreen();
                }
                if (lEventSubNo == HySDispDefine.NOTICE_SCREEN_CLOSE)
                {  // 子画面終了通知の場合
                    if (m_csContainer is HySDataContainer)
                    {  // データコンテナが有る場合
                        m_csDBPCtlInfo = m_csContainer.GetData(HySDispDefine.DISPCTL_INFO_KEYS) as HySDispBusiProcedureCtlInfo;
                        if (m_csDBPCtlInfo is HySDispBusiProcedureCtlInfo)
                        {  // 表示業務管理データが有る場合
                            if (m_csDBPCtlInfo.GetChildCount() <= 0)
                            {  // 全子画面が終了した場合
                                this.CloseScreen(); // 画面を閉じる
                            }
                            else
                            {  // 子画面が有る場合
                                if (m_csDBPCtlInfo.GetChildCount() == 1)
                                {  // 子画面が1つの場合
                                    if (m_csDBPCtlInfo.GetChildScreenKind(1).Equals(HySDefine.DISP_FORM_SEARCH_CONDITION) == false)
                                    {  // 検索条件設定画面が閉じられた場合
                                        this.CloseScreen(); // 画面を閉じる
                                    }
                                }
                            }
                        }
                    }
                }
            }
            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)
        {
            this.EventCallback(csEvent); // 初期起動イベントを画面に渡す
            if (m_csDBPCtlInfo.GetParentsScreenMode() == HySDispDefine.NOTICE_NO_SEARCH_CONDITION_SCREEN_LATEST)
            {  // 自動検索要求の場合
                HySEventObject csEventObj = new HySEventObject(HySSysEvent.OBJID_BUSIPROCEDURE, HySEventObject.CMND_DISPLY_COMMON);
                csEventObj.SetToSimKind(m_csSimKindID);
                csEventObj.SetSuppID(m_csID);
                csEventObj.SetData(HySDefine.DISP_FORM_SEARCH_CONDITION);
                csEventObj.SetSubEventNo(HySDispDefine.NOTICE_CALC_RESULT_DATA_LIST_REQUEST);
                this.PutEvent(csEventObj);
            }
            else
            {  // 自動検索要求以外の場合
                HySEventObject csEventObj = new HySEventObject(HySSysEvent.OBJID_BUSIPROCEDURE, HySEventObject.CMND_DISP_SCREEN);
                csEventObj.SetToSimKind(m_csSimKindID);
                csEventObj.SetSuppID(m_csID);
                csEventObj.SetData(HySDefine.DISP_FORM_SEARCH_CONDITION);
                csEventObj.SetSubEventNo(HySDispDefine.NOTICE_ONLY_RESULT_SELECTION_NOTIFICATION);
                this.PutEvent(csEventObj);
            }
        }

        #region CellDataMergeデバッグ用

        private void DumpGeoDim2MeshSerialData(HySGeoDim2MeshSerialData csGeoDim2MeshSerialData)
        {
            double dUpAlt = 0;
            double dLwAlt = 0;
            double dSWLat = 0;
            double dSWLon = 0;
            double dNELat = 0;
            double dNELon = 0;
            long lAltDimension;
            long lDataDimentionInCell;
            long lLatDimension;
            long lLonDimension;
            long lPatternNumber;
            long lCount;
            HySGeoMesh.MESH_DATA_KIND eGeoMeshKind;
            HySDataCharacteristicInCell csDataCharacteristicInCell;
            HySCellIDManageData csCellIDMngData;
            List<HySGeoMeshDispPattern> csPatternList = new List<HySGeoMeshDispPattern>();
            List<HySGeoDim2MeshData> csGeoDim2MeshDataList = new List<HySGeoDim2MeshData>();

            lAltDimension = csGeoDim2MeshSerialData.GetAltDimension();
            csGeoDim2MeshSerialData.GetAltitude(ref dUpAlt, ref dLwAlt);
            csDataCharacteristicInCell = csGeoDim2MeshSerialData.GetCellDataCharacteristic();
            csCellIDMngData = csGeoDim2MeshSerialData.GetCellIDMngData();
            lDataDimentionInCell = csGeoDim2MeshSerialData.GetDataDimentionInCell();
            eGeoMeshKind = csGeoDim2MeshSerialData.GetDataMeshKind();
            lLatDimension = csGeoDim2MeshSerialData.GetLatDimension();
            csGeoDim2MeshSerialData.GetLocation(ref dSWLat, ref dSWLon, ref dNELat, ref dNELon);
            lLonDimension = csGeoDim2MeshSerialData.GetLonDimension();
            lPatternNumber = csGeoDim2MeshSerialData.GetPatternNumber();
            for (long lPtnIdx = 0; lPtnIdx < lPatternNumber; ++lPtnIdx)
            {
                csPatternList.Add(csGeoDim2MeshSerialData.GetPattern(lPtnIdx));
            }
            lCount = csGeoDim2MeshSerialData.GetCount();
            csGeoDim2MeshSerialData.SetCursorFirst();
            for (long lDataIdx = 0; lDataIdx < lCount; ++lDataIdx)
            {
                HySGeoDim2MeshData csData = (HySGeoDim2MeshData)csGeoDim2MeshSerialData.GetCursorData();
                csGeoDim2MeshSerialData.MoveCursorNext();

                csGeoDim2MeshDataList.Add(csData);
            }

            string myLabel = "HySGeoDim2MeshSerialData";
            LogOut(myLabel, "dUpAlt={0}, dLwAlt={1}", dUpAlt, dLwAlt);
            LogOut(myLabel, "dSWLat={0}, dSWLon={1}, dNELat={2}, dNELon={3}", dSWLon, dSWLon, dNELat, dNELon);
            LogOut(myLabel, "lAltDimension={0}", lAltDimension);
            LogOut(myLabel, "lLatDimension={0}", lLatDimension);
            LogOut(myLabel, "lLonDimension={0}", lLonDimension);
            LogOut(myLabel, "lPatternNumber={0}", lPatternNumber);
            LogOut(myLabel, "lDataDimentionInCell={0}", lDataDimentionInCell);
            LogOut(myLabel, "lCount={0}", lCount);
            LogOut(myLabel, "eGeoMeshKind={0}", eGeoMeshKind);

            DumpDataCharacteristicInCell("HySGeoDim2MeshSerialData", csDataCharacteristicInCell);
            DumpPatternList("HySGeoDim2MeshSerialData", csPatternList);
            DumpMeshDataList("HySGeoDim2MeshSerialData", csGeoDim2MeshDataList);
        }

        private void DumpMeshDataList(string parentLabel, List<HySGeoDim2MeshData> csGeoDim2MeshDataList)
        {
            string myLabelBase = parentLabel + ".GeoDim2MeshData";
            int n = csGeoDim2MeshDataList.Count;
            for (int i = 0; i < n; ++i)
            {
                double dUpAlt = 0;
                double dLwAlt = 0;
                double dSWLat = 0;
                double dSWLon = 0;
                double dNELat = 0;
                double dNELon = 0;
                long lAltDimension;
                long lDataDimentionInCell;
                long lLatDimension;
                long lLonDimension;
                long lPatternNumber;
                //long lCount;
                HySDataCharacteristicInCell csDataCharacteristicInCell;
                List<HySGeoMeshDispPattern> csPatternList = new List<HySGeoMeshDispPattern>();
                HySTime csLastTime;
                HySCellArray csCellArray;

                string myLabel = myLabelBase + string.Format("[{0}]", i);
                HySGeoDim2MeshData csData = csGeoDim2MeshDataList[i];
                csData.GetAltitude(ref dUpAlt, ref dLwAlt);
                csData.GetLocation(ref dSWLat, ref dSWLon, ref dNELat, ref dNELon);
                lAltDimension = csData.GetAltDimension();
                lDataDimentionInCell = csData.GetDataDimentionInCell();
                lLatDimension = csData.GetLatDimension();
                lLonDimension = csData.GetLonDimension();
                lPatternNumber = csData.GetPatternNumber();
                for (long lPtnIdx = 0; lPtnIdx < lPatternNumber; ++lPtnIdx)
                {
                    csPatternList.Add(csData.GetPattern(lPtnIdx));
                }
                csDataCharacteristicInCell = csData.GetCellDataCharacteristic();
                csCellArray = csData.GetCellArray();
                csLastTime = csData.GetLastTime();

                LogOut(myLabel, "LastTime={0}", HySCalendar.GetString(csLastTime, HySCalendar.FORMAT.lSW_YEAR).ToString());
                LogOut(myLabel, "dUpAlt={0}, dLwAlt={1}", dUpAlt, dLwAlt);
                LogOut(myLabel, "dSWLat={0}, dSWLon={1}, dNELat={2}, dNELon={3}", dSWLon, dSWLon, dNELat, dNELon);
                LogOut(myLabel, "lAltDimension={0}", lAltDimension);
                LogOut(myLabel, "lLatDimension={0}", lLatDimension);
                LogOut(myLabel, "lLonDimension={0}", lLonDimension);
                LogOut(myLabel, "lPatternNumber={0}", lPatternNumber);
                LogOut(myLabel, "lDataDimentionInCell={0}", lDataDimentionInCell);

                DumpDataCharacteristicInCell(myLabel, csDataCharacteristicInCell);
                DumpPatternList(myLabel, csPatternList);
                DumpCellArray(myLabel, csCellArray);
            }
        }

        private void DumpCellArray(string parentLabel, HySCellArray csCellArray)
        {
            string myLabelBase = parentLabel + ".CellArray";
            long lDim1 = csCellArray.GetDimension1();
            long lDim2 = csCellArray.GetDimension2();
            for (long lDim1Idx = 0; lDim1Idx < lDim1; ++lDim1Idx)
            {
                for (long lDim2Idx = 0; lDim2Idx < lDim2; ++lDim2Idx)
                {
                    string myLabel = myLabelBase + string.Format("[{0}][{1}]", lDim1Idx, lDim2Idx);
                    HySCellData csData = csCellArray.GetCell(lDim1Idx, lDim2Idx);

                    LogOut(myLabel, "m_lDim={0}", csData.m_lDim);
                    for (long lDtIdx = 0; lDtIdx < csData.m_lDim; ++lDtIdx)
                    {
                        LogOut(myLabel, ".Data[{0}]={1}", lDtIdx, csData.m_dData[lDtIdx]);
                    }
                }
            }
            throw new Exception("The method or operation is not implemented.");
        }

        private void DumpPatternList(string parentLabel, List<HySGeoMeshDispPattern> csPatternList)
        {
            string myLabelBase = parentLabel + ".GeoMeshDispPattern";
            int n = csPatternList.Count;
            for (int i = 0; i < n; ++i)
            {
                short sLineR = 0;
                short sLineG = 0;
                short sLineB = 0;
                short sPolyR = 0;
                short sPolyG = 0;
                short sPolyB = 0;
                short sSymR = 0;
                short sSymG = 0;
                short sSymB = 0;
                string myLabel = myLabelBase + string.Format("[{0}]", i);
                HySGeoMeshDispPattern csData = csPatternList[i];
                csData.GetLineColor(ref sLineR, ref sLineG, ref sLineB);
                csData.GetPolyColor(ref sPolyR, ref sPolyG, ref sPolyB);
                csData.GetSymbolColor(ref sPolyR, ref sPolyG, ref sPolyB);
                LogOut(myLabel, "AltMode={0}", csData.GetAltMode());
                LogOut(myLabel, "ExtrudeMode={0}", csData.GetExtrudeMode());
                LogOut(myLabel, "FillStyle={0}", csData.GetFillStyle());
                LogOut(myLabel, "LineColor: R={0}, G={1}, B={2}", sLineR, sLineG, sLineB);
                LogOut(myLabel, "LineTransparency={0}", csData.GetLineTransparency());
                LogOut(myLabel, "LineWidth={0}", csData.GetLineWidth());
                LogOut(myLabel, "PatternName={0}", csData.GetPatternName());
                LogOut(myLabel, "PolyColor: R={0}, G={1}, B={2}", sPolyR, sPolyG, sPolyB);
                LogOut(myLabel, "PolyTransparency={0}", csData.GetPolyTransparency());
                LogOut(myLabel, "SymbolColor: R={0}, G={1}, B={2}", sSymR, sSymG, sSymB);
                LogOut(myLabel, "SymbolTransparency={0}", csData.GetSymbolTransparency());
                LogOut(myLabel, "TessellateMode={0}", csData.GetTessellateMode());
            }
        }

        private void DumpDataCharacteristicInCell(string parentLabel, HySDataCharacteristicInCell csDataCharacteristicInCell)
        {
            string myLabel = parentLabel + ".DataCharacteristicInCell";
            LogOut(myLabel, "m_lDim={0}", csDataCharacteristicInCell.m_lDim);
            for (long lDimIdx = 0; lDimIdx < csDataCharacteristicInCell.m_lDim; ++lDimIdx)
            {
                LogOut(myLabel, "[{0}].DataKind={1}", lDimIdx, csDataCharacteristicInCell.m_csDataKind[lDimIdx].ToString());
                LogOut(myLabel, "[{0}].Label={1}", lDimIdx, csDataCharacteristicInCell.m_csLabel[lDimIdx]);
                LogOut(myLabel, "[{0}].Unit={1}", lDimIdx, csDataCharacteristicInCell.m_csUnit[lDimIdx]);
            }
        }

        private void LogOut(string dataLabel, string format, params object[] args)
        {
            HySLog.LogOut(HySLog.ONLINE, dataLabel + ": " + string.Format(format, args));
        }

        #endregion
    }
}
