using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Media;
using BeWo.Core;
using BeWo.Core.Service;
using BeWo.Validation;
using BeWo.ViewModel.ListViewModel;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using Color = System.Drawing.Color;

namespace BeWo.ViewModel
{
	public class EmployeeVM : AbstractDCMapperVM<EmployeeDC>
	{
		#region Property Names

		public static string PropertyName_Abbreviation            = "Abbreviation";
		public static string PropertyName_AbsenceTimes            = "AbsenceTimes";
		public static string PropertyName_AccountNumber           = "AccountNumber";
		public static string PropertyName_BankCode                = "BankCode";
		public static string PropertyName_BankName                = "BankName";
		public static string PropertyName_Bic                     = "Bic";
		public static string PropertyName_CancellationPeriod      = "CancellationPeriod";
		public static string PropertyName_Contracts               = "Contracts";
		public static string PropertyName_CustomerRelations       = "CustomerRelations";
		public static string PropertyName_DateOfBirth             = "DateOfBirth";
		public static string PropertyName_EMail                   = "EMail";
		public static string PropertyName_EmploymentType          = "EmploymentType";
		public static string PropertyName_EntryDate               = "EntryDate";
		public static string PropertyName_FamilyStatus            = "FamilyStatus";
		public static string PropertyName_Fax                     = "Fax";
		public static string PropertyName_Female                  = "IsFemale";
		public static string PropertyName_FirstName               = "FirstName";
		public static string PropertyName_Focuses                 = "Focuses";
		public static string PropertyName_Gender                  = "Gender";
		public static string PropertyName_HealthInsurance         = "HealthInsurance";
		public static string PropertyName_HourlyRate              = "HourlyRate";
		public static string PropertyName_IBAN                    = "IBAN";
		public static string PropertyName_InsuranceNumber         = "InsuranceNumber";
		public static string PropertyName_IsArchived              = "IsArchived";
		public static string PropertyName_IsMarried               = "IsMarried";
		public static string PropertyName_IsQualified             = "IsQualified";
		public static string PropertyName_IsSingle                = "IsSingle";
		public static string PropertyName_LastName                = "LastName";
		public static string PropertyName_LeaveDays               = "LeaveDays";
		public static string PropertyName_Male                    = "IsMale";
		public static string PropertyName_MobilePhone             = "MobilePhone";
		public static string PropertyName_Notice2                 = "Notice2";
		public static string PropertyName_Overtimes               = "Overtimes";
		public static string PropertyName_PersonnelNumber         = "PersonnelNumber";
		public static string PropertyName_Phone                   = "Phone";
		public static string PropertyName_PossibleEmploymentTypes = "PossibleEmploymentTypes";
		public static string PropertyName_PostalCode              = "PostalCode";
		public static string PropertyName_PrivateEMail            = "PrivateEMail";
		public static string PropertyName_ProbationPeriod         = "ProbationPeriod";
        public static string PropertyName_WeeklyDays              = "WeeklyDays";
		public static string PropertyName_Profession              = "Profession";
		public static string PropertyName_Qualifications          = "Qualifications";
		public static string PropertyName_Street                  = "Street";
		public static string PropertyName_TaxNumber               = "TaxNumber";
		public static string PropertyName_Text1                   = "Text1";
		public static string PropertyName_Text2                   = "Text2";
		public static string PropertyName_Text3                   = "Text3";
		public static string PropertyName_Text4                   = "Text4";
		public static string PropertyName_Text5                   = "Text5";
		public static string PropertyName_Town                    = "Town";
		public static string PropertyName_WeeklyFLS               = "WeeklyFLS";
		public static string PropertyName_WeeklyTotalHours        = "WeeklyTotalHours";
	    public static String PropertyName_EmployeeColor           = "EmployeeColor";
	    public static String PropertyName_EmployeeBrush           = "EmployeeBrush";

		#endregion

