using System.Collections.ObjectModel;
using System.Collections.Specialized;

using System;
using System.Windows.Input;
using System.ComponentModel;

namespace ZadaniaUA.ModelWidoku
{
	public class Zadania
	{
        public const string NazwaPlikuXml = "zadania.xml";

        //przechowywanie dwóch kolekcji
        private Model.Zadania model;
		public ObservableCollection<Zadanie> ListaZadań { get; private set; }

		private void KopiujZadania()
		{
			ListaZadań.CollectionChanged -= SynchronizacjaModelu;
			ListaZadań.Clear();
			foreach (Model.Zadanie zadanie in model) ListaZadań.Add(new Zadanie(zadanie));
			ListaZadań.CollectionChanged += SynchronizacjaModelu;
		}

        private async void Inicjuj()
        {
            model = await Model.PlikXML.CzytajAsync(NazwaPlikuXml);
            if (model == null) model = new Model.Zadania();

            //*
			//testy - początek
            if (model.LiczbaZadań == 0)
            {
                model.DodajZadanie(new Model.Zadanie("Pierwsze", DateTime.Now, DateTime.Now.AddDays(2), Model.PriorytetZadania.Ważne, false));
                model.DodajZadanie(new Model.Zadanie("Drugie", DateTime.Now, DateTime.Now.AddDays(2), Model.PriorytetZadania.Ważne, false));
                model.DodajZadanie(new Model.Zadanie("Trzecie", DateTime.Now, DateTime.Now.AddDays(1), Model.PriorytetZadania.MniejWażne, false));
                model.DodajZadanie(new Model.Zadanie("Czwarte", DateTime.Now, DateTime.Now.AddDays(3), Model.PriorytetZadania.Krytyczne, false));
                model.DodajZadanie(new Model.Zadanie("Piąte", DateTime.Now, new DateTime(2015, 03, 15, 1, 2, 3), Model.PriorytetZadania.Krytyczne, false));
                model.DodajZadanie(new Model.Zadanie("Szóste", DateTime.Now, new DateTime(2015, 03, 14, 1, 2, 3), Model.PriorytetZadania.Krytyczne, false));
            }
			//testy - koniec
			//*/

            KopiujZadania();            
        }

        public Zadania()
		{
            ListaZadań = new ObservableCollection<Zadanie>();
            CzyśćWłasnościNowegoZadania();

            Inicjuj();
		}

		private void SynchronizacjaModelu(object sender, NotifyCollectionChangedEventArgs e)
		{
			switch (e.Action)
			{
				case NotifyCollectionChangedAction.Add:
					Zadanie noweZadanie = (Zadanie)e.NewItems[0];
					if (noweZadanie != null)
						model.DodajZadanie(noweZadanie.GetModel());
					break;
				case NotifyCollectionChangedAction.Remove:
					Zadanie usuwaneZadanie = (Zadanie)e.OldItems[0];
					if (usuwaneZadanie != null)
						model.UsuńZadanie(usuwaneZadanie.GetModel());
					break;
			}
		}

		private ICommand zapiszCommand;

		public ICommand Zapisz
		{
			get
			{
				if (zapiszCommand == null)
                    //zapiszCommand = new RelayCommand(argument => { Model.PlikXML.Zapisz(NazwaPlikuXml, model); });
                    zapiszCommand = new RelayCommand(async argument => { await Model.PlikXML.ZapiszAsync(NazwaPlikuXml, model); });
                return zapiszCommand;
			}
		}

        private int wybranyIndeksZadania = -1;

        public int WybranyIndeksZadania
        {
            get
            {
                return wybranyIndeksZadania;
            }
            set
            {
                wybranyIndeksZadania = value;
                if (usuńZadanie != null)
                    (usuńZadanie as RelayCommand).OnCanExecuteChanged();
            }
        }        

	    private ICommand usuńZadanie;

        public ICommand UsuńZadanie
        {
            get
            {
                if (usuńZadanie == null)
                    usuńZadanie = new RelayCommand(
                        o =>
                        {
                            /*
                            int indeksZadania = (int)o;
                            Zadanie zadanie = ListaZadań[indeksZadania];
                            ListaZadań.Remove(zadanie);
                            */
                            Zadanie zadanie = ListaZadań[WybranyIndeksZadania];
                            ListaZadań.Remove(zadanie);
                        },
                        o =>
                        {
                            /*
                            if (o == null) return false;
                            int indeksZadania = (int)o;
                            return indeksZadania >= 0;
                            */
                            return WybranyIndeksZadania >= 0;
                        });
                return usuńZadanie;
            }
        }

        /*
        private ICommand dodajZadanie;

		public ICommand DodajZadanie
		{
			get
			{
				if (dodajZadanie == null)
					dodajZadanie = new RelayCommand(
						o =>
						{
							Zadanie zadanie = o as Zadanie;
							if (zadanie != null) ListaZadań.Add(zadanie);
						},
						o =>
						{
							return (o as Zadanie) != null;
						});
				return dodajZadanie;
			}
		}
        */
          
        private ICommand sortujZadania;
        
        public ICommand SortujZadania
		{
			get
			{
				if (sortujZadania == null)
					sortujZadania = new RelayCommand(
						o =>
						{
							bool porównywaniePriorytetówCzyPlanowanychTerminówRealizacji = bool.Parse((string)o);
							model.SortujZadania(porównywaniePriorytetówCzyPlanowanychTerminówRealizacji);
							KopiujZadania();
						});
				return sortujZadania;
			}
		}

        //własności wiązane z DodajZadanieDialog.xaml
        public string OpisNowegoZadania { get; set; }
        public Model.PriorytetZadania PriorytetNowegoZadania { get; set; }
        public DateTime PlanowanyTerminRealizacjiNowegoZadania { get; set; }

        private void CzyśćWłasnościNowegoZadania()
        {
            OpisNowegoZadania = "";
            PriorytetNowegoZadania = Model.PriorytetZadania.Ważne;
            PlanowanyTerminRealizacjiNowegoZadania = DateTime.Now;
        }


        private ICommand dodajZadanie;

        public ICommand DodajZadanie
        {
            get
            {
                if (dodajZadanie == null)
                {
                    dodajZadanie = new RelayCommand(
                        o =>
                        {
                            //Zadanie zadanie = o as Zadanie;
                            Zadanie zadanie = new Zadanie(OpisNowegoZadania, DateTime.Now, PlanowanyTerminRealizacjiNowegoZadania, PriorytetNowegoZadania, false);
                            ListaZadań.Add(zadanie);
                            CzyśćWłasnościNowegoZadania();
                        },
                        o =>
                        {
                            //return (o as Zadanie) != null;
                            return string.IsNullOrWhiteSpace(OpisNowegoZadania) && PlanowanyTerminRealizacjiNowegoZadania > DateTime.Now;
                        });
                }
                return dodajZadanie;
            }
        }
    }
}
