using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;

namespace ZadaniaWPF.ModelWidoku
{
    /*
    public class ZadaniaOdczyt : INotifyPropertyChanged
    {
        private Model.ZadaniaOdczyt modelOdczyt;
        public Zadanie[] Zadania { get; private set; }

        private void kopiujZadania()
        {
            int liczbaZadań = modelOdczyt.LiczbaZadań;
            Zadania = new Zadanie[liczbaZadań];
            for (int i = 0; i < liczbaZadań; ++i)
                Zadania[i] = new Zadanie(modelOdczyt[i]);

            OnPropertyChanged();
        }

        public ZadaniaOdczyt(Model.Zadania modelZapis)
        {
            modelOdczyt = new Model.ZadaniaOdczyt(modelZapis);
            modelOdczyt.ZadaniaZmienione += modelOdczyt_ZadaniaZmienione;
            kopiujZadania();
        }

        private void modelOdczyt_ZadaniaZmienione(object sender, Model.ZadaniaEventArgs e)
        {
            //nie korzystam z e.Zadania
            kopiujZadania();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged()
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(Zadania)));
        }
    }
    */

    public class ZadaniaOdczyt
    {
        private Model.ZadaniaOdczyt modelOdczyt;
        public ObservableCollection<Zadanie> Zadania { get; private set; } =
            new ObservableCollection<Zadanie>();

        public ZadaniaOdczyt(Model.ZadaniaOdczyt modelOdczyt)
        {
            this.modelOdczyt = modelOdczyt;
            modelOdczyt.ZadaniaZmienione += modelOdczyt_ZadaniaZmienione;
        }

        //Uwaga!! Skopiowany kod, ale nie ten sam bo dla zadań z innej warstwy
        private Comparison<Zadanie> porównywaniePriorytetów =
            new Comparison<Zadanie>(
                (Zadanie zadanie1, Zadanie zadanie2) =>
                {
                    int wynik = -zadanie1.Priorytet.CompareTo(zadanie2.Priorytet);
                    if (wynik == 0) wynik = zadanie1.PlanowanyTerminRealizacji.CompareTo(zadanie2.PlanowanyTerminRealizacji);
                    return wynik;
                });

        private Comparison<Zadanie> porównywaniePlanowanychTerminówRealizacji =
            new Comparison<Zadanie>(
                (Zadanie zadanie1, Zadanie zadanie2) =>
                {
                    int wynik = zadanie1.PlanowanyTerminRealizacji.CompareTo(zadanie2.PlanowanyTerminRealizacji);
                    if (wynik == 0) wynik = -zadanie1.Priorytet.CompareTo(zadanie2.Priorytet);
                    return wynik;
                });

        private void sortujZadania(bool porównywaniePriorytetówCzyPlanowanychTerminówRealizacji)
        {
            List<Zadanie> _listaZadań = Zadania.ToList();
            if (porównywaniePriorytetówCzyPlanowanychTerminówRealizacji)
                _listaZadań.Sort(porównywaniePriorytetów);
            else
                _listaZadań.Sort(porównywaniePlanowanychTerminówRealizacji);
            Zadania.Clear();
            foreach (Zadanie zadanie in _listaZadań) Zadania.Add(zadanie);
        }

        private void modelOdczyt_ZadaniaZmienione(object sender, Model.ZadaniaEventArgs e)
        {
            if (e.Zdarzenie is Model.ZdarzenieDodaniaZadania)
            {
                Model.Zadanie dodaneZadanie = (e.Zdarzenie as Model.ZdarzenieDodaniaZadania).DodaneZadanie;
                Zadania.Add(new Zadanie(dodaneZadanie));
            }
            if (e.Zdarzenie is Model.ZdarzenieUsunięciaZadania)
            {
                Model.Zadanie usuwaneZadanie = (e.Zdarzenie as Model.ZdarzenieUsunięciaZadania).UsunięteZadanie;
                int idUsuwanegoZadania = usuwaneZadanie.Id.Value;
                Zadanie _usuwaneZadanie = Zadania.FirstOrDefault(z => z.Id == idUsuwanegoZadania);
                if (_usuwaneZadanie != null) Zadania.Remove(_usuwaneZadanie);
            }
            if (e.Zdarzenie is Model.ZdarzenieSortowaniaZadań) //sortowanie niezależnie od sortowania modelu
            {
                bool porównywaniePriorytetówCzyPlanowanychTerminówRealizacji = (e.Zdarzenie as Model.ZdarzenieSortowaniaZadań).PorównywaniePriorytetówCzyPlanowanychTerminówRealizacji;
                sortujZadania(porównywaniePriorytetówCzyPlanowanychTerminówRealizacji);
            }
        }
    }
}
