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

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

using Tools;

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

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

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

        /// \property   public Settlement before
        ///
        /// \brief  Ссылка на экземпляр основного поселения
        /// Обязательное свойство. Установлен атрибут IndexAttrib со значением 2
        /// \returns    The before.

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



        /// \property   public InstantTime hasBeginning
        ///
        /// \brief  Точный год, к которому относится информация
        /// Обязательное свойство. Установлен атрибут IndexAttrib со значением 3
        /// \returns    The has beginning.

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



        /// \property   public string Source
        ///
        /// \brief  Источник данных
        /// Может содержать URL, ISBN, точное наименование научной работы и т.п.
        /// Обязательное свойство. Установлен атрибут IndexAttrib со значением 4
        /// \returns    The source.

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

        #endregion

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

        /// \property   public SettlementType Type
        ///
        /// \brief  Тип поселения
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 5
        /// \returns    The type.

        [IndexAttrib(5)] public SettlementType Type { set; get; }



        /// \property   public Region Region
        ///
        /// \brief  Регион, в составе которого находится поселение
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 6
        /// \returns    The region.

        [IndexAttrib(6)] public Region Region { set; get; }



        /// \property   public int? PopulationAll
        ///
        /// \brief  Общее количество населения
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 7
        /// \returns    The population all.

        [IndexAttrib(7)] public int? PopulationAll { set; get; }

        /// \property   public int? PopulationMales
        ///
        /// \brief  Количество мужского населения
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 8
        /// \returns    The population males.

        [IndexAttrib(8)] public int? PopulationMales { set; get; }



        /// \property   public int? PopulationFemales
        ///
        /// \brief  Количество женского населения
        /// Может быть задан или равняться null.
        /// Установлен атрибут IndexAttrib со значением 9
        /// \returns    The population females.

        [IndexAttrib(9)] public int? PopulationFemales { set; get; }



        /// \property   public List<string> AlternativeName
        ///
        /// \brief  Другие названия поселения
        /// Количество может быть равно 0 или более
        /// Установлен атрибут IndexAttrib со значением 10
        /// \returns    The name of the alternative.

        [IndexAttrib(10)] public List<string> AlternativeName { set; get; }



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

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

        #endregion

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

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

        protected EditedSettlement()
        {
            Init();
        }



        /// \fn public EditedSettlement(string URL, Settlement before, InstantTime hasBeginning, string Source)
        ///
        /// \brief  Основной конструктор
        /// Запрашивает все необходимые параметры, согласно архитектуре онтологии.
        /// \author Denis
        /// \date   30.03.2019
        ///
        /// \param  URL             URL измененного поселения.
        /// \param  before          Ссылка на экземпляр основного поселения.
        /// \param  hasBeginning    Точный год.
        /// \param  Source          Источник.

        public EditedSettlement(string URL, Settlement before, InstantTime hasBeginning, string Source)
        {
            this.URL = URL;
            this.before = before;
            this.hasBeginning = hasBeginning;
            this.Source = Source;

            Init();
        }



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

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



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

        public override Dictionary<string, string> Serialize()
        {
            return new Dictionary<string, string>()
            {
                ["URL"] = this.URL ?? "",
                ["Соответствующий год"] = this.hasBeginning.ToString() ?? "",
                ["В составе региона"] = Concat(this.Region?.Serialize()) ?? "",
                ["Тип поселения"] = Concat(this.Type?.Serialize()) ?? "",
                ["Всего населения"] = PopulationAll?.ToString() ?? "",
                ["Мужского населения"] = PopulationMales?.ToString() ?? "",
                ["Женского населения"] = PopulationFemales?.ToString() ?? "",
                ["Другое название"] = Concat(this.AlternativeName) ?? ""
            };
        }

        #endregion
    }
    /// @}
}
