using System;
using System.Collections.Generic;
using System.Linq;

using BeWo.Validation;
using BeWo.ViewModel.ListViewModel;

using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;

namespace BeWo.ViewModel
{
    public class WohnheimbuchungsVM : AbstractDCMapperVM<WohnheimbuchungDC>
    {
        public static String PropertyName_Wohnheimbuchung2Costbearer2SupportConceptList = "Wohnheimbuchung2Costbearer2SupportConceptList";
        public static String PropertyName_EmployeeWohnheimbuchungsRelation              = "EmployeeList";
        public static String PropertyName_Buchungsdatum                                 = "Buchungsdatum";
        public static String PropertyName_Wohnheim                                      = "Wohnheim";
        public static String PropertyName_ServiceDescription                            = "ServiceDescription";
        public static String PropertyName_Category                                      = "Category";

        private WohnheimbuchungEmployeeRelListVM                   _EmployeeList;
        private Wohnheimbuchung2Costbearer2SupportConceptRelListVM _Wohnheimbuchung2Costbearer2SupportConceptList;
        private DateTime?                                          _Buchungsdatum;
        private CompactWohnheimDC                                  _Wohnheim;

        public Wohnheimbuchung2Costbearer2SupportConceptRelListVM Wohnheimbuchung2Costbearer2SupportConceptList
        {
            get { return _Wohnheimbuchung2Costbearer2SupportConceptList; }

            set
            {
                if (AreDifferent(_Wohnheimbuchung2Costbearer2SupportConceptList, value))
                {
                    _Wohnheimbuchung2Costbearer2SupportConceptList = value;
                    FirePropertyChanged(PropertyName_Wohnheimbuchung2Costbearer2SupportConceptList);
                }
            }
        }

        public WohnheimbuchungEmployeeRelListVM EmployeeList
        {
            get { return _EmployeeList; }

            set
            {
                if (AreDifferent(_EmployeeList, value))
                {
                    _EmployeeList = value;
                    FirePropertyChanged(PropertyName_EmployeeWohnheimbuchungsRelation);
                }
            }
        }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public ServiceDescriptionDC ServiceDescription
        {
            get { return _ServiceDescription; }

            set
            {
                if (AreDifferent(_ServiceDescription, value))
                {
                    _ServiceDescription = value;
                    StoreDirtyInformation(AreDifferent(DataContract.ServiceDescription, value), PropertyName_ServiceDescription);
                    FirePropertyChanged("ServiceDescription");
                }
            }
        }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public ServiceCategoryDC Category
        {
            get { return _Category; }

            set
            {
                if (AreDifferent(_Category, value))
                {
                    _Category = value;
                    ServiceDescription = null;
                    FirePropertyChanged("Category");
                    FirePropertyChanged("PossibleServiceDescriptions");
                }
            }
        }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public DateTime? Buchungsdatum
        {
            get { return _Buchungsdatum; }
            set
            {
                if (AreDifferent(_Buchungsdatum, value))
                {
                    _Buchungsdatum = value;
                    StoreDirtyInformation(AreDifferent(DataContract.Buchungsdatum, value), PropertyName_Buchungsdatum);
                    FirePropertyChanged(PropertyName_Buchungsdatum);
                }
            }
        }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public CompactWohnheimDC Wohnheim
        {
            get { return _Wohnheim; }
            set
            {
                if (AreDifferent(_Wohnheim, value))
                {
                    _Wohnheim = value;
                    StoreDirtyInformation(AreDifferent(DataContract.Wohnheim, value), PropertyName_Wohnheim);
                    FirePropertyChanged(PropertyName_Wohnheim);
                }
            }
        }

