// <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>remarks:</para>
    /// <para>無し</para>
    /// </remarks>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/05/01][新規作成]</para>
    /// </remarks>
    [Serializable]
    public class HySGeoRiverCrossSectionData : HySDataRoot, HySVersionManagement
    {
        /// <summary>最小ｘ座標値</summary>
        private double m_dMinCoordinate = 0.0;
        /// <summary>最大ｘ座標値</summary>
        private double m_dMaxCoordinate = 0.0;

        /// <summary>河川コード</summary>
        private HySString m_csRiverCode;
        /// <summary>河川名</summary>
        private HySString m_csRiverName;
        /// <summary>補助河川コード</summary>
        private HySString m_csAuxRiverCode;
        /// <summary>距離標</summary>
        private HySString m_csDistancePost;
        /// <summary>断面ID</summary>
        private HySGeoRiverCrossSectionID m_csID;
        /// <summary>河川距離標</summary>
        private HySGeoRiverDistancePost m_csGeoRiverDistancePost;
        /// <summary>断面形状</summary>
        private HySGeoRiverCrossSectionShape m_csSectionShape;
        /// <summary>断面属性リスト</summary>
        private HySDataLinkedList m_csSectionAttribute = new HySDataLinkedList();
        /// <summary>ポイント属性テーブル</summary>
        private HySDataHashTable m_csPointAttributes = new HySDataHashTable();
        /// <summary>ライン属性テーブル</summary>
        private HySDataHashTable m_csLineAttributes = new HySDataHashTable();

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeoRiverCrossSectionData csSectionData = new HySGeoRiverCrossSectionData(csID) </para>
        /// </example>
        /// <param name="csID">断面ID</param>
        /// <returns>HySGeoRiverCrossSectionData 生成したインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySGeoRiverCrossSectionData(HySString csID)
        {
            //バージョン情報設定
            SetNowVersion();

            m_csID = new HySGeoRiverCrossSectionID(csID);

        }

        /// <summary><para>method outline:</para>
        /// <para>河川コード設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetRiverCode( csCode ) </para>
        /// </example>
        /// <param name="csCode">河川コード</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetRiverCode(HySString csCode)
        {
            m_csRiverCode = csCode;
        }

        /// <summary><para>method outline:</para>
        /// <para>河川コード取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csRiverCode = GetRiverCode( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>河川コード</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySString GetRiverCode()
        {
            return m_csRiverCode;
        }

        /// <summary><para>method outline:</para>
        /// <para>河川名設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetRiverName( csName ) </para>
        /// </example>
        /// <param name="csName">河川名</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetRiverName(HySString csName)
        {
            m_csRiverName = csName;
        }

        /// <summary><para>method outline:</para>
        /// <para>河川名取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csRiverName = GetRiverName( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>河川名</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySString GetRiverName()
        {
            return m_csRiverName;
        }

        /// <summary><para>method outline:</para>
        /// <para>補助河川コード設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetAuxRiverCode( csCode ) </para>
        /// </example>
        /// <param name="csCode">補助河川コード</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetAuxRiverCode(HySString csCode)
        {
            m_csAuxRiverCode = csCode;
        }

        /// <summary><para>method outline:</para>
        /// <para>補助河川コード取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csAuxRiverCode = GetAuxRiverCode( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>補助河川コード</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySString GetAuxRiverCode()
        {
            return m_csAuxRiverCode;
        }

        /// <summary><para>method outline:</para>
        /// <para>距離標設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetDistancePost( csDistancePost ) </para>
        /// </example>
        /// <param name="csDistancePost">距離標</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetDistancePost(HySString csDistancePost)
        {
            m_csDistancePost = csDistancePost;
        }

        /// <summary><para>method outline:</para>
        /// <para>距離標取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csDistancePost = GetDistancePost( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>距離標</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySString GetDistancePost()
        {
            return m_csDistancePost;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面ID取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeoRiverCrossSectionID csID = GetID() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>断面ID</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySGeoRiverCrossSectionID GetID()
        {
            return m_csID;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面X座標最小値取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> double dMinCoordinate = GetMinXCoordinate( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>断面X座標最小値 </returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>断面形状の構成点が無い場合は0.0を返却する</para>
        /// </remarks>
        public double GetMinXCoordinate()
        {
            if (m_csSectionShape == null)
            {   // 断面形状構成点未設定
                return m_dMinCoordinate;
            }
            HySDataLinkedList csShape = m_csSectionShape.GetShapePoints();
            if (csShape.GetCount() == 0)
            {   // 断面形状構成点無し
                return m_dMinCoordinate;
            }

            // 構成点リストの最初の点のX座標を最小値に設定しておく
            csShape.SetCursorFirst();
            double dMinVal = ((HySGeoRiverCrossSectionShapePoint)csShape.GetFirstData()).GetXValue();
            csShape.MoveCursorNext();
            long lCount = csShape.GetCount() - 1;
            for (int i = 0; i < lCount; i++)
            {
                HySGeoRiverCrossSectionShapePoint csPoint = (HySGeoRiverCrossSectionShapePoint)csShape.GetCursorData();
                if (csPoint.GetXValue() < dMinVal)
                {   // 現在の最小X座標より小さい場合
                    dMinVal = csPoint.GetXValue();
                }
                csShape.MoveCursorNext();
            }

            return dMinVal;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面X座標最大値取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> double dMaxCoordinate = GetMaxXCoordinate( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>断面X座標最大値 </returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>断面形状の構成点が無い場合は0.0を返却する</para>
        /// </remarks>
        public double GetMaxXCoordinate()
        {
            if (m_csSectionShape == null)
            {   // 断面形状構成点未設定
                return m_dMaxCoordinate;
            }
            HySDataLinkedList csShape = m_csSectionShape.GetShapePoints();
            if (csShape.GetCount() == 0)
            {   // 断面形状構成点無し
                return m_dMaxCoordinate;
            }

            // 構成点リストの最初の点のX座標を最大値に設定しておく
            csShape.SetCursorFirst();
            double dMaxVal = ((HySGeoRiverCrossSectionShapePoint)csShape.GetFirstData()).GetXValue();
            csShape.MoveCursorNext();
            long lCount = csShape.GetCount() - 1;
            for (int i = 0; i < lCount; i++)
            {
                HySGeoRiverCrossSectionShapePoint csPoint = (HySGeoRiverCrossSectionShapePoint)csShape.GetCursorData();
                if (csPoint.GetXValue() > dMaxVal)
                {   // 現在の最大X座標より大きい場合
                    dMaxVal = csPoint.GetXValue();
                }
                csShape.MoveCursorNext();
            }

            return dMaxVal;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面X座標最小値設定(DBAが使用します)</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetMinXCoordinate( dMinCoordinate ) </para>
        /// </example>
        /// <param name="dMinCoordinate">断面X座標最小値</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>データベースからオブジェクトを復元する際に使用します。他の用途では利用しないでください。</para>
        /// </remarks>
        public void SetMinXCoordinate(double dMinCoordinate)
        {
            m_dMinCoordinate = dMinCoordinate;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面X座標最大値設定(DBAが使用します)</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetMaxXCoordinate( dMaxCoordinate ) </para>
        /// </example>
        /// <param name="dMaxCoordinate">断面X座標最大値</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>データベースからオブジェクトを復元する際に使用します。他の用途では利用しないでください。</para>
        /// </remarks>
        public void SetMaxXCoordinate(double dMaxCoordinate)
        {
            m_dMaxCoordinate = dMaxCoordinate;
        }

        /// <summary><para>method outline:</para>
        /// <para>河川距離標設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetGeoRiverDistancePost( csDistancePost ) </para>
        /// </example>
        /// <param name="csDistancePost">河川距離標</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetGeoRiverDistancePost(HySGeoRiverDistancePost csDistancePost)
        {
            m_csGeoRiverDistancePost = csDistancePost;
        }

        /// <summary><para>method outline:</para>
        /// <para>河川距離標取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeoRiverDistancePost csDistancePost = GetGeoRiverDistancePost( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>河川距離標</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySGeoRiverDistancePost GetGeoRiverDistancePost()
        {
            return m_csGeoRiverDistancePost;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面形状設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetSectionShape( csShape ) </para>
        /// </example>
        /// <param name="csShape">断面形状</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSectionShape(HySGeoRiverCrossSectionShape csShape)
        {
            m_csSectionShape = csShape;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面形状取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySGeoRiverCrossSectionShape csShape = GetSectionShape( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>断面形状</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySGeoRiverCrossSectionShape GetSectionShape()
        {
            return m_csSectionShape;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面属性リスト設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetSectionAttribute( csAttribute ) </para>
        /// </example>
        /// <param name="csAttribute">断面属性リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSectionAttribute(HySDataLinkedList csAttribute)
        {
            m_csSectionAttribute = csAttribute;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面属性リスト取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySDataLinkedList csAttribute = GetSectionAttribute( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>断面属性リスト</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySDataLinkedList GetSectionAttribute()
        {
            return m_csSectionAttribute;
        }

        /// <summary><para>method outline:</para>
        /// <para>ポイント属性テーブル設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetPointAttributes( csAttributes ) </para>
        /// </example>
        /// <param name="csAttributes">ポイント属性テーブル</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetPointAttributes(HySDataHashTable csAttributes)
        {
            m_csPointAttributes = csAttributes;
        }

        /// <summary><para>method outline:</para>
        /// <para>断面属性リスト取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySDataHashTable csAttributes = GetPointAttributes( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>ポイント属性テーブル</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySDataHashTable GetPointAttributes()
        {
            return m_csPointAttributes;
        }

        /// <summary><para>method outline:</para>
        /// <para>ライン属性テーブル設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetLinetAttributes( csAttributes ) </para>
        /// </example>
        /// <param name="csAttributes">ライン属性テーブル</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetLinetAttributes(HySDataHashTable csAttributes)
        {
            m_csLineAttributes = csAttributes;
        }

        /// <summary><para>method outline:</para>
        /// <para>ライン属性テーブル取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySDataHashTable csAttributes = GetLinetAttributes( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>ライン属性テーブル</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySDataHashTable GetLinetAttributes()
        {
            return m_csLineAttributes;
        }

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

        /// <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();
        }
    }
}