		private readonly                                   ObservableSortCollection<ValueListEntryDC> _PossibleFocuses;
		private readonly                                   ObservableSortCollection<ValueListEntryDC> _PossibleQualifications;
		private string                                     _Abbreviation;
		private AbsenceTimeListVM                          _AbsenceTimes;
		private string                                     _AccountNumber;
		private string                                     _BankCode;
		private string                                     _BankName;
		private string                                     _Bic;
		private ContractListVM                             _Contracts;
		private CustomerEmployeeRelationListVM             _CustomerRelations;
		private DateTime?                                  _DateOfBirth;
		private string                                     _EMail;
		private FamilyStatus?                              _FamilyStatus;
		private string                                     _Fax;
		private string                                     _FirstName;
		private ObservableSortCollection<ValueListEntryDC> _Focuses;
		private string                                     _HealthInsurance;
		private string                                     _IBAN;
		private string                                     _InsuranceNumber;
		private bool                                       _IsArchived;
		private bool                                       _IsFemale;
		private bool                                       _IsMale;
		private bool                                       _IsQualified = true;
		private string                                     _LastName;
		private string                                     _MobilePhone;
		private string                                     _Notice2;
		private OvertimeListVM                             _Overtimes;
		private string                                     _PersonnelNumber;
		private string                                     _Phone;
		private IList<AuszahlungsartDC>                    _PossibleAuszahlungsarten;
		private IList<EmploymentTypeDC>                    _PossibleEmploymentTypes;
		private string                                     _PostalCode;
		private string                                     _PrivateEMail;
		private string                                     _Profession;
		private ObservableSortCollection<ValueListEntryDC> _Qualifications;
		private Sex?                                       _Sex;
		private string                                     _Street;
		private string                                     _TaxNumber;
		private string                                     _Text1;
		private string                                     _Text2;
		private string                                     _Text3;
		private string                                     _Text4;
		private string                                     _Text5;
		private string                                     _Town;
	    private String                                     _EmployeeColor;
        private SolidColorBrush                            _EmployeeBrush;

		public EmployeeVM(
			EmployeeDC pEmployeeDC, IList<EmploymentTypeDC> pPossibleTypes, IEnumerable<ValueListEntryDC> pPossibleQualifications,
			IEnumerable<ValueListEntryDC> pPossibleFocusTypes, IEnumerable<AuszahlungsartDC> pPossibleAuszahlungsarten)
			: base(pEmployeeDC, pEmployeeDC.EmployeeOid == null)
		{
			_PossibleEmploymentTypes = pPossibleTypes;

			Contracts = new ContractListVM(_PossibleEmploymentTypes, DataContract.Contracts ?? (DataContract.Contracts = new List<ContractDC>()));

			_PossibleQualifications = DataContract.Qualifications != null
				? new ObservableSortCollection<ValueListEntryDC>(pPossibleQualifications.Except(DataContract.Qualifications), Comparer.ValueListEntryDCComparer)
				: new ObservableSortCollection<ValueListEntryDC>(pPossibleQualifications, Comparer.ValueListEntryDCComparer);

			_PossibleFocuses = DataContract.Focuses != null
				? new ObservableSortCollection<ValueListEntryDC>(pPossibleFocusTypes.Except(DataContract.Focuses), Comparer.ValueListEntryDCComparer)
				: new ObservableSortCollection<ValueListEntryDC>(pPossibleFocusTypes, Comparer.ValueListEntryDCComparer);

			_PossibleAuszahlungsarten = new List<AuszahlungsartDC>(pPossibleAuszahlungsarten);

            if(EmployeeBrush != null)
            {
                EmployeeBrush.Freeze();
            }
		}

        public List<SolidColorBrush> AllBrushes
        {
            get
            {
                var lTemp = typeof(Color).GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static).Select(pi => (Color)pi.GetGetMethod().Invoke(null, null)).ToList();

                lTemp.Sort((x, y) => x.GetBrightness().CompareTo(y.GetBrightness()));

                return lTemp.Where(w => (w.R * 0.299 + w.G * 0.587 + w.B * .114) > 75).Select(c => new SolidColorBrush(System.Windows.Media.Color.FromArgb(c.A, c.R, c.G, c.B))).ToList();
            }
        }

		public bool IsArchived
		{
			get { return _IsArchived; }

			set
			{
				if (AreDifferent(_IsArchived, value))
				{
					_IsArchived = value;
					StoreDirtyInformation(
						(value && DataContract.ActivationType == ActivationTypeId.Active) ||
						(!value && DataContract.ActivationType == ActivationTypeId.Archived), PropertyName_IsArchived);
					FirePropertyChanged(PropertyName_IsArchived);
				}
			}
		}

		public string Abbreviation
		{
			get { return _Abbreviation; }

			set
			{
				if (AreDifferent(_Abbreviation, value))
				{
					_Abbreviation = value;

					StoreDirtyInformation(AreDifferent(DataContract.Abbreviation, value), PropertyName_Abbreviation);

					FirePropertyChanged(PropertyName_Abbreviation);
				}
			}
		}

	    public SolidColorBrush EmployeeBrush
	    {
            get { return _EmployeeBrush; }

	        set
	        {
                if (AreDifferent(_EmployeeBrush, value))
	            {
                    _EmployeeBrush = value;
	                _EmployeeColor = value.ToString();
                    StoreDirtyInformation(AreDifferent(DataContract.EmployeeColor, value.ToString()), PropertyName_EmployeeBrush);
                    FirePropertyChanged(PropertyName_EmployeeBrush);
	            }
	        }
	    }

		public AbsenceTimeListVM AbsenceTimes
		{
			get { return _AbsenceTimes; }

			set
			{
				_AbsenceTimes = value;
				FirePropertyChanged(PropertyName_AbsenceTimes);
			}
		}