        public Dictionary<ServiceCategoryDC, List<ServiceDescriptionDC>> Category2Services
        {
            get { return _Category2Services; }
            set
            {
                _Category2Services = value;
                FirePropertyChanged("Category2Services");
                FirePropertyChanged("SortedCategories");
                FirePropertyChanged("PossibleServiceDescriptions");
            }
        }
        public IList<ServiceCategoryDC> SortedCategories
        {
            get
            {
                return Category2Services != null ? Category2Services.Keys.OrderBy(cat => cat.Position).ToList() : null;
            }
        }
        private ServiceDescriptionDC _ServiceDescription;
        private Dictionary<ServiceCategoryDC, List<ServiceDescriptionDC>> _Category2Services;
        private ServiceCategoryDC _Category;
        public List<ServiceDescriptionDC> PossibleServiceDescriptions
        {
            get
            {
                if (_Category == null)
                {
                    return null;
                }

                return _Category2Services.ContainsKey(_Category) ? _Category2Services[_Category] : null;
            }
        }

        public WohnheimbuchungsVM(WohnheimbuchungDC pDC, Dictionary<ServiceCategoryDC, List<ServiceDescriptionDC>> pCategory2Services) : base(pDC, pDC.WohnheimbuchungOid == null)
        {
            _Category2Services = pCategory2Services;
        }

        public override bool IsDirty
        {
            get
            {
                return base.IsDirty || EmployeeList.IsDirty || Wohnheimbuchung2Costbearer2SupportConceptList.IsDirty;
            }
        }

        protected override void InitByDataContract(WohnheimbuchungDC pDataContract)
        {
            if (!IsNew)
            {
                _EmployeeList                                  = VMFactory.CreateEmployeeWohnheimbuchungsListVM(pDataContract.EmployeeList);
                _Wohnheimbuchung2Costbearer2SupportConceptList = VMFactory.CreateSupportConceptWohnheimbuchungsListVM(pDataContract.Costbearer2SupportConceptList.ToObservableCollection());
            }
            else
            {
                _EmployeeList                                  = new WohnheimbuchungEmployeeRelListVM(new List<WohnheimbuchungEmployeeRelationDC>());
                _Wohnheimbuchung2Costbearer2SupportConceptList = new Wohnheimbuchung2Costbearer2SupportConceptRelListVM(new List<Wohnheimbuchung2Costbearer2SupportConceptRelationDC>());
            }
            _Buchungsdatum = pDataContract.Buchungsdatum;
            _Wohnheim = pDataContract.Wohnheim;
        }

        protected override WohnheimbuchungDC MapToDataContract(WohnheimbuchungDC pDataContract, bool doCommit)
        {
            foreach (var item in _Wohnheimbuchung2Costbearer2SupportConceptList.VMList)
            {
				if (!item.StartDate.HasValue)
				{
					item.StartDate = _Buchungsdatum.Value.Date;
				}
				else
				{
					item.StartDate = _Buchungsdatum.Value.MergeDatesByDate(item.StartDate.Value);
				}
				if (!item.EndDate.HasValue)
				{
					item.EndDate = _Buchungsdatum.Value.AddDays(1);
				}
				else
				{
					item.EndDate = _Buchungsdatum.Value.MergeDatesByDate(item.EndDate.Value);		
				}
            }

            foreach (var item in _EmployeeList.VMList)
            {
				if (!item.StartDate.HasValue)
				{
					item.StartDate = _Buchungsdatum.Value.Date;
				}
				else
				{
					item.StartDate = _Buchungsdatum.Value.MergeDatesByDate(item.StartDate.Value);
				}
				if (!item.EndDate.HasValue)
				{
					item.EndDate = _Buchungsdatum.Value.AddDays(1);
				}
				else
				{
					item.EndDate = _Buchungsdatum.Value.MergeDatesByDate(item.EndDate.Value);
				}
            }

            pDataContract.EmployeeList                  = _EmployeeList.CopyToDCList(doCommit);
            pDataContract.Costbearer2SupportConceptList = _Wohnheimbuchung2Costbearer2SupportConceptList.CopyToDCList(doCommit);
            pDataContract.Buchungsdatum                 = _Buchungsdatum;
            pDataContract.Wohnheim                      = _Wohnheim;

            return pDataContract;
        }
    }
}