// <summary>ソースコード：背景地図情報 データクラス<</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

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

namespace CommonMP.HYSSOP.CoreImpl.HSData
{
    /// <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>
    /// <para>Remarks</para>
    /// <para>なし</para>
    /// </remarks>
    [Serializable]
    public class HySGeoBaseMapData : HySDataRoot, HySVersionManagement
    {
        // 注視点 FocusPoint
        /// <summary>注視点位置</summary>
        protected HySGeoPoint m_csFocusPoint = new HySGeoPoint(360.0, 360.0, -10000.0);
        //// <summary>注視点緯度（度）</summary>
        //protected double m_dFocusLat = 360.0;
        //// <summary>注視点経度(度）</summary>
        //protected double m_dFocusLon = 360.0;
        //// <summary>注視点高度（ｍ）FocusPointAltitude</summary>
        //protected double m_dFocusAlt = -10000.0;
        /// <summary>注視点高度設定モード</summary>
        protected FoucusPntAltMode m_eFoucusAltMode = FoucusPntAltMode.RELATIVE_GND;
        /// <summary>注視点高度設定モードの定義　FocusPointAltitudeMode</summary>
        public enum FoucusPntAltMode
        {
            /// <summary>海抜</summary>
            ABSOLUTE = 1,
            /// <summary>地面相対</summary>
            RELATIVE_GND  

        }
        

        // 視点（カメラ位置）　２次元地図の場合には無効
        /// <summary>距離（ｍ）</summary>
        protected double m_dRange=-10000.0;
        /// <summary>天頂角（度）注視点から視点へのベクトルが垂直線となす角度　真上０、水平０</summary>
        protected long m_lTilt=0;
        /// <summary>方位角（度）注視点が北＝０度　時計回りに－１８０～＋１８０</summary>
        protected long m_lAzimuth=0;

        // 縮尺
        /// <summary>縮尺(1/m_lScale) カメラ位置指定がない場合に有効（２次元地図の場合）</summary>
        protected long m_lScale = 25000;

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeoBaseMapData csBaseMapData
        /// = new HySGeoBaseMapData( dLat,dLon,lScale) 
        /// </para>
        /// </example>
        /// <param name="dLat">注視点緯度（度）</param>
        /// <param name="dLon">注視点経度（度）</param>
        /// <param name="lScale">縮尺</param>
        /// <returns>生成インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySGeoBaseMapData(double dLat, double dLon,long lScale)
        {
            m_csFocusPoint.m_dLatitude = dLat;
            m_csFocusPoint.m_dLongitude = dLon;
            m_lScale = lScale;
            //バージョン情報設定
            SetNowVersion();
        }

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeoBaseMapData csBaseMapData
        /// = new HySGeoBaseMapData( dLat,dLon,dRange,lTilt,lAzimuth) 
        /// </para>
        /// </example>
        /// <param name="dLat">注視点緯度（度）</param>
        /// <param name="dLon">注視点経度（度）</param>
        /// <param name="dRange">距離（ｍ）</param>
        /// <param name="lTilt">天頂角（度）</param>        
        /// <param name="lAzimuth">方位角（度）</param>
        /// <returns>生成インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySGeoBaseMapData(double dLat, double dLon,double dRange,long lTilt,long lAzimuth)
        {
            m_csFocusPoint.m_dLatitude = dLat;
            m_csFocusPoint.m_dLongitude = dLon;

            m_dRange = dRange;
            m_lTilt = lTilt;
            m_lAzimuth = lAzimuth;
            //バージョン情報設定
            SetNowVersion();
        }

        /// <summary><para>method outline:</para>
        /// <para>注視点位置設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetFocusPoint(csFocusPoint)
        /// </para>
        /// </example>     
        /// <param name="csFocusPoint">注視点位置</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetFocusPoint(HySGeoPoint csFocusPoint)
        {
            m_csFocusPoint.m_dLatitude = csFocusPoint.m_dLatitude;
            m_csFocusPoint.m_dLongitude = csFocusPoint.m_dLongitude;
            m_csFocusPoint.m_dAltitude = csFocusPoint.m_dAltitude;
        }
        /// <summary><para>method outline:</para>
        /// <para>注視点座標取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeoPoint csFcsPnt = GetFocusPoint() 
        /// </para>
        /// </example>     
        /// <param name="">無し</param>
        /// <returns>注視点座標</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySGeoPoint GetFocusPoint()
        {
            return m_csFocusPoint;
        }

