using SurfacePlot3D.Members;
using System.Collections.Generic;
using System;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.Linq;

namespace SurfacePlot3D
{
    public class SurfacePlotDataModel : CustomBindableBase
    {
		#region Private Variables

		private ObservableCollection<StatePopulationDataItem> _statePopulationDataItems = new ObservableCollection<StatePopulationDataItem>();
        private String _stateFilter = String.Empty;
        private String _yearFilter = String.Empty;
        private String _populationFilter = String.Empty;
        private String _rowFilter = String.Empty;
        private String _columnFilter = String.Empty;

        #endregion

        #region Public Clr Properties

        public ObservableCollection<StatePopulationDataItem> StatePopulationDataItems { get { return _statePopulationDataItems; } set { SetProperty(ref _statePopulationDataItems, value); } }
        public String StateFilter { get { return _stateFilter; } set { SetProperty(ref _stateFilter, value); NotifyPropertyChanged("FilteredStatePopulationDataItems"); } }
        public String YearFilter { get { return _yearFilter; } set { SetProperty(ref _yearFilter, value); NotifyPropertyChanged("FilteredStatePopulationDataItems"); } }
        public String PopulationFilter { get { return _populationFilter; } set { SetProperty(ref _populationFilter, value); NotifyPropertyChanged("FilteredStatePopulationDataItems"); } }
        public String RowFilter { get { return _rowFilter; } set { SetProperty(ref _rowFilter, value); NotifyPropertyChanged("FilteredStatePopulationDataItems"); } }
        public String ColumnFilter { get { return _columnFilter; } set { SetProperty(ref _columnFilter, value); NotifyPropertyChanged("FilteredStatePopulationDataItems"); } }

        #endregion

        #region Public Readonly Properties
        [XmlIgnore] public IEnumerable<StatePopulationDataItem> FilteredStates
        {
            get
            {
                var predicate = PredicateBuilder.True<StatePopulationDataItem>();

                if (!String.IsNullOrEmpty(StateFilter)) predicate = predicate.And(c => c.State.ToLower().Contains(StateFilter.ToLower()));

                return (StatePopulationDataItems.AsQueryable()).DistinctBy(c=>c.State).Where(predicate.Compile()).ToList();
            }
        }

        #endregion

        #region Predicate Filters

        [XmlIgnore]
        public IEnumerable<StatePopulationDataItem> FilteredStatePopulationDataItems
        {
            get
            {
                var predicate = PredicateBuilder.True<StatePopulationDataItem>();

                if (!String.IsNullOrEmpty(StateFilter)) predicate = predicate.And(c => c.State.ToLower().Contains(StateFilter.ToLower()));
                if (!String.IsNullOrEmpty(YearFilter)) predicate = predicate.And(c => c.Year.ToString().ToLower().Contains(YearFilter.ToLower()));
                if (!String.IsNullOrEmpty(PopulationFilter)) predicate = predicate.And(c => c.Population.ToString().ToLower().Contains(PopulationFilter.ToLower()));
                if (!String.IsNullOrEmpty(RowFilter)) predicate = predicate.And(c => c.Row.ToString().ToLower().Contains(RowFilter.ToLower()));
                if (!String.IsNullOrEmpty(ColumnFilter)) predicate = predicate.And(c => c.Column.ToString().ToLower().Contains(ColumnFilter.ToLower()));

                return (StatePopulationDataItems.AsQueryable()).Where(predicate.Compile()).ToList();
            }
        }

        #endregion
    }
}