		public OvertimeListVM Overtimes
		{
			get { return _Overtimes; }

			set
			{
				_Overtimes = value;
				FirePropertyChanged(PropertyName_Overtimes);
			}
		}

		public List<AuszahlungsartDC> PossibleAuszahlungsarten
		{
			get { return _PossibleAuszahlungsarten.ToList(); }

			set
			{
				if (AreDifferent(_PossibleAuszahlungsarten.ToList(), value))
				{
					_PossibleAuszahlungsarten = value;
				}
			}
		}

		public ContractListVM Contracts
		{
			get { return _Contracts; }

			set
			{
				_Contracts = value;
				FirePropertyChanged(PropertyName_Contracts);
			}
		}

		public ContractVM LastContract
		{
			get
			{
				DateTime maxDate = DateTime.MinValue;
				ContractVM contractWithMaxDate = null;

				if (Contracts != null)
				{
					foreach (ContractVM item in Contracts.VMList)
					{
						if (!item.ContractEndDate.HasValue)
						{
							contractWithMaxDate = item;
							maxDate = DateTime.MaxValue;
						}
						else if (item.ContractEndDate.Value > maxDate)
						{
							maxDate = item.ContractEndDate.Value;
							contractWithMaxDate = item;
						}
					}
				}

				return contractWithMaxDate;
			}
		}

		public string AccountNumber
		{
			get { return _AccountNumber; }

			set
			{
				if (AreDifferent(_AccountNumber, value))
				{
					_AccountNumber = value;

					StoreDirtyInformation(AreDifferent(DataContract.AccountNumber, value), PropertyName_AccountNumber);

					FirePropertyChanged(PropertyName_AccountNumber);
				}
			}
		}

		public string BankCode
		{
			get { return _BankCode; }

			set
			{
				if (AreDifferent(_BankCode, value))
				{
					_BankCode = value;

					StoreDirtyInformation(AreDifferent(DataContract.BankCode, value), PropertyName_BankCode);

					FirePropertyChanged(PropertyName_BankCode);
				}
			}
		}

		public string BankName
		{
			get { return _BankName; }

			set
			{
				if (AreDifferent(_BankName, value))
				{
					_BankName = value;

					StoreDirtyInformation(AreDifferent(DataContract.BankName, value), PropertyName_BankName);

					FirePropertyChanged(PropertyName_BankName);
				}
			}
		}

		public string Bic
		{
			get { return _Bic; }

			set
			{
				if (AreDifferent(_Bic, value))
				{
					_Bic = value;

					StoreDirtyInformation(AreDifferent(DataContract.Bic, value), PropertyName_Bic);

					FirePropertyChanged(PropertyName_Bic);
				}
			}
		}

		//public int CancellationPeriod
		//{
		//    get { return this._CancellationPeriod; }

		//    set
		//    {
		//        if (this.AreDifferent(this._CancellationPeriod, value))
		//        {
		//            this._CancellationPeriod = value;

		//            this.StoreDirtyInformation(this.AreDifferent(this.DataContract.CancellationPeriod, value), PropertyName_CancellationPeriod);

		//            this.FirePropertyChanged(PropertyName_CancellationPeriod);
		//        }
		//    }
		//}

		public CustomerEmployeeRelationListVM CustomerRelations
		{
			get { return _CustomerRelations; }

			set
			{
				_CustomerRelations = value;
				FirePropertyChanged(PropertyName_CustomerRelations);
			}
		}

