using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ModelData.BusinessModel.RDF;

namespace ModelData.BusinessModel
{
    public class BusinessDataManager
    {
        #region singl

        private static BusinessDataManager dataManager;
        public static BusinessDataManager Get()
        {
            if (dataManager == null)
                dataManager = new BusinessDataManager();

            return dataManager;
        }
        public static void Destroy()
        {
            dataManager = null;
        }

        private BusinessDataManager()
        {
            Init();
        }

        #endregion

        #region Data

        private List<Settlement> lst_settlements;
        private bool needUpdate;

        #endregion

        #region Private Methods

        private void Init()
        {
            lst_settlements = new List<Settlement>();
            needUpdate = true;
        }

        private void LoadAllSettlements(string YearMin, string YearMax)
        {
            var lst_query = RDFQuery.GetData(RDFQuery.QueryType.AllSettlements , new string[] { YearMin, YearMax });
            Settlement settlement;

            foreach (var elem in lst_query)
            {
                int pop = int.Parse(elem["population"].ToString().Split('^')[0]);
                settlement = new Settlement(elem["settlement"].ToString(), elem["name"].ToString(), new Position(elem["long"], elem["lat"]))
                {
                    Population = elem["population"] != null ? elem["population"].ToString() : "0"
                };
                lst_settlements.Add(settlement);
            }
        }
        private void LoadInfoAboutSettlement(string URL)
        {
            System.IO.StreamWriter wr = new System.IO.StreamWriter("D:\\out.txt", true);
            wr.WriteLine(URL);

            var lst_query = RDFQuery.GetData(RDFQuery.QueryType.SettlementInfo, new string[] { URL });
            foreach (var elem in lst_query)
            {
                //name nameOfRegion nameOfType hasBeginning lat long population populationOfMan populationOfWoman year source
                Settlement settlement = lst_settlements[FindByURL(URL)];
                settlement.Type = elem["nameOfType"] != null ? elem["nameOfType"].ToString() : null;
                settlement.Year = elem["year"] != null ? elem["year"].ToString() : null;
                settlement.Region = elem["nameOfRegion"] != null ? elem["nameOfRegion"].ToString() : null;
                settlement.Population = elem["population"] != null ? elem["population"].ToString() : "0";
                settlement.PopulationOfMan = elem["populationOfMan"] != null ? elem["populationOfMan"].ToString() : null;
                settlement.PopulationOfWoman = elem["populationOfWoman"] != null ? elem["populationOfWoman"].ToString() : null;
                settlement.Description = u.ToString();
                settlement.Source = elem["source"] != null ? elem["source"].ToString() : null;

                u++;
                wr.Close();
                //lst_settlements.Add(new_settlement);
            }
        }

        #endregion

        #region Public Methods

        public bool Update
        {
            get { return needUpdate; }
            set { if (value) needUpdate = true; }
        }

        public Settlement[] GetSettlements(int YearMin, int YearMax)
        {
            if (needUpdate)
            {
                Clear();
                LoadAllSettlements(YearMin.ToString(), YearMax.ToString());
                needUpdate = false;
            }
            return lst_settlements.ToArray();
        }

        public Settlement GetInfoAboutSettlement(string URL)
        {
            LoadInfoAboutSettlement(URL);
            return lst_settlements[FindByURL(URL)];
        }

        public string[] GetSettlementsNames(string subName)
        {
            var lst_query = RDFQuery.GetData(RDFQuery.QueryType.SubName, new string[] { subName });
            List<string> result = new List<string>();
            foreach (var elem in lst_query)
                result.Add(elem["name"].ToString());
            
            return result.ToArray();
        }

        #region Tools

        private void Clear()
        {
            lst_settlements = new List<Settlement>();
        }

        private int FindByName(string name)
        {
            for (int i = 0; i < lst_settlements.Count; i++)
            {
                if (lst_settlements[i].Name == name)
                    return i;
            }
            return -1;
        }

        private int FindByURL(string URL)
        {
            for (int i = 0; i < lst_settlements.Count; i++)
            {
                if (lst_settlements[i].URL == URL)
                    return i;
            }
            return -1;
        }

        #endregion

        #endregion

    }
}
