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

using ModelData.BusinessModel.Tools;
using ModelData.BusinessModel.ExtraEntities;
using ModelData.BusinessModel.BaseAndInterface;

using Tools;

namespace ModelData.BusinessModel.MainEntities
{
    /// \addtogroup Entities
    /// @{

    /// \class  Settlement
    ///
    /// \brief  Описывает сущность поселения
    /// Поселение содержит всю известную информацию об одноименной сущности в онтологии
    /// Все относящиеся к основному поселению сведения содержатся здесь, все прочие - в измененных поселениях
    /// Основное поселение имеет List измененных поселений для доступа к сведениям о них
    /// Обязательными параметрами являются: url; отображаемое название; географические координаты.
    /// \warning При автоматической сериализации возможна закольцовка, т.к. класс содержит ссылки на измененные поселения, а измененные поселения содержат ссылку на основное.
    /// \author Denis
    /// \date   31.03.2019

    public class Settlement : BaseOntologyEntity
    {
        #region Обязательные данные

        /// \property   public Coordinate Coordinate
        ///
        /// \brief  Координаты поселения
        /// Обязательное свойство. Установлен атрибут IndexAttrib со значением 2
        /// \returns    The coordinate.

        [IndexAttrib(2)] public Coordinate Coordinate { set; get; }

        #endregion

        #region Необязательные данные

        /// \property   public InstantTime hasBeginning
        ///
        /// \brief  Год основания поселения
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 3
        /// \returns    The has beginning.

        [IndexAttrib(3)] public InstantTime hasBeginning { set; get; }



        /// \property   public Founder Founder
        ///
        /// \brief  Основатель поселения
        /// Личность или народ-основатель поселения.
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 4
        /// \returns    The founder.

        [IndexAttrib(4)] public Founder Founder { set; get; }



        /// \property   public string Legend
        ///
        /// \brief  История основания поселения
        /// Содержит ссылку или текст об основании поселения.       
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 5
        /// \returns    The legend.

        [IndexAttrib(5)] public string Legend { set; get; }



        /// \property   public Dictionary<string, string> Others
        ///
        /// \brief  Dictionary, содержащий разную информацию
        /// Это свойство-заглушка на тот случай, если нужно быстро добавить какую-то информацию, которая не отражена в других свойствах.
        /// Такой подход создает довольно гибкую структуру описания имеющейся информации, но затрудняет восприятие того, что действительно необходимо знать о поселении.
        ///
        /// Количество может быть равно 0 или более
        /// Установлен атрибут IndexAttrib со значением 6
        /// \warning На данный момент вся требуемая информация отражена в свойствах, поэтому данная коллекция не заполняется и не выводится.
        /// \returns    The others.

        [IndexAttrib(6)] public Dictionary<string, string> Others { set; get; }

        #endregion

        #region Служебные данные

        /// \property   public List<EditedSettlement> EditedSettlements
        ///
        /// \brief  Список измененных поселений
        /// Содержит ссылки на экземпляры всех изменных поселений, относящихся к основному.
        /// Установлен атрибут IndexAttrib со значением 7.
        /// \returns    The edited settlements.

        [IndexAttrib(7)] public List<EditedSettlement> EditedSettlements { set; get; }

        #endregion

        #region Конструктор

        /// \fn protected Settlement()
        ///
        /// \brief  Protected конструктор
        /// Думаю, его нужно создать, мало ли, но фактически он пока не используется
        /// \author Denis
        /// \date   31.03.2019

        protected Settlement()
        {
            Init();
        }



        /// \fn public Settlement(string URL, string Title, Coordinate Coordinate)
        ///
        /// \brief  Основной конструктор
        /// Запрашивает все необходимые параметры, согласно архитектуре онтологии.
        /// \author Denis
        /// \date   31.03.2019
        ///
        /// \param  URL         URL.
        /// \param  Title       Отображаемое название.
        /// \param  Coordinate  Координаты.

        public Settlement(string URL, string Title, Coordinate Coordinate)
        {
            this.URL = URL;
            this.Title = Title;
            this.Coordinate = Coordinate;

            Init();
        }



        /// \fn protected void Init()
        ///
        /// \brief  Инициализация
        /// Создает новые коллекции для List измененных поселений и Dictionary другой информации
        /// \author Denis
        /// \date   31.03.2019

        protected void Init()
        {
            Others = new Dictionary<string, string>();
            EditedSettlements = new List<EditedSettlement>();
        }



        /// \fn public override Dictionary<string, string> Serialize()
        ///
        /// \brief  Метод записи данных о сущности в Dictionary.
        ///
        /// \author Denis
        /// \date   31.03.2019
        ///
        /// \returns    A Dictionary&lt;string,string&gt;

        public override Dictionary<string, string> Serialize()
        {
            List<string> edited = new List<string>();
            foreach (var edit in EditedSettlements)
                edited.Add(Concat(edit.Serialize()));
            
            return new Dictionary<string, string>()
            {
                ["URL"] = this.URL ?? "",
                ["Название"] = this.Title ?? "",
                ["Год основания"] = this.hasBeginning?.ToString() ?? "",
                ["Основатель"] = Concat(this.Founder?.Serialize()) ?? "",
                ["История основания"] = this.Legend ?? "",
                ["Дополнительно"] = Concat(edited) ?? ""
            };
        }

        #endregion       
    }
    /// @}
}