        /// <summary><para>method outline:</para>
        /// <para>注視点高度設定モード設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetFoucusPntAltMode(eFcsPntAltMode) 
        /// </para>
        /// </example>     
        /// <param name="eFcsPntAltMode">注視点高度設定モード</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public  void SetFoucusPntAltMode(FoucusPntAltMode eFcsPntAltMode)
        {
            m_eFoucusAltMode = eFcsPntAltMode;
        }
        /// <summary><para>method outline:</para>
        /// <para>注視点高度設定モード取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> FoucusPntAltMode eFcsAltMode = GetFoucusPntAltMode() 
        /// </para>
        /// </example>     
        /// <param name="">無し</param>
        /// <returns>注視点高度設定モード</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public FoucusPntAltMode GetFoucusPntAltMode()
        {
            return m_eFoucusAltMode;
        }

        /// <summary><para>method outline:</para>
        /// <para>カメラ位置設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetCamera( dRange, lTilt, lAzimuth) 
        /// </para>
        /// </example>
        /// <param name="dRange">距離（ｍ）</param>
        /// <param name="lTilt">天頂角（度）</param>        
        /// <param name="lAzimuth">方位角（度）</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetCamera( double dRange,  long lTilt,  long lAzimuth)
        {
            this.m_dRange =dRange;
            this.m_lTilt =lTilt;
            this.m_lAzimuth =lAzimuth;
        }
        /// <summary><para>method outline:</para>
        /// <para>カメラ位置取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> GetCamera( ref dRange,ref lTilt,ref lAzimuth) 
        /// </para>
        /// </example>
        /// <param name="dRange">距離（ｍ）</param>
        /// <param name="lTilt">天頂角（度）</param>        
        /// <param name="lAzimuth">方位角（度）</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void GetCamera(ref double dRange, ref long lTilt, ref long lAzimuth)
        {
            dRange = this.m_dRange;
            lTilt = this.m_lTilt;
            lAzimuth = this.m_lAzimuth;
        }

        /// <summary><para>method outline:</para>
        /// <para>縮尺設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetScale( lScale) 
        /// </para>
        /// </example>
        /// <param name="lScale">縮尺</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetScale(long lScale)
        {
            this.m_lScale = lScale;
        }
        /// <summary><para>method outline:</para>
        /// <para>縮尺取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> long lScale = GetScale() 
        /// </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>縮尺</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public long GetScale()
        {
            return this.m_lScale;
        }

        // ================================================
        //   バージョンアップ時の下位互換性を保つ為の処理
        // ================================================

        /// <summary>保存バージョン情報</summary>
        private string m_sDecodedVersion;

        /// <summary><para>method outline:</para>
        /// <para>バージョン情報取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> string sDecodedVersion = GetDecodedVersion()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>string 保存バージョン情報</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>メンバー変数に設定されているバージョン情報を返す</para>
        /// </remarks>
        public string GetDecodedVersion()
        {
            return m_sDecodedVersion;
        }

        /// <summary><para>method outline:</para>
        /// <para>バージョン情報取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> string sVersion = GetNowVersion()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>string 現在のバージョン情報</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public string GetNowVersion()
        {
            return "1.00";
        }

        /// <summary><para>method outline:</para>
        /// <para>バージョン情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetNowVersion()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>現在のバージョン情報をメンバー変数に設定する</para>
        /// </remarks>
        public void SetNowVersion()
        {
            m_sDecodedVersion = GetNowVersion();
        }

        /// <summary><para>method outline:</para>
        /// <para>復元後の整合性確保処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> PostDeserialize( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>シリアライズされた旧バージョン情報を復元する際、過去の整合性をとる時に使用する
        /// バージョンによって変数等追加がない場合には、実装の必要がない
        /// </para>
        /// </remarks>
        public virtual void PostDeserialize()
        {
            if (GetDecodedVersion() != GetNowVersion())
            {
                //旧バージョンから順にバージョンを上げて行く
                switch (GetDecodedVersion())
                {
                    case "1.00":
                        break;
                }
                SetNowVersion();
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>逆シリアル化時追加処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> IDeserializationCallback.OnDeserialization(csObj)</para>
        /// </example>
        /// <param name="csObj">ダミー</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>予約処理</para>
        /// </remarks>
        void IDeserializationCallback.OnDeserialization(Object csObj)
        {
            PostDeserialize();
        }
    }
}