		[Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
		public DateTime? DateOfBirth
		{
			get { return _DateOfBirth; }

			set
			{
				if (AreDifferent(_DateOfBirth, value))
				{
					_DateOfBirth = value;

					StoreDirtyInformation(AreDifferent(DataContract.DateOfBirth, value), PropertyName_DateOfBirth);

					FirePropertyChanged(PropertyName_DateOfBirth);
				}
			}
		}

		public string EMail
		{
			get { return _EMail; }

			set
			{
				if (AreDifferent(_EMail, value))
				{
					_EMail = value;

					StoreDirtyInformation(
						DataContract.ContactInformations.SingleOrDefault(
							con => con.ContactType == ContactType.business_Mail && con.ContactValue == value) == null,
						PropertyName_EMail);

					FirePropertyChanged(PropertyName_EMail);
				}
			}
		}

		//public string EmploymentType
		//{
		//    get { return this._EmploymentType; }

		//    set
		//    {
		//        if (this.AreDifferent(this._EmploymentType, value))
		//        {
		//            this._EmploymentType = value;

		//            bool lDirty = true;
		//            if (this.DataContract.EmploymentType != null)
		//            {
		//                lDirty = this.DataContract.EmploymentType.TypeDescription != value;
		//            }

		//            this.StoreDirtyInformation(lDirty, PropertyName_EmploymentType);

		//            this.FirePropertyChanged(PropertyName_EmploymentType);
		//        }
		//    }
		//}

		//public DateTime? EntryDate
		//{
		//    get { return this._EntryDate; }

		//    set
		//    {
		//        if (this.AreDifferent(this._EntryDate, value))
		//        {
		//            this._EntryDate = value;

		//            this.StoreDirtyInformation(this.AreDifferent(this.DataContract.EntryDate, value), PropertyName_EntryDate);

		//            this.FirePropertyChanged(PropertyName_EntryDate);
		//        }
		//    }
		//}

		public FamilyStatus? FamilyStatus
		{
			get { return _FamilyStatus; }

			set
			{
				if (AreDifferent(_FamilyStatus, value))
				{
					_FamilyStatus = value;
					StoreDirtyInformation(AreDifferent(DataContract.FamilyStatus, value), PropertyName_FamilyStatus);
					FirePropertyChanged(PropertyName_FamilyStatus);
				}
			}
		}

		public string Fax
		{
			get { return _Fax; }

			set
			{
				if (AreDifferent(_Fax, value))
				{
					_Fax = value;

					StoreDirtyInformation(
						DataContract.ContactInformations.Where(
							con => con.ContactType == ContactType.business_Fax && con.ContactValue == value).SingleOrDefault() == null,
						PropertyName_Fax);

					FirePropertyChanged(PropertyName_Fax);
				}
			}
		}

		[Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
		public string FirstName
		{
			get { return _FirstName; }

			set
			{
				if (AreDifferent(_FirstName, value))
				{
					_FirstName = value;

					StoreDirtyInformation(AreDifferent(DataContract.FirstName, value), PropertyName_FirstName);

					FirePropertyChanged(PropertyName_FirstName);
				}
			}
		}

		public ObservableSortCollection<ValueListEntryDC> Focuses
		{
			get
			{
				return _Focuses ?? (_Focuses = new ObservableSortCollection<ValueListEntryDC>(Comparer.ValueListEntryDCComparer));
			}
		}

		public string HealthInsurance
		{
			get { return _HealthInsurance; }

			set
			{
				if (AreDifferent(_HealthInsurance, value))
				{
					_HealthInsurance = value;

					StoreDirtyInformation(AreDifferent(DataContract.HealthInsurance, value), PropertyName_HealthInsurance);

					FirePropertyChanged(PropertyName_HealthInsurance);
				}
			}
		}

		//public decimal? HourlyRate
		//{
		//    get { return this._HourlyRate; }

		//    set
		//    {
		//        if (this.AreDifferent(this._HourlyRate, value))
		//        {
		//            this._HourlyRate = value;

		//            this.StoreDirtyInformation(this.AreDifferent(this.DataContract.HourlyRate, value), PropertyName_HourlyRate);

		//            this.FirePropertyChanged(PropertyName_HourlyRate);
		//        }
		//    }
		//}

		public string IBAN
		{
			get { return _IBAN; }

			set
			{
				if (AreDifferent(_IBAN, value))
				{
					_IBAN = value;

					StoreDirtyInformation(AreDifferent(DataContract.IBAN, value), PropertyName_IBAN);

					FirePropertyChanged(PropertyName_IBAN);
				}
			}
		}

		public string InsuranceNumber
		{
			get { return _InsuranceNumber; }

			set
			{
				if (AreDifferent(_InsuranceNumber, value))
				{
					_InsuranceNumber = value;

					StoreDirtyInformation(AreDifferent(DataContract.InsuranceNumber, value), PropertyName_InsuranceNumber);

					FirePropertyChanged(PropertyName_InsuranceNumber);
				}
			}
		}

		public override bool IsDirty
		{
			get
			{
				return base.IsDirty || (CustomerRelations != null && CustomerRelations.IsDirty)
					   || (_AbsenceTimes != null && _AbsenceTimes.IsDirty) || (_Contracts != null && _Contracts.IsDirty) || (_Overtimes != null && _Overtimes.IsDirty);
			}
		}

		// HACK: Bug bei den RadioButtons, geben false nicht weiter
		// TODO nochmal angucken wenn mehr als zwei Optionen, dann in listbox und an selected item binden
		// http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2146568&SiteID=1
		public bool IsFemale
		{
			get { return _IsFemale; }

			set
			{
				if (_IsFemale != value)
				{
					_IsFemale = value;
					_IsMale = !value;

					StoreDirtyInformation((DataContract.Sex == Sex.Female) != value, "sex");

					FirePropertyChanged(PropertyName_Female);
					FirePropertyChanged(PropertyName_Male);
				}
			}
		}

		public bool IsMale
		{
			get { return _IsMale; }

			set
			{
				if (_IsMale != value)
				{
					_IsMale = value;
					_IsFemale = !value;

					StoreDirtyInformation((DataContract.Sex == Sex.Male) != value, "sex");

					FirePropertyChanged(PropertyName_Female);
					FirePropertyChanged(PropertyName_Male);
				}
			}
		}

		public bool IsQualified
		{
			get { return _IsQualified; }

			set
			{
				if (AreDifferent(_IsQualified, value))
				{
					_IsQualified = value;
					StoreDirtyInformation(AreDifferent(DataContract.IsQualified, value), PropertyName_IsQualified);
					FirePropertyChanged(PropertyName_IsQualified);
				}
			}
		}

		[Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
		public string LastName
		{
			get { return _LastName; }

			set
			{
				if (AreDifferent(_LastName, value))
				{
					_LastName = value;

					StoreDirtyInformation(AreDifferent(DataContract.LastName, value), PropertyName_LastName);

					FirePropertyChanged(PropertyName_LastName);
				}
			}
		}

		//public decimal? LeaveDays
		//{
		//    get { return this._LeaveDays; }

		//    set
		//    {
		//        if (this.AreDifferent(this._LeaveDays, value))
		//        {
		//            this._LeaveDays = value;
		//            this.StoreDirtyInformation(this.AreDifferent(this.DataContract.LeaveDays, value), PropertyName_LeaveDays);
		//            this.FirePropertyChanged(PropertyName_LeaveDays);
		//        }
		//    }
		//}

		public string MobilePhone
		{
			get { return _MobilePhone; }

			set
			{
				if (AreDifferent(_MobilePhone, value))
				{
					_MobilePhone = value;

					StoreDirtyInformation(
						DataContract.ContactInformations.Where(
							con => con.ContactType == ContactType.business_MobilePhone && con.ContactValue == value).SingleOrDefault() ==
						null,
						PropertyName_MobilePhone);

					FirePropertyChanged(PropertyName_MobilePhone);
				}
			}
		}

		[Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
		public string PersonnelNumber
		{
			get { return _PersonnelNumber; }

			set
			{
				if (AreDifferent(_PersonnelNumber, value))
				{
					_PersonnelNumber = value;

					StoreDirtyInformation(AreDifferent(DataContract.PersonnelNumber, value), PropertyName_PersonnelNumber);

					FirePropertyChanged(PropertyName_PersonnelNumber);
				}
			}
		}

		public string Phone
		{
			get { return _Phone; }

			set
			{
				if (AreDifferent(_Phone, value))
				{
					_Phone = value;

					StoreDirtyInformation(
						DataContract.ContactInformations.Where(
							con => con.ContactType == ContactType.business_Phone && con.ContactValue == value).SingleOrDefault() == null,
						PropertyName_Phone);

					FirePropertyChanged(PropertyName_Phone);
				}
			}
		}

		//public IEnumerable<string> PossibleEmploymentTypeNames
		//{
		//    get { return this._PossibleEmploymentTypesBack.Select(empType => empType.TypeDescription); }
		//}

		//public IEnumerable<ValueListEntryDC> PossibleEmploymentTypes
		//{
		//    set { this._PossibleEmploymentTypesBack = value; }
		//}

		public ObservableSortCollection<ValueListEntryDC> PossibleFocuses
		{
			get { return _PossibleFocuses; }
		}

		public ObservableSortCollection<ValueListEntryDC> PossibleQualifications
		{
			get { return _PossibleQualifications; }
		}

		public string PostalCode
		{
			get { return _PostalCode; }

			set
			{
				if (AreDifferent(_PostalCode, value))
				{
					_PostalCode = value;

					StoreDirtyInformation(AreDifferent(DataContract.PostalCode, value), PropertyName_PostalCode);

					FirePropertyChanged(PropertyName_PostalCode);
				}
			}
		}

		public string PrivateEMail
		{
			get { return _PrivateEMail; }

			set
			{
				if (AreDifferent(_PrivateEMail, value))
				{
					_PrivateEMail = value;

					StoreDirtyInformation(
						DataContract.ContactInformations.Where(
							con => con.ContactType == ContactType.private_Mail && con.ContactValue == value).SingleOrDefault() == null,
						PropertyName_PrivateEMail);

					FirePropertyChanged(PropertyName_PrivateEMail);
				}
			}
		}

		//public int ProbationPeriod
		//{
		//    get { return this._ProbationPeriod; }

		//    set
		//    {
		//        if (this.AreDifferent(this._ProbationPeriod, value))
		//        {
		//            this._ProbationPeriod = value;

		//            this.StoreDirtyInformation(this.AreDifferent(this.DataContract.ProbationPeriod, value), PropertyName_ProbationPeriod);

		//            this.FirePropertyChanged(PropertyName_ProbationPeriod);
		//        }
		//    }
		//}

		public string Profession
		{
			get { return _Profession; }

			set
			{
				if (AreDifferent(_Profession, value))
				{
					_Profession = value;

					StoreDirtyInformation(AreDifferent(DataContract.Profession, value), PropertyName_Profession);

					FirePropertyChanged(PropertyName_Profession);
				}
			}
		}

		public ObservableSortCollection<ValueListEntryDC> Qualifications
		{
			get
			{
				return _Qualifications ?? (_Qualifications = new ObservableSortCollection<ValueListEntryDC>(Comparer.ValueListEntryDCComparer));
			}
		}

		public string Street
		{
			get { return _Street; }

			set
			{
				if (AreDifferent(_Street, value))
				{
					_Street = value;

					StoreDirtyInformation(AreDifferent(DataContract.Street, value), PropertyName_Street);

					FirePropertyChanged(PropertyName_Street);
				}
			}
		}

		public string TaxNumber
		{
			get { return _TaxNumber; }

			set
			{
				if (AreDifferent(_TaxNumber, value))
				{
					_TaxNumber = value;

					StoreDirtyInformation(AreDifferent(DataContract.TaxNumber, value), PropertyName_TaxNumber);

					FirePropertyChanged(PropertyName_TaxNumber);
				}
			}
		}

		public string Town
		{
			get { return _Town; }

			set
			{
				if (AreDifferent(_Town, value))
				{
					_Town = value;

					StoreDirtyInformation(AreDifferent(DataContract.Town, value), PropertyName_Town);

					FirePropertyChanged(PropertyName_Town);
				}
			}
		}

		//public decimal? WeeklyFLS
		//{
		//    get { return this._WeeklyFLS; }

		//    set
		//    {
		//        if (this.AreDifferent(this._WeeklyFLS, value))
		//        {
		//            this._WeeklyFLS = value;
		//            this.StoreDirtyInformation(this.AreDifferent(this.DataContract.WeeklyFLS, value), PropertyName_WeeklyFLS);
		//            this.FirePropertyChanged(PropertyName_WeeklyFLS);
		//        }
		//    }
		//}

		//public decimal? WeeklyTotalHours
		//{
		//    get { return this._WeeklyTotalHours; }

		//    set
		//    {
		//        if (this.AreDifferent(this._WeeklyTotalHours, value))
		//        {
		//            this._WeeklyTotalHours = value;
		//            this.StoreDirtyInformation(this.AreDifferent(this.DataContract.WeeklyTotalHours, value), PropertyName_WeeklyTotalHours);
		//            this.FirePropertyChanged(PropertyName_WeeklyTotalHours);
		//        }
		//    }
		//}

		public string Text1
		{
			get { return _Text1; }
			set
			{
				if (base.AreDifferent(_Text1, value))
				{
					_Text1 = value;

					StoreDirtyInformation(AreDifferent(DataContract.Text1, value), PropertyName_Text1);

					FirePropertyChanged(PropertyName_Text1);
				}
			}
		}

		public string Text2
		{
			get { return _Text2; }
			set
			{
				if (base.AreDifferent(_Text2, value))
				{
					_Text2 = value;

					StoreDirtyInformation(AreDifferent(DataContract.Text2, value), PropertyName_Text2);

					FirePropertyChanged(PropertyName_Text2);
				}
			}
		}

		public string Text3
		{
			get { return _Text3; }
			set
			{
				if (base.AreDifferent(_Text3, value))
				{
					_Text3 = value;

					StoreDirtyInformation(AreDifferent(DataContract.Text3, value), PropertyName_Text3);

					FirePropertyChanged(PropertyName_Text3);
				}
			}
		}

		public string Text4
		{
			get { return _Text4; }
			set
			{
				if (base.AreDifferent(_Text4, value))
				{
					_Text4 = value;

					StoreDirtyInformation(AreDifferent(DataContract.Text4, value), PropertyName_Text4);

					FirePropertyChanged(PropertyName_Text4);
				}
			}
		}

		public string Text5
		{
			get { return _Text5; }
			set
			{
				if (base.AreDifferent(_Text5, value))
				{
					_Text5 = value;

					StoreDirtyInformation(AreDifferent(DataContract.Text5, value), PropertyName_Text5);

					FirePropertyChanged(PropertyName_Text5);
				}
			}
		}

		public string Notice2
		{
			get { return _Notice2; }
			set
			{
				if (base.AreDifferent(_Notice2, value))
				{
					_Notice2 = value;

					StoreDirtyInformation(AreDifferent(DataContract.Notice2, value), PropertyName_Notice2);

					FirePropertyChanged(PropertyName_Notice2);
				}
			}
		}

		protected override void InitByDataContract(EmployeeDC pDataContract)
		{
			if (!IsNew)
			{
				_DateOfBirth = pDataContract.DateOfBirth;
				_FirstName = pDataContract.FirstName;
				_Abbreviation = pDataContract.Abbreviation;
				_FamilyStatus = pDataContract.FamilyStatus;
				_Sex = pDataContract.Sex;
				_HealthInsurance = pDataContract.HealthInsurance;
				_InsuranceNumber = pDataContract.InsuranceNumber;
				_LastName = pDataContract.LastName;
				_PersonnelNumber = pDataContract.PersonnelNumber;
				_PostalCode = pDataContract.PostalCode;
				_Profession = pDataContract.Profession;
				_Street = pDataContract.Street;
				_TaxNumber = pDataContract.TaxNumber;
				_Town = pDataContract.Town;
				_BankName = pDataContract.BankName;
				_AccountNumber = pDataContract.AccountNumber;
				_BankCode = pDataContract.BankCode;
				_IBAN = pDataContract.IBAN;
				_Bic = pDataContract.Bic;
				_FamilyStatus = pDataContract.FamilyStatus;
				_IsQualified = pDataContract.IsQualified == null || pDataContract.IsQualified.Value;
				_IsMale = pDataContract.Sex == Sex.Male;
				_IsFemale = pDataContract.Sex == Sex.Female;
				_Text1 = pDataContract.Text1;
				_Text2 = pDataContract.Text2;
				_Text3 = pDataContract.Text3;
				_Text4 = pDataContract.Text4;
				_Text5 = pDataContract.Text5;
				_Notice2 = pDataContract.Notice2;
			    _EmployeeColor = pDataContract.EmployeeColor;

				_IsArchived = pDataContract.ActivationType == ActivationTypeId.Archived;

				//this._CancellationPeriod = pDataContract.CancellationPeriod;
				//this._EntryDate = pDataContract.EntryDate;
				//this._ProbationPeriod = pDataContract.ProbationPeriod;
				//this._HourlyRate = pDataContract.HourlyRate;
				//this._WeeklyFLS = pDataContract.WeeklyFLS.HasValue ? Math.Round(pDataContract.WeeklyFLS.Value, 2) : pDataContract.WeeklyFLS;
				//this._WeeklyTotalHours = pDataContract.WeeklyTotalHours.HasValue ? Math.Round(pDataContract.WeeklyTotalHours.Value, 2) : pDataContract.WeeklyTotalHours;
				//this._LeaveDays = pDataContract.LeaveDays.HasValue ? Math.Round(pDataContract.LeaveDays.Value, 2) : pDataContract.LeaveDays;

                if (!String.IsNullOrEmpty(pDataContract.EmployeeColor))
                {
                    EmployeeBrush = (SolidColorBrush)new BrushConverter().ConvertFrom(_EmployeeColor);
                }

				VMFactory.CreateAbsenceTimeListVMAsync(pDataContract.AbsenceTimes ?? (pDataContract.AbsenceTimes = new List<AbsenceTimeDC>()), cb => AbsenceTimes = cb);
				VMFactory.CreateOvertimeListVMAsync(pDataContract.Overtimes ?? (pDataContract.Overtimes = new List<OvertimeDC>()), cb => Overtimes = cb);
				CustomerRelations = VMFactory.CreateCustomerEmployeeRelationListVM(pDataContract.RelatedCustomers ?? (pDataContract.RelatedCustomers = new List<CustomerEmployeeRelationDC>()));

				if (pDataContract.Focuses != null)
				{
					_Focuses = new ObservableSortCollection<ValueListEntryDC>(pDataContract.Focuses, Comparer.ValueListEntryDCComparer);
				}

				if (pDataContract.Qualifications != null)
				{
					_Qualifications = new ObservableSortCollection<ValueListEntryDC>(pDataContract.Qualifications,
						Comparer.ValueListEntryDCComparer);
				}

				foreach (ContactDC iContactDC in pDataContract.ContactInformations)
				{
					if (iContactDC.ContactType == ContactType.private_Mail)
					{
						_PrivateEMail = iContactDC.ContactValue;
					}

					if (iContactDC.ContactType == ContactType.business_Mail)
					{
						_EMail = iContactDC.ContactValue;
					}

					if (iContactDC.ContactType == ContactType.business_Fax)
					{
						_Fax = iContactDC.ContactValue;
					}

					if (iContactDC.ContactType == ContactType.business_Phone)
					{
						_Phone = iContactDC.ContactValue;
					}

					if (iContactDC.ContactType == ContactType.business_MobilePhone)
					{
						_MobilePhone = iContactDC.ContactValue;
					}
				}

				//if (pDataContract.EmploymentType != null)
				//{
				//    this._EmploymentType = pDataContract.EmploymentType.TypeDescription;
				//}
			}

			Focuses.CollectionChanged += (s, e) => StoreDirtyInformation(!_Focuses.ContainsSameItemsAs(pDataContract.Focuses), PropertyName_Focuses);
			Qualifications.CollectionChanged += (s, e) => StoreDirtyInformation(!_Qualifications.ContainsSameItemsAs(pDataContract.Qualifications), PropertyName_Qualifications);
		}

		protected override EmployeeDC MapToDataContract(EmployeeDC pDataContract, bool doCommit)
		{
			pDataContract.DateOfBirth = _DateOfBirth;
			pDataContract.FirstName = _FirstName;
			pDataContract.Abbreviation = _Abbreviation;
			pDataContract.FamilyStatus = _FamilyStatus;
			pDataContract.HealthInsurance = _HealthInsurance;
			pDataContract.InsuranceNumber = _InsuranceNumber;
			pDataContract.LastName = _LastName;
			pDataContract.PersonnelNumber = _PersonnelNumber;
			pDataContract.PostalCode = _PostalCode;
			pDataContract.Profession = _Profession;
			pDataContract.Street = _Street;
			pDataContract.TaxNumber = _TaxNumber;
			pDataContract.Town = _Town;
			pDataContract.BankName = _BankName;
			pDataContract.AccountNumber = _AccountNumber;
			pDataContract.BankCode = _BankCode;
			pDataContract.IBAN = _IBAN;
			pDataContract.Bic = _Bic;
			pDataContract.FamilyStatus = _FamilyStatus;
			pDataContract.IsQualified = _IsQualified;
			pDataContract.Text1 = _Text1;
			pDataContract.Text2 = _Text2;
			pDataContract.Text3 = _Text3;
			pDataContract.Text4 = _Text4;
			pDataContract.Text5 = _Text5;
			pDataContract.Notice2 = _Notice2;
		    pDataContract.EmployeeColor = _EmployeeColor;

			pDataContract.ActivationType = _IsArchived ? ActivationTypeId.Archived : ActivationTypeId.Active;
			//pDataContract.CancellationPeriod = this._CancellationPeriod;
			//pDataContract.EntryDate = this._EntryDate;
			//pDataContract.ProbationPeriod = this._ProbationPeriod;
			//pDataContract.HourlyRate = this._HourlyRate;
			//pDataContract.LeaveDays = this._LeaveDays;
			//pDataContract.WeeklyFLS = this._WeeklyFLS;
			//pDataContract.WeeklyTotalHours = this._WeeklyTotalHours;


			CommitContact(_MobilePhone, ContactType.business_MobilePhone);
			CommitContact(_Phone, ContactType.business_Phone);
			CommitContact(_Fax, ContactType.business_Fax);
			CommitContact(_EMail, ContactType.business_Mail);
			CommitContact(_PrivateEMail, ContactType.private_Mail);

			if (this._IsMale)
				pDataContract.Sex = Sex.Male;
			if (this._IsFemale)
				pDataContract.Sex = Sex.Female;

			if (_CustomerRelations != null)
			{
				pDataContract.RelatedCustomers = _CustomerRelations.CopyToDCList(doCommit);
			}

			pDataContract.Focuses = _Focuses.ToList();
			pDataContract.Qualifications = _Qualifications.ToList();
			if (_AbsenceTimes != null)
			{
				pDataContract.AbsenceTimes = _AbsenceTimes.CopyToDCList(doCommit);
			}

			if (_Contracts != null)
			{
				pDataContract.Contracts = _Contracts.CopyToDCList(doCommit);
			}

			if (_Overtimes != null)
			{
				pDataContract.Overtimes = _Overtimes.CopyToDCList(doCommit);
			}
			//if (this._PossibleEmploymentTypesBack != null)
			//{
			//    ValueListEntryDC lEmplyomentType = this._PossibleEmploymentTypesBack.SingleOrDefault(empType => empType.TypeDescription == this._EmploymentType);

			//    if ((pDataContract.EmploymentType == null && lEmplyomentType != null) || pDataContract.EmploymentType != null)
			//    {
			//        pDataContract.EmploymentType = lEmplyomentType;
			//    }
			//}

			return pDataContract;
		}

		private void CommitContact(string pValue, ContactType pContactType)
		{
			List<ContactDC> lOldContactDCs;
			if (DataContract.ContactInformations != null)
			{
				lOldContactDCs = DataContract.ContactInformations.ToList();
			}
			else
			{
				lOldContactDCs = new List<ContactDC>();
			}

			ContactDC lContactDC = null;
			try
			{
				lContactDC = lOldContactDCs.SingleOrDefault(con => con.ContactType == pContactType);
			}
			catch (Exception)
			{
				// donothing
			}

			if (string.IsNullOrEmpty(pValue) && lContactDC != null)
			{
				lOldContactDCs.Remove(lContactDC);
			}
			else if (!string.IsNullOrEmpty(pValue))
			{
				if (lContactDC == null)
				{
					lContactDC = new ContactDC
					{
						ContactType = pContactType
					};
					lOldContactDCs.Add(lContactDC);
				}

				lContactDC.ContactValue = pValue;
			}

			DataContract.ContactInformations = lOldContactDCs;
		}
	}
}