// <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][2009/05/01][新規作成]</para>
    /// <para>remarks:</para>
    /// <para>地理空間上に表示する幾何学図形</para>
    /// </remarks>
    [Serializable]
    public abstract class HySGeometry : HySDataRoot, HySVersionManagement
    {
        /// <summary>個別図形識別子 </summary>
        protected HySID m_csID = null;

        // 表示属性：図形によっては　使用しない属性もある
        /// <summary>線色：Ｒ：０～２５５ </summary>
        protected short m_sLineColorR = 128;
        /// <summary>線色：Ｇ：０～２５５ </summary>
        protected short m_sLineColorG = 128;
        /// <summary>線色：Ｂ：０～２５５ </summary>
        protected short m_sLineColorB = 128;
        /// <summary>線透明度：０～２５５、 ０の時完全透明、２５５の時完全不透明</summary>
        protected short m_sLineAlpha = 255;

        /// <summary>面色：Ｒ：０～２５５ </summary>
        protected short m_sPolyColorR = 128;
        /// <summary>面色：Ｇ：０～２５５ </summary>
        protected short m_sPolyColorG = 128;
        /// <summary>面色：Ｂ：０～２５５ </summary>
        protected short m_sPolyColorB = 128;
        /// <summary>面透明度：０～２５５、 ０の時完全透明、２５５の時完全不透明</summary>
        protected short m_sPolyAlpha = 255;

        /// <summary>シンボル色：Ｒ：０～２５５ </summary>
        protected short m_sSymbolColorR = 128;
        /// <summary>シンボル色：Ｇ：０～２５５ </summary>
        protected short m_sSymbolColorG = 128;
        /// <summary>シンボル色：Ｂ：０～２５５ </summary>
        protected short m_sSymbolColorB = 128;
        /// <summary>シンボル透明度：０～２５５、 ０の時完全透明、２５５の時完全不透明</summary>
        protected short m_sSymbolAlpha = 255;

        /// <summary>塗り潰し定義 </summary>
        public enum FillStyle
        {
            /// <summary>塗り潰し</summary>
            FILL = 1,
            /// <summary>塗り潰しなし</summary>
            BLANK,
            /// <summary>ハッチング（ＧＩＳ ＣＯＴＳによっては表示できないこともある。この場合、FILLで表示する）</summary>
            HATCH
        }
        /// <summary>塗り潰しパターン番号</summary>
        protected FillStyle m_eFillStyle = FillStyle.BLANK;

        /// <summary>線幅(ピクセル単位) </summary>
        protected short m_sLineWidth = 3;

        /// <summary>高度設定モード</summary>
        protected AltMode m_eAltMode = AltMode.RELATIVE_GND;
        /// <summary>高度設定モードの定義</summary>
        public enum AltMode
        {
            /// <summary>海抜</summary>
            ABSOLUTE = 1,
            /// <summary>地面相対</summary>
            RELATIVE_GND,
            /// <summary>高度指定を無視（地面張り付き表示：２Ｄ表示）</summary>
            CLAMP_TO_GND

        }

        /// <summary>地面からの突き出しモード（true:地面から押し出された３次元物体となる）</summary>
        protected bool m_bExtrudeMode = true;
        /// <summary>地面に沿った表示を行うモード（m_eAltMode = AltMode.RELATIVE_GNDの時のみ有効）
        /// 図形が非常に大きいときには、地球の湾曲に沿って表示する場合に必要になる。
        /// </summary>
        protected bool m_bTessellateMode = true;

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeometry csGeometry = new HySGeometry()  </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySGeometry 生成されたクラスのインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected HySGeometry()
        {
            //バージョン情報設定
            SetNowVersion();
        }

        /// <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(HySID csID)
        {
            m_csID = (HySID)csID;
        }
        /// <summary><para>method outline:</para>
        /// <para>識別子取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySID csIdentifier = GetID( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>識別子</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySID GetID()
        {
            return m_csID;
        }

        /// <summary><para>method outline:</para>
        /// <para>線色情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetLineColor(sR,sG,sB) </para>
        /// </example>
        /// <param name="sR">赤</param>
        /// <param name="sG">緑</param>
        /// <param name="sB">青</param> 
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetLineColor(short sR, short sG, short sB)
        {
            m_sLineColorR = sR;
            m_sLineColorG = sG;
            m_sLineColorB = sB;
        }
        /// <summary><para>method outline:</para>
        /// <para>線色情報取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> GetLineColor(ref sR,ref sG,ref sB) </para>
        /// </example>
        /// <param name="sR">赤</param>
        /// <param name="sG">緑</param>
        /// <param name="sB">青</param> 
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>設定値の有効範囲は０～２５５です。</para>
        /// </remarks>
        public void GetLineColor(ref short sR, ref short sG, ref short sB)
        {
            sR = m_sLineColorR;
            sG = m_sLineColorG;
            sB = m_sLineColorB;
        }

        /// <summary><para>method outline:</para>
        /// <para>面色情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetPolyColor(sR,sG,sB) </para>
        /// </example>
        /// <param name="sR">赤</param>
        /// <param name="sG">緑</param>
        /// <param name="sB">青</param> 
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>設定値の有効範囲は０～２５５です。</para>
        /// </remarks>
        public void SetPolyColor(short sR, short sG, short sB)
        {
            m_sPolyColorR = sR;
            m_sPolyColorG = sG;
            m_sPolyColorB = sB;
        }
        /// <summary><para>method outline:</para>
        /// <para>面色情報取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> GetPolyColor(ref sR,ref sG,ref sB) </para>
        /// </example>
        /// <param name="sR">赤</param>
        /// <param name="sG">緑</param>
        /// <param name="sB">青</param> 
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void GetPolyColor(ref short sR, ref short sG, ref short sB)
        {
            sR = m_sPolyColorR;
            sG = m_sPolyColorG;
            sB = m_sPolyColorB;
        }
        /// <summary><para>method outline:</para>
        /// <para>シンボル色情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetSymbolColor(sR,sG,sB) </para>
        /// </example>
        /// <param name="sR">赤</param>
        /// <param name="sG">緑</param>
        /// <param name="sB">青</param> 
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>設定値の有効範囲は０～２５５です。</para>
        /// </remarks>
        public void SetSymbolColor(short sR, short sG, short sB)
        {
            m_sSymbolColorR = sR;
            m_sSymbolColorG = sG;
            m_sSymbolColorB = sB;
        }
        /// <summary><para>method outline:</para>
        /// <para>シンボル色情報取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> GetSymbolColor(ref sR,ref sG,ref sB) </para>
        /// </example>
        /// <param name="sR">赤</param>
        /// <param name="sG">緑</param>
        /// <param name="sB">青</param> 
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void GetSymbolColor(ref short sR, ref short sG, ref short sB)
        {
            sR = m_sSymbolColorR;
            sG = m_sSymbolColorG;
            sB = m_sSymbolColorB;
        }

        /// <summary><para>method outline:</para>
        /// <para>線透明度設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetLineTransparency(sAlpha) </para>
        /// </example>
        /// <param name="sAlpha">線透明度</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>設定値の有効範囲は０～２５５（０の時完全透明、２５５の時完全不透明）です。</para>
        /// </remarks>
        public void SetLineTransparency(short sAlpha)
        {
            m_sLineAlpha = sAlpha;
        }
        /// <summary><para>method outline:</para>
        /// <para>線透明度取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> short sValue = GetLineTransparency() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>線透明度</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public short GetLineTransparency()
        {
            return m_sLineAlpha;
        }

        /// <summary><para>method outline:</para>
        /// <para>面透明度設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetPolyTransparency(sAlpha) </para>
        /// </example>
        /// <param name="sAlpha">面透明度</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>設定値の有効範囲は０～２５５（０の時完全透明、２５５の時完全不透明）です。</para>
        /// </remarks>
        public void SetPolyTransparency(short sAlpha)
        {
            m_sPolyAlpha = sAlpha;
        }
        /// <summary><para>method outline:</para>
        /// <para>面透明度取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> short sValue = GetPolyTransparency() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>面透明度</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public short GetPolyTransparency()
        {
            return m_sPolyAlpha;
        }

        /// <summary><para>method outline:</para>
        /// <para>シンボル透明度設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetSymbolTransparency(sAlpha) </para>
        /// </example>
        /// <param name="sAlpha">シンボル透明度</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>設定値の有効範囲は０～２５５（０の時完全透明、２５５の時完全不透明）です。</para>
        /// </remarks>
        public void SetSymbolTransparency(short sAlpha)
        {
            m_sSymbolAlpha = sAlpha;
        }
        /// <summary><para>method outline:</para>
        /// <para>シンボル透明度取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> short sValue = GetSymbolTransparency() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>シンボル透明度</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public short GetSymbolTransparency()
        {
            return m_sSymbolAlpha;
        }

        /// <summary><para>method outline:</para>
        /// <para>塗り潰しパターン番号を設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetFillStyle(elType)</para>
        /// </example>
        /// <param name="eType">塗り潰しパターン番号</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public  void SetFillStyle(FillStyle eType)
        {
            m_eFillStyle = eType;
        }
        /// <summary><para>method outline:</para>
        /// <para>塗り潰しパターン番号取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>FillStyle eType = GetFillStyle()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>塗り潰しパターン番号</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public  FillStyle GetFillStyle()
        { 
            return m_eFillStyle; 
        }

        /// <summary><para>method outline:</para>
        /// <para>線幅を設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetLineWidth(sWidth)</para>
        /// </example>
        /// <param name="sWidth">線幅</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetLineWidth(short sWidth)
        {
            m_sLineWidth = sWidth;
        }
        /// <summary><para>method outline:</para>
        /// <para>線幅取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>short sWidth = GetLineWidth()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>線幅</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public short GetLineWidth()
        {
            return m_sLineWidth;
        }

        /// <summary><para>method outline:</para>
        /// <para>高度設定モードを設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetAltMode(eAltMode)</para>
        /// </example>
        /// <param name="eAltMode">高度設定モード</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetAltMode(AltMode eAltMode)
        {
            m_eAltMode = eAltMode;
        }
        /// <summary><para>method outline:</para>
        /// <para>高度設定モード取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>AltMode eAltMode = GetAltMode()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>高度設定モード</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public AltMode GetAltMode()
        {
            return m_eAltMode;
        }

        /// <summary><para>method outline:</para>
        /// <para>地面からの突き出しモードを設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetExtrudeMode(bExMode)</para>
        /// </example>
        /// <param name="bExMode">地面からの突き出しモード</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>true:モードON, false:モードOFF</para>
        /// </remarks>
        public void SetExtrudeMode(bool bExMode)
        {
            m_bExtrudeMode = bExMode;
        }
        /// <summary><para>method outline:</para>
        /// <para>地面からの突き出しモード取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bExMode = GetExtrudeMode()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>地面からの突き出しモード</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>true:モードON, false:モードOFF</para>
        /// </remarks>
        public bool GetExtrudeMode()
        {
            return m_bExtrudeMode;
        }

        /// <summary><para>method outline:</para>
        /// <para>地面に沿った表示を行うモードを設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetTessellateMode(bTesMode)</para>
        /// </example>
        /// <param name="bTesMode">地面に沿った表示を行うモード</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>true:モードON, false:モードOFF</para>
        /// </remarks>
        public void SetTessellateMode(bool bTesMode)
        {
            m_bTessellateMode = bTesMode;
        }
        /// <summary><para>method outline:</para>
        /// <para>地面に沿った表示を行うモード取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bTesMode = GetTessellateMode()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>地面に沿った表示を行うモード</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>true:モードON, false:モードOFF</para>
        /// </remarks>
        public bool GetTessellateMode()
        {
            return m_bTessellateMode;
        }

        /// <summary><para>method outline:</para>
        /// <para>データのコピー</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> DataCopy(csOrgData) </para>
        /// </example>
        /// <param name="csOrgData">コピー元データ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void DataCopy(HySGeometry csOrgData)
        {
            m_csID = csOrgData.m_csID.Clone();
            m_sLineColorR = csOrgData.m_sLineColorR;
            m_sLineColorG = csOrgData.m_sLineColorG;
            m_sLineColorB = csOrgData.m_sLineColorB;
            m_sLineAlpha = csOrgData.m_sLineAlpha;
            m_sPolyColorR = csOrgData.m_sPolyColorR;
            m_sPolyColorG = csOrgData.m_sPolyColorG;
            m_sPolyColorB = csOrgData.m_sPolyColorB;
            m_sPolyAlpha = csOrgData.m_sPolyAlpha;
            m_sSymbolColorR = csOrgData.m_sSymbolColorR;
            m_sSymbolColorG = csOrgData.m_sSymbolColorG;
            m_sSymbolColorB = csOrgData.m_sSymbolColorB;
            m_sSymbolAlpha = csOrgData.m_sSymbolAlpha;
            m_eFillStyle = csOrgData.m_eFillStyle;
            m_sLineWidth = csOrgData.m_sLineWidth;
            m_eAltMode = csOrgData.m_eAltMode;
            m_bExtrudeMode = csOrgData.m_bExtrudeMode;
            m_bTessellateMode = csOrgData.m_bTessellateMode;
        }

        // ================================================
        //   バージョンアップ時の下位互換性を保つ為の処理
        // ================================================
        /// <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();
        }
    }
}
