using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Threading;

using BeWo.Core;
using BeWo.ServiceProxy;
using BeWo.Validation;
using BeWo.View.Controls;
using BeWo.ViewModel;
using BeWo.ViewModel.ListViewModel;

using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Services;
using DevExpress.Utils;
using DevExpress.Xpf.Docking;
using DevExpress.Xpf.Editors;
using DevExpress.Xpf.Editors.Settings;
using DevExpress.Xpf.Grid;

namespace BeWo.View.Detail
{
    public partial class AdditionalServiceView : BeWoView, INotifyPropertyChanged
    {
        private GroupOfPeopleView _GroupOfPeopleModalPopUp;

        private AdditionalServiceGroupOfPeopleView _AdditionalServiceGroupOfPeoplePopUp;

        private readonly Dictionary<DayOfWeek, CheckBox> _DayBoxes = new Dictionary<DayOfWeek, CheckBox>();

        private CompactEmployeeDC _SelectedEmployee;

        private ServiceRecordListVM _ViewModel;

        private AssessmentSheetEntryView assessmentSheet;

        public AdditionalServiceView(ServiceRecordListVM pViewModel)
        {
            InitializeComponent();
            multiAddServGroupOfPeopleSelectionControl.EditGroupButtonClicked += multiAddServGroupOfPeopleSelectionControl_EditGroupButtonClicked;
            popup_content.Visibility = Visibility.Hidden;


            ViewModel = pViewModel;
            ViewModel.ShowOnlyAdditionalServiceRecords = true;

            DownloadLinkEngine = new DownloadLinkEngine();
            linkExcelExport.NavigateUri = DownloadLinkEngine.GenerateNewExcelLink();

            combobox_services.SelectionChanged += (s, e) =>
                {
                    if (combobox_services.SelectedIndex == -1)
                        combobox_services.SelectedIndex = 0;
                };

            InitDayCheckBoxes();

            Loaded += ServiceRecordView2_Loaded;


            if (BeWoApp.LoggedOnUser.HasRight(UserRightType.AssessmentSheet_View))
            {
                assessmentSheet = new AssessmentSheetEntryView();
                punktebogenRootGrid.Children.Clear();
                punktebogenRootGrid.Children.Add(assessmentSheet);
                assessmentSheet.Visibility = Visibility.Collapsed;
            } 
            else
            {
                punktebogenRootGrid.Visibility = Visibility.Collapsed;
            }
            multiEmployeeControlAddServ.SelectedEmployees.CollectionChanged += multiEmployeeAddServ_CollectionChanged;

            AdditionalServiceBookings = new AdditionalServiceBookingListVM(ServiceFacade.DoOperationsServiceSync(s => s.GetAllAdditionalServiceBookings()));
            
            ReloadAdditionalServiceRelatedObjects();

            Years = new int[10];
            for (var i = (Years.Length - 1); i > -1; i--)
                Years[i] = DateTime.Now.Year - i;

            MonatsCombobox.DataContext = this;
            JahresCombobox.DataContext = this;
            teilnahmeGrid.DataContext = this;

            SelectedYear = Years[0];
            SelectedMonth = (Monat) DateTime.Now.Month;
            
            MonatsCombobox.SelectedIndex = 0;
            JahresCombobox.SelectedIndex = 0;

            saveBtn.IsEnabled = false;

            supportConceptSelectionControl.SupportConceptList = new List<CompactSupportConceptDC>();
        }
        public event PropertyChangedEventHandler PropertyChanged;
        void multiEmployeeAddServ_CollectionChanged(object sender, EventArgs e)
        {
            AdditionalServiceBookings.NewVM.EmployeeList = multiEmployeeControlAddServ.SelectedEmployees;
            if (AdditionalServiceBookings.NewVM.EmployeeList.Count <= 0) 
                return;

            _SelectedEmployee = AdditionalServiceBookings.NewVM.EmployeeList.First();
            popupedit_employee.Text = _SelectedEmployee.ToString();
        }

        public override bool CanDelete
        {
            get { return false; }
        }

        public List<AdditionalServiceDC> AdditionalServices { get; set; }
        public List<AdditionalServiceRegionDC> AdditionalServiceRegions { get; set; }
        public List<AdditionalServiceGroupOfPeopleDC> AdditionalServiceGroupOfPeoples { get; set; }

        public AdditionalServiceBookingListVM AdditionalServiceBookings { get; set; }
        private int _PreviousGridColumnCount;
        private int _GridColumnCount;
        public int GridColumnCount 
        { 
            get { return _GridColumnCount; } 
            set
            {
                _PreviousGridColumnCount = _GridColumnCount;
                _GridColumnCount = value;
            } 
        }

        public int[] Years { get; set; }
        private int _SelectedYear;
        public int SelectedYear 
        {
            get { return _SelectedYear; }
            set
            {
                _SelectedYear = value;

                if ((int) SelectedMonth == 0)
                    return;

                GridColumnCount = DateTime.DaysInMonth(value, (int)SelectedMonth);
                UpdateTeilnahmeGrid();
            }
        }

        private Monat _SelectedMonth;
        public Monat SelectedMonth
        {
            get { return _SelectedMonth; }
            set
            {
                _SelectedMonth = value;

                GridColumnCount = DateTime.DaysInMonth(SelectedYear, (int)value);
                UpdateTeilnahmeGrid();
            }
        }

        private List<Teilnehmer> _TeilnehmerListe;
        public List<Teilnehmer> TeilnehmerListe
        {
            get
            {
                if(_TeilnehmerListe!=null)
                    _TeilnehmerListe.Sort((x, y) => x.Customer.LastNameFirstName.CompareTo(y.Customer.LastNameFirstName));

                return _TeilnehmerListe ?? (_TeilnehmerListe = new List<Teilnehmer>());
            } 
            set
            {
                _TeilnehmerListe = value; 
                OnPropertyChanged("TeilnehmerListe");
            }
        }

        private List<AdditionalServiceBookingVM> _SelectedBookings;
        public List<AdditionalServiceBookingVM> SelectedBookings
        {
            get { return _SelectedBookings; }
            set
            {
                _SelectedBookings = value; 
                OnPropertyChanged("SelectedBookings");
            }
        }

        internal void UpdateTeilnahmeGrid()
        {
            if (angebotscombobox.SelectedItem == null)
                return;

            SelectedBookings = AdditionalServiceBookings.VMList.Where(asb => asb.AdditionalServiceRegion.AdditionalServiceRegionOid.Equals((angebotscombobox.SelectedItem as AdditionalServiceRegionDC).AdditionalServiceRegionOid) && 
                asb.Date.Year == SelectedYear && 
                asb.Date.Month == (int)SelectedMonth).ToList();

            TeilnehmerListe = new List<Teilnehmer>();

            foreach (var booking in SelectedBookings)
            {
                foreach (var teilnehmer in booking.CustomerList)
                {
                    var bookingRel = new Dictionary<long, BookingRelationDictionaryValue>();
                    var index = -1;
                    var anwesenheiten = new bool[GridColumnCount];

                    if (TeilnehmerListe.Any(t => t.Customer.Equals(teilnehmer.Key)))
                    {
                        var x = TeilnehmerListe.Where(t => t.Customer.Equals(teilnehmer.Key)).ToList();
                        anwesenheiten = x.First().TeilnahmenForUpdating;
                    }

                    anwesenheiten[booking.Date.Day - 1] = teilnehmer.Value;

                    foreach (var item in TeilnehmerListe.Where(item => item.Customer.Equals(teilnehmer.Key)))
                    {
                        index = TeilnehmerListe.IndexOf(item);
                        foreach (var element in item.BookingRelation.Where(element => !bookingRel.ContainsKey(element.Key)))
                            bookingRel.Add(element.Key, element.Value);
                    }

                    if (!bookingRel.ContainsKey(booking.DataContract.AdditionalServiceBookingOid.Value))
                        bookingRel.Add(booking.DataContract.AdditionalServiceBookingOid.Value, new BookingRelationDictionaryValue(booking.Date, booking.StartDate.Value, booking.EndDate.Value));

                    if (index >= 0)
                        TeilnehmerListe.RemoveAt(index);

                    TeilnehmerListe.Add(new Teilnehmer(teilnehmer.Key, anwesenheiten, bookingRel));
                }
            }

            if (_PreviousGridColumnCount < GridColumnCount)
                for (var i = _PreviousGridColumnCount + 1; i <= GridColumnCount; i++)
                    teilnahmeGrid.Columns[i].Visible = true;
            else
                for (var i = _PreviousGridColumnCount; i > GridColumnCount; i--)
                    teilnahmeGrid.Columns[i].Visible = false;

            teilnahmeGrid.ItemsSource = TeilnehmerListe;
            teilnahmeGrid.RefreshData();

            foreach (var item in teilnahmeGrid.Columns)
            {
                var swap = item.Header.ToString();
                item.Header = "";
                item.Header = swap;
            }
        }

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private void gridView1_DoubleClick(object sender, RoutedEventArgs e)
        {
            var selectedCustomer = ((sender as TableView).Grid.GetFocusedRow() as Teilnehmer).Customer;
            
            if(selectedCustomer != null)
                VMFactory.CreateCustomerVMAsync(selectedCustomer.CustomerOid, cb => this.Dispatch(
                        () => BeWoUtils.openModalViewWindow<CustomerVM, CustomerDC, AdditionalServiceView>(cb, this, () => this.Dispatch(
                        () => BeWoUtils.UpdateAllViews(selectedCustomer)))));
        }

        private void pg_ShownEditor(object sender, EditorEventArgs e)
        {
            if (!(e.Editor is CheckEdit)) 
                return;

            (e.Editor as CheckEdit).Tag = new CheckEditTag(e.Row as Teilnehmer, e.Column);
            (e.Editor as CheckEdit).Unchecked -= checked_changed;
            (e.Editor as CheckEdit).Unchecked += checked_changed;
            (e.Editor as CheckEdit).Checked -= checked_changed;
            (e.Editor as CheckEdit).Checked += checked_changed;
        }

        private readonly List<AdditionalServiceBookingDC> BookingsToUpdate = new List<AdditionalServiceBookingDC>();
        private void checked_changed(object sender, RoutedEventArgs e)
        {
            var s = sender as CheckEdit;
            var tag = s.Tag as CheckEditTag;
            var key = 0L;

            try
            {
                key = tag.Teilnehmer.BookingRelation.First(b => b.Value.Datum.Equals(new DateTime(SelectedYear, (int) SelectedMonth, tag.GetHeaderAsDay()))).Key;
            }
            catch (Exception wtf) { return; }

            var ab = AdditionalServiceBookings.VMList.First(asb => asb.DataContract.AdditionalServiceBookingOid.Value == key);
            
            ab.CustomerList[tag.Teilnehmer.Customer] = s.IsChecked.Value;

            if (!BookingsToUpdate.Contains(ab.CommitToDataContract()))
                BookingsToUpdate.Add(ab.CommitToDataContract());

            saveBtn.IsEnabled = true;
        }

        private void SaveBookingChanges(object sender, RoutedEventArgs e)
        {
            if (BookingsToUpdate.Count == 0)
                return;

            ServiceFacade.DoOperationsServiceAsync(o => o.UpdateAdditionalServiceBookings(BookingsToUpdate), 
                                                  () => this.Dispatch(
                                                      delegate
                                                          {
                                                              UpdateTeilnahmeGrid();
                                                              BookingsToUpdate.Clear();
                                                              saveBtn.IsEnabled = false;
                                                          }));
        }

        

        public DownloadLinkEngine DownloadLinkEngine { get; set; }

        public override bool IsDirty
        {
            get { return ViewModel != null && ViewModel.AddedCount != 0; }
        }

        public override string Title
        {
            get { return "Ergänzende Dienste"; }
        }

        public bool WithoutClient
        {
            get { return ViewModel != null && ViewModel.WithoutClient; }

            set
            {
                if (ViewModel != null)
                    ViewModel.WithoutClient = value;
            }
        }

        internal override DependencyObject ValidationOnSaveRootElement
        {
            get { return srListBox; }
        }

        private ServiceRecordListVM ViewModel
        {
            get { return _ViewModel; }

            set
            {
                _SelectedEmployee = BeWoApp.LoggedOnUser.Employee;
                popupedit_employee.Text = _SelectedEmployee.ToString();

                DataContext = value;

                SetEmployeeComboVisibility();

                //supportConceptSelectionControl.SelectedItem = new FlatSupportConceptTreeNodeDC();
                _ViewModel = value;
                
                _ViewModel.ServiceRecordListChanged += _ViewModel_ServiceRecordListChanged;

                if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecordView_Create) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.CreateAll))
                {
                    newObjectInfoGrid.IsEnabled = false;
                    button_add.IsEnabled = false;
                }

                Unloaded += ServiceRecordView2_Unloaded;
            }
        }

        public void AnimateOpacity(double pOpacitiy, double pDuration)
        {
            var lAnimation = new DoubleAnimation
                {From = detailContentGrid.Opacity, To = pOpacitiy, Duration = TimeSpan.FromMilliseconds(pDuration)};

            detailContentGrid.BeginAnimation(OpacityProperty, lAnimation);
        }

        public override void Delete()
        {
            Delete(GetSelectedServiceRecordFromListBox());
        }

        public void Delete(ServiceRecordVM vm)
        {
            if (vm == null) return;
            string msg = vm.GroupOid != null ? "ACHTUNG, wenn Sie fortfahren, löschen Sie die gesamte Gruppenbuchung.\nWenn Sie nur einzelne Klienten aus der Gruppe entfernen möchten,\neditieren Sie die Gruppe und entfernen den Klienten aus der Liste aller Hilfepläne.\nSind Sie sicher, dass Sie dem gesamten Gruppeneintrag löschen möchten?" : "Sind Sie sicher, dass Sie den gewählten Eintrag löschen möchten?";

            if (MessageBox.Show(msg, "Eintrag löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                if (vm.GroupOid != null)
                {
                    List<ServiceRecordVM> deletedVMs = ViewModel.VMList.Where(item => item.GroupOid != null && item.GroupOid.Value == vm.GroupOid.Value).ToList();

                    foreach (var deletedVM in deletedVMs)
                    {
                        ViewModel.VMList.Remove(deletedVM);
                    }
                }
                else
                {
                    ViewModel.VMList.Remove(vm);
                }

                var lDC = vm.CommitToDataContract();
                ServiceFacade.DoOperationsServiceAsync(s => s.DeleteServiceRecord(lDC.ServiceRecordOid.Value, lDC.ServiceRecordVersion.Value), RefreshGrid);
            }
        }

        public ServiceRecordVM GetSelectedServiceRecordFromListBox()
        {
            return (ServiceRecordVM)srListBox.SelectedItem;
        }

        public void SetSelectedServiceRecordVM(ServiceRecordVM vm)
        {
            srListBox.SelectedItem = vm;
        }

        protected override void Save()
        {
            var lToDos = new List<Action<IOperationsService>>();

            if (ViewModel.AddedCount > 0)
            {
                lToDos.Add(
                    s =>
                        {
                            var newItems = ViewModel.CommitAdded();
                            try
                            {
                                List<long> oids = s.InsertNewServiceRecords(newItems);

                                int idx = 0;
                                foreach (ServiceRecordVM vm in ViewModel.VMList)
                                {
                                    if (vm.IsNew)
                                    {
                                        vm.IsNew = false;
                                        vm.DataContract.ServiceRecordVersion = 1;
                                        vm.DataContract.ServiceRecordOid = oids[idx++];
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                List<ServiceRecordVM> newVMs = ViewModel.VMList.Where(vm => vm.IsNew).ToList();

                                foreach (var serviceRecordVm in newVMs)
                                    ViewModel.VMList.Remove(serviceRecordVm);

                                this.Dispatch(() => ViewModel.RefreshServiceRecordsForSelectedTreeNode());
                                
                                throw;
                            }
                    });
            }

            ServiceFacade.DoMultipleOperationsServicesAsync(lToDos, ReloadViewModel);
        }

        private void ReloadAdditionalServiceRelatedObjects()
        {
            AdditionalServices = ServiceFacade.DoOperationsServiceSync(f => f.GetAllAdditionalService());
            AdditionalServiceRegions = ServiceFacade.DoOperationsServiceSync(adsr => adsr.GetAllAdditionalServiceRegion());

            groupBoxAdditionalService.DataContext = this;

            AdditionalServiceBookings.NewVM.AdditionalServiceRegion = (AdditionalServiceRegionDC)angebotscombobox.SelectedItem;
        }

        private void ClosePopupView()
        {
            this.SetPopupViewVisible(false);
            this.popup_content.Child = null;
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.VMList.Remove((ServiceRecordVM)((Button)sender).Tag);
            Save();
        }

        private void Edit(ServiceRecordVM vm)
        {
            ServiceRecordVM backup = new ServiceRecordVM();
            bool notOverlapping = true;

            if (vm != null && vm.EditAllowed)
            {
                BeWoView serviceRecordEditView = null;
                double height = 450;
                double width = 800;
                if (vm.GroupOid != null)
                    serviceRecordEditView = new ServiceRecordGroupEditView();
                else
                    serviceRecordEditView = new ServiceRecordEditView();

                popup_content.Child = serviceRecordEditView;
                popup_content.Width = width;

                if (rootGrid.ActualHeight < height)
                    height = rootGrid.ActualHeight;

                popup_content.Height = height;

                if (serviceRecordEditView.CommandBindings.Count == 0)
                {
                    serviceRecordEditView.CommandBindings.Add(
                        new CommandBinding(
                            ApplicationCommands.Close,
                            (s, e) =>
                            {
                                if (!serviceRecordEditView.DoSaveCheck()) 
                                    return;
                                ClosePopupView();
                                ViewModel.RefreshServiceRecordsForSelectedTreeNode();

                                SetSelectedServiceRecordVM(vm);
                            }));
                    serviceRecordEditView.CommandBindings.Add(
                        new CommandBinding(
                            ApplicationCommands.Save,
                            (s, e) =>
                            {
                                bool save;
                                if (serviceRecordEditView is ServiceRecordEditView)
                                {
                                    save = ((ServiceRecordEditView)serviceRecordEditView).IsValid() && ((ServiceRecordEditView)serviceRecordEditView).IsCustomerChangeAllowed();
                                    //backup = (e.Source as ServiceRecordEditView).ViewModel.SelectedVMForEditing;
                                }
                                else
                                    save = ((ServiceRecordGroupEditView)serviceRecordEditView).IsValid() && ((ServiceRecordGroupEditView)serviceRecordEditView).IsCustomerChangeAllowed();

                                if (save)
                                {
                                    serviceRecordEditView.SaveData();
                                    this.ClosePopupView();

                                    if (serviceRecordEditView is ServiceRecordEditView)
                                    {
                                        vm.Employee = _SelectedEmployee;
                                        //notOverlapping = ServiceFacade.DoOperationsServiceSync(overlaps => overlaps.DoesNotOverlapWithOtherServiceRecord(vm.CommitToDataContract(), vm.Customer.Oid.Value, vm.Employee.EmployeeOid));

                                        //if (!notOverlapping)
                                        //{
                                        //    MessageBox.Show("Der gewählte Zeitpunkt '" + vm.DateAndTime.Value.ToShortDateString() + " " + vm.DateAndTime.Value.ToShortTimeString() + "' überschneidet sich mit einem bereits existierenden Eintrag desselben Hilfeplans.\nSpeichern nicht möglich.", "Speichern nicht möglich", MessageBoxButton.OK, MessageBoxImage.Information);
                                        //    SetSelectedServiceRecordVM(backup);
                                            
                                        //    return;
                                        //}

                                        ViewModel.RefreshServiceRecordsForSelectedTreeNode();
                                        SetSelectedServiceRecordVM(vm);
                                    }
                                }
                            }));
                }

                if (serviceRecordEditView is ServiceRecordEditView)
                {
                    ((ServiceRecordEditView)serviceRecordEditView).InitView(this.ViewModel, vm, this.WithoutClient);
                    serviceRecordEditView.ParentView = this;
                    this.SetPopupViewVisible(true);
                }
                else
                {
                    ServiceFacade.DoOperationsServiceAsync(
                        s => s.GetServiceRecordGroup(vm.GroupOid.Value),
                        r => this.Dispatch(
                            delegate
                            {
                                ((ServiceRecordGroupEditView)serviceRecordEditView).InitView(this.ViewModel, vm, r);

                                serviceRecordEditView.ParentView = this;
                                this.SetPopupViewVisible(true);
                            }));
                }
            }
        }

        private void ShowHistory(ServiceRecordVM vm)
        {
            if (vm != null)
            {
                double height = 450;
                double width = 800;

                ServiceRecordHistoryView serviceRecordHistoryView = new ServiceRecordHistoryView();

                this.popup_content.Child = serviceRecordHistoryView;
                this.popup_content.Width = width;

                if (this.rootGrid.ActualHeight < height)
                {
                    height = this.rootGrid.ActualHeight;
                }

                this.popup_content.Height = height;

                if (serviceRecordHistoryView.CommandBindings.Count == 0)
                {
                    serviceRecordHistoryView.CommandBindings.Add(
                        new CommandBinding(
                            ApplicationCommands.Close,
                            (s, e) => this.ClosePopupView()));

                }
                

                ServiceFacade.DoOperationsServiceAsync(
                    s => s.GetServiceRecordHistory(vm.DataContract.ServiceRecordOid.Value),
                        r => this.Dispatch(
                            delegate
                            {
                                serviceRecordHistoryView.InitView(r);

                                serviceRecordHistoryView.ParentView = this;
                                this.SetPopupViewVisible(true);
                            }));
            }
        }

        private void EmployeeSearchView_CustomerSelected(object sender, EventArgs<CompactEmployeeDC> e)
        {
            this._SelectedEmployee = e.Data;
            this.popupedit_employee.Text = this._SelectedEmployee.ToString();
            this.popup_employee.IsOpen = false;

            this.ViewModel.SelectedEmployee = this._SelectedEmployee;
            if (this.WithoutClient)
            {
                this.SelectedItemChanged(null);
            }
        }

        private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                {
                    return (childItem)child;
                }
                else
                {
                    childItem childOfChild = this.FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                    {
                        return childOfChild;
                    }
                }
            }

            return null;
        }

        private void InitDayCheckBoxes()
        {
            foreach (DayOfWeek iDay in Utils.GetDayOfWeeks(DayOfWeek.Monday))
            {
                CheckBox lCb = new CheckBox { Content = DateTimeFormatInfo.CurrentInfo.GetAbbreviatedDayName(iDay), Margin = new Thickness(3), IsHitTestVisible = DateTime.Now.DayOfWeek != iDay, };

                this._DayBoxes[iDay] = lCb;
                this.wrapPanel_days.Visibility = Visibility.Collapsed;
                this.wrapPanel_days.Children.Add(lCb);

                lCb.Checked += (s, e) => this.ViewModel.RecordingDays.Add(this._DayBoxes.Single(entry => entry.Value == s).Key);
                lCb.Unchecked += (s, e) => this.ViewModel.RecordingDays.Remove(this._DayBoxes.Single(entry => entry.Value == s).Key);

                lCb.IsChecked = DateTime.Now.DayOfWeek == iDay;
            }

            DependencyPropertyDescriptor.FromProperty(DateEdit.EditValueProperty, typeof(DateEdit)).AddValueChanged(
                this.datepicker_newDate,
                (s, e) => this._DayBoxes.DoForEach(
                    iCheck =>
                    {
                        iCheck.Value.IsChecked = this.datepicker_newDate.EditValue != null && iCheck.Key == this.datepicker_newDate.DateTime.DayOfWeek;
                        iCheck.Value.IsHitTestVisible = !iCheck.Value.IsChecked.Value;
                        iCheck.Value.IsEnabled = iCheck.Value.IsHitTestVisible;
                    }));
        }

        private bool IsPartOf(object p, Type type)
        {
            if (p != null)
            {
                FrameworkElement fe = p as FrameworkElement;
                if (fe != null)
                {
                    if (fe.GetType().Equals(type))
                    {
                        return true;
                    }
                    else
                    {
                        return this.IsPartOf(fe.TemplatedParent, type);
                    }
                }
            }

            return false;
        }

        private void RefreshGrid()
        {
            this.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal,
                (Action)delegate
                    {
                        ServiceRecordVM selected = GetSelectedServiceRecordFromListBox();
                        this.ViewModel.RefreshServiceRecordsForSelectedTreeNode();
                        this.SetSelectedServiceRecordVM(selected);
                    });
        }

        private void ReloadViewModel()
        {
            ViewModel.PrototypeVM.Notice = string.Empty;

            if (ViewModel.PrototypeVM.GoalTree == null || ViewModel.PrototypeVM.GoalTree.Count <= 0) 
                return;

            foreach (var child in ViewModel.PrototypeVM.GoalTree.SelectMany(item => item.Children.Where(child => child.IsChecked)))
                child.IsChecked = false;
        }

        private void SaveSingleBooking()
        {
            bool lValid = true;

            FlatSupportConceptTreeNodeDC selectedNode = null;
            if (this.ViewModel.CustomerNodes.Count > 0)
            {
                selectedNode = this.ViewModel.CustomerNodes[0];
            }

            if (!this.WithoutClient && (selectedNode == null || selectedNode.SupportConceptTreeNodeDC == null))
            {
                MessageBox.Show("Bitte wählen Sie zuerst einen Hilfeplan, für den Sie Leistungen dokumentieren möchten.", "Speichern", MessageBoxButton.OK, MessageBoxImage.Information);
                lValid = false;
            }

            if (lValid)
            {
                lValid = this.ValidateServiceRecordVM(this.ViewModel.PrototypeVM, selectedNode, false);

                if (lValid)
                {
                    // StringBuilder lSb = new StringBuilder("Folgende Leistungen wurden der Übersicht hinzugefügt:\n\n");
                    bool save = false;
                    foreach (var iVM in this.ViewModel.CreateFromPrototype())
                    {
                        iVM.Employee = this._SelectedEmployee;

                        // lSb.Append("\t" + iVM.ToString() + "\n");

                        // ###AddServiceRecord
                        this.ViewModel.VMList.Add(iVM);
                        save = true;
                    }

                    // lSb.Append("\nSpeichern Sie zur endgültigen Buchung.");
                    // MessageBox.Show(lSb.ToString());

                    // ViewModel.VMList.Sort();
                    if (save)
                    {
                        this.Save();
                        this.ViewModel.RefreshServiceRecordsForSelectedTreeNode();
                    }
                }
            }
        }

        
        private void SelectedItemChanged(FlatSupportConceptTreeNodeDC selectedNode)
        {
            if (this.ViewModel != null)
            {
                UpdateAssessmentSheet(selectedNode);

                this.ViewModel.ChangeTreeItemSelection(selectedNode);
                this.srListBox.SelectedIndex = -1;

                ScrollViewer sv = this.FindVisualChild<ScrollViewer>(this.srListBox);
                if (sv != null)
                    sv.ScrollToTop();

                this.UpdateServiceRecordListReportUrl(selectedNode);
            }
        }

        private void ServiceRecordView2_Loaded(object sender, RoutedEventArgs e)
        {
            //this.supportConceptSelectionControl.Focus();
        }
       

        private void ServiceRecordView2_Unloaded(object sender, RoutedEventArgs e)
        {
            // BeWoApp.SaveAppSettings();
        }

        private void SetEmployeeComboVisibility()
        {
            //if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecord_AllowCreationForOtherEmployees) || this.chkGroupBooking.IsChecked.Value)
            //{
            //    this.lblEmployee.Visibility = Visibility.Collapsed;
            //    this.popupedit_employee.Visibility = Visibility.Collapsed;
            //}
            //else
            //{
            //    this.lblEmployee.Visibility = Visibility.Visible;
            //    this.popupedit_employee.Visibility = Visibility.Visible;
            //}
        }

        private void SetPopupViewVisible(bool visible)
        {
            popup_content.Visibility = visible ? Visibility.Visible : Visibility.Hidden;

            if (visible)
                AnimateOpacity(0.5, 200);
            else
                AnimateOpacity(1, 100);
        }

        private void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            var vm = ((TextBox)sender).Tag as ServiceRecordVM;
            if (vm != null)
                srListBox.SelectedItem = vm;
        }

        
        private void UpdateServiceRecordListReportUrl(FlatSupportConceptTreeNodeDC selectedNode)
        {
            string url;

            long scOid = 0;
            long cOid = 0;
            long cb2scOid = 0;
            long eOid = BeWoApp.LoggedOnUser.Employee.EmployeeOid;

            // if (ViewModel != null && ViewModel.ServiceRecordsForSelectedCustomer != null && ViewModel.ServiceRecordsForSelectedCustomer.Count > 0)
            // {
            if (selectedNode != null && selectedNode.SupportConceptTreeNodeDC != null)
            {
                if (selectedNode.SupportConceptTreeNodeDC.SupportConcept != null)
                {
                    scOid = selectedNode.SupportConceptTreeNodeDC.SupportConcept.SupportConceptOid;
                }

                if (selectedNode.SupportConceptTreeNodeDC.Customer != null)
                {
                    cOid = selectedNode.SupportConceptTreeNodeDC.Customer.CustomerOid;
                }

                if (selectedNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC != null)
                {
                    cb2scOid = selectedNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid.Value;
                }
            }

            url = BeWoApp.SiteOfOrigin + "/ReportView.aspx" + "?tenant=" + BeWoApp.Tenant + "&username=" + BeWoApp.UserName + "&token=" + BeWoApp.LoggedOnUser.RC2Password + "&eOid=" + eOid + "&scOid=" + scOid + "&cOid=" + cOid + "&cb2scOid=" + cb2scOid + "&type=" + Utils.EnumName(ReportTypes.ServiceRecordList);

            url = BeWoWpfUtils.GetHTMLEncodedURL(url);

            this.linkPdfExport.NavigateUri = new Uri(url);

            // }
        }

        private void UpdateViewModel()
        {
            // VMFactory.CreateServiceRecordVMAsync(BeWoApp.LoggedOnUser.Employee.EmployeeOid, r =>
            // this.Dispatch(delegate { ViewModel = r; }));
            this.Dispatch(
                delegate
                {
                    this.ReloadViewModel();
                    this.ViewModel.RefreshServiceRecordsForSelectedTreeNode();
                });
        }

        private bool ValidateAdditionalServiceBookings()
        {
            const bool lValid = true;

            if (AdditionalServiceBookings.NewVM.CustomerList.Count == 0)
            {
                MessageBox.Show("Bitte wählen Sie mindestens einen Klienten aus, für den dieses Angebot gebucht werden soll.", 
                                "Buchen nicht möglich", 
                                MessageBoxButton.OK, 
                                MessageBoxImage.Information);
                return false;
            }

            if (AdditionalServiceBookings.NewVM.EmployeeList.Count == 0)
            {
                MessageBox.Show("Bitte wählen Sie mindestens einen Mitarbeiter aus, für den dieses Angebot gebucht werden soll.", 
                                "Buchen nicht möglich", 
                                MessageBoxButton.OK, 
                                MessageBoxImage.Information);
                return false;
            }

            return lValid;
        }

        private bool ValidateServiceRecordVM(ServiceRecordVM vm, FlatSupportConceptTreeNodeDC node, bool isGroupBooking)
        {
            bool lValid = true;

            DateTime? date = vm.DateAndTime;

            if (date.HasValue)
            {
                if (!this.WithoutClient && BeWoApp.AppSettings.MaxDaysEditServiceRecordsAllowed > 0)
                {
                    if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecord_AllowEditAfterMaxDaysInNextMonth))
                    {
                        DateTime dt = new DateTime(date.Value.Year, date.Value.Month, 1);
                        dt = dt.AddMonths(1);
                        dt = dt.AddDays(BeWoApp.AppSettings.MaxDaysEditServiceRecordsAllowed);
                        if (DateTime.Now >= dt)
                        {
                            MessageBox.Show("Sie können keine neuen Leistungen für den " + date.Value.ToShortDateString() + " dokumentieren, da bereits der " + BeWoApp.AppSettings.MaxDaysEditServiceRecordsAllowed + ". des nachfolgenden Monats überschritten ist.", "Speichern", MessageBoxButton.OK, MessageBoxImage.Information);
                            lValid = false;
                        }
                    }
                }

                decimal duration = (decimal)vm.Duration;
                decimal roundedDuration = duration;

                if (lValid && node != null)
                {
                    if (vm.ServiceDescription != null && vm.ServiceDescription.Category != null && vm.ServiceDescription.Category.IsBillable && node.SupportConceptTreeNodeDC.CostBearer != null)
                    {
                        int minuteInterval = node.SupportConceptTreeNodeDC.CostBearer.ActualMinuteIntervall;
                        if (minuteInterval > 0)
                        {
                            roundedDuration = vm.Duration.Value % minuteInterval != 0 ? vm.Duration.Value + (minuteInterval - (vm.Duration.Value % minuteInterval)) : vm.Duration.Value;
                        }
                    }

                    if (!isGroupBooking && vm.GoalTree != null && vm.GoalTree.Count > 0)
                        if (vm.SelectedGoals.Count == 0)
                            if (MessageBox.Show("Es wurde kein Ziel zugeordnet. Sind Sie sicher dass Sie speichern möchten?", "Speichern", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                                lValid = false;

                    if (lValid)
                    {
                        if (node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC != null)
                        {
                            var reldc = node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC;
                            decimal totalFLSApproved = Calculations.GetInstance(reldc.CostBearer.CostBearerID).GetApprovedHoursTotal(reldc, true) ?? 0m;
                            if (totalFLSApproved > 0)
                            {
                                decimal totalFLSRounded = this.ViewModel.FLSTotalRounded;
                                decimal totalFLSNew = totalFLSRounded + (roundedDuration / 60);
                                if (vm.ServiceDescription.Category.IsBillable && totalFLSNew > totalFLSApproved)
                                {
                                    if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecord_AllowCreateMoreFLSThanApproved))
                                    {
                                        MessageBox.Show("Die für diesen Hilfeplan genehmigten FLS (" + totalFLSApproved.ToString("N") + ") werden mit diesem Eintrag überschritten. (" + totalFLSNew.ToString("N") + ").\nSpeichern nicht möglich.", "Speichern nicht möglich", MessageBoxButton.OK, MessageBoxImage.Information);
                                        lValid = false;
                                    }
                                    else if (MessageBox.Show("Die für diesen Hilfeplan genehmigten FLS (" + totalFLSApproved.ToString("N") + ") werden mit diesem Eintrag überschritten. (" + totalFLSNew.ToString("N") + ").\nMöchten Sie trotzdem speichern?", "Speichern", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                                    {
                                        lValid = false;
                                    }
                                }
                            }

                            if (lValid)
                            {
                                DateTime? start = node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.StartDate;
                                DateTime? end = node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.EndDate;

                                if (date.HasValue && start.HasValue && end.HasValue)
                                {
                                    //end = end.Value.AddDays(1).AddSeconds(-1);
                                    if (!date.Value.InBetween(start.Value, end.Value, true))
                                    {
                                        MessageBox.Show(
                                            "Das gewählte Datum '" + date.Value.ToShortDateString() +
                                            "' liegt ausserhalb des Zeitraums des gewählten Hilfeplans (" +
                                            node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.DateRangeString +
                                            ").\nDas Speichern ist nicht möglich.", "Speichern", MessageBoxButton.OK,
                                            MessageBoxImage.Information);
                                        lValid = false;
                                    }
                                }
                            }
                        }
                    }
                }

                if (lValid)
                {
                    var list = this.ViewModel.ServiceRecordsForSelectedCustomer;
                    DateTime newStart = date.Value;

                    if (newStart.Second == 0)
                    {
                        DateTime newEnd = date.Value.AddMinutes((double)roundedDuration);

                        Dictionary<DateTime, decimal> flsPerWeekDict = new Dictionary<DateTime, decimal>();
                        foreach (var item in list)
                        {
                            if (item.DateAndTime.HasValue)
                            {
                                DateTime start = item.DateAndTime.Value;
                                if (start.Second == 0)
                                {
                                    DateTime end = start.AddMinutes((double)item.RoundedDuration);

                                    DateTime mondayDT = start.GetLast(DayOfWeek.Monday).Date;
                                    decimal flsWeek = 0;
                                    if (flsPerWeekDict.ContainsKey(mondayDT))
                                    {
                                        flsWeek = flsPerWeekDict[mondayDT];
                                    }

                                    flsWeek += item.RoundedDuration / 60;

                                    flsPerWeekDict[mondayDT] = flsWeek;

                                    if (lValid && !(newEnd <= start || newStart >= end))
                                    {
                                        if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecord_AllowCreateOverlappingFLS))
                                        {
                                            MessageBox.Show("An dem gewählten Datum '" + date.Value.ToShortDateString() + " " + date.Value.ToShortTimeString() + "' existiert bereits ein Eintrag (" + start.ToShortDateString() + " " + start.ToShortTimeString() + ", Dauer " + string.Format("{0:0}", item.RoundedDuration) + " Minuten).\nSpeichern nicht möglich.", "Speichern nicht möglich", MessageBoxButton.OK, MessageBoxImage.Information);
                                            lValid = false;
                                        }
                                        else if (MessageBox.Show("An dem gewählten Datum '" + date.Value.ToShortDateString() + " " + date.Value.ToShortTimeString() + "' existiert bereits ein Eintrag (" + start.ToShortDateString() + " " + start.ToShortTimeString() + ", Dauer " + string.Format("{0:0}", item.RoundedDuration) + " Minuten).\nMöchten Sie trotzdem speichern?", "Speichern", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                                        {
                                            lValid = false;
                                        }
                                        
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return lValid;
        }

        private void _ViewModel_ServiceRecordListChanged(object sender, EventArgs e)
        {
            var list = this._ViewModel.ServiceRecordsForSelectedCustomer.OrderByDescending(srVM => srVM.DateAndTime).ToList();
            
            srListBox.ItemsSource = list;

            if (assessmentSheet != null)
                assessmentSheet.ServiceRecords = list;
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            ServiceRecordVM vm = ((Button)sender).Tag as ServiceRecordVM;
            if (vm != null)
                srListBox.SelectedItem = vm;

            Delete();
        }

        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            ServiceRecordVM vm = ((Button)sender).Tag as ServiceRecordVM;

            if (vm != null)
                this.srListBox.SelectedItem = vm;

            this.Edit(GetSelectedServiceRecordFromListBox());
        }

        private void button_ADadd_Click(object sender, RoutedEventArgs e)
        {
            if (AdditionalServiceBookings.NewVM == null ||
                AdditionalServiceBookings.NewVM.CustomerList == null) 
                return;
            
            ReloadAdditionalServiceRelatedObjects();

            if (!ValidateAdditionalServiceBookings())
                return;

            var lToDos = new List<Action<IOperationsService>>();

            AdditionalServiceBookings.AddNewVMToList();

            if (AdditionalServiceBookings.AddedCount > 0)
            {
                lToDos.Add(
                    s =>
                        {
                            var newItems = AdditionalServiceBookings.CommitAdded();
                            try
                            {
                                var oids = s.InsertNewAdditionalServiceBookings(newItems);

                                var idx = 0;
                                foreach (var vm in AdditionalServiceBookings.VMList.Where(vm => vm.IsNew))
                                {
                                    vm.IsNew = false;
                                    vm.DataContract.AdditionalServiceBookingVersion = 1;
                                    vm.DataContract.AdditionalServiceBookingOid = oids[idx++];
                                }
                            }
                            catch (Exception)
                            {
                                List<AdditionalServiceBookingVM> newVMs = AdditionalServiceBookings.VMList.Where(vm => vm.IsNew).ToList();

                                foreach (var AdditionalServiceBookingVm in newVMs)
                                    AdditionalServiceBookings.VMList.Remove(AdditionalServiceBookingVm);

                                throw;
                            }
                        });
            }

            ServiceFacade.DoMultipleOperationsServicesAsync(lToDos, () =>
                {
                    AdditionalServiceBookings.VMList.Clear();

                    foreach (var item in ServiceFacade.DoOperationsServiceSync(t => t.GetAllAdditionalServiceBookings()))
                        AdditionalServiceBookings.VMList.Add(new AdditionalServiceBookingVM(item));

                    AdditionalServiceBookings.NewVM.EmployeeList = multiEmployeeControlAddServ.SelectedEmployees;
                    this.Dispatch(delegate { AdditionalServiceBookings.NewVM.CustomerList = multiAddServGroupOfPeopleSelectionControl.CurrentGroup.CustomerList.ToDictionary(customer => customer, customer => true);
                                               updateAngebotsCombobox();
                    });
                });
        }

        private void bereichsComboboxChange(object sender, RoutedEventArgs e)
        {
            bereichscombobox.DataContext = this;

            if (bereichscombobox.SelectedItem == null)
                bereichscombobox.SelectedItem = AdditionalServices.ElementAt(0);

            updateAngebotsCombobox();
        }

        private void updateAngebotsCombobox()
        {
            List<AdditionalServiceRegionDC> ASRDCs = AdditionalServiceRegions.Where( id => id.AdditonalServiceOid == ((AdditionalServiceDC) bereichscombobox.SelectedItem).AdditionalServiceOid).ToList();

            var list = angebotscombobox.ItemsSource;
            angebotscombobox.ItemsSource = null;
            //ASRDCs.AddRange((list as List<AdditionalServiceRegionDC>).Where(p => p.Name.Equals("Angebot hinzufügen")));
            angebotscombobox.ItemsSource = ASRDCs;

            if (ASRDCs.Any())
                angebotscombobox.SelectedItem = AdditionalServiceRegions.Where(id => id.AdditonalServiceOid == ((AdditionalServiceDC) bereichscombobox.SelectedItem).AdditionalServiceOid).ElementAt(0);

            if (angebotscombobox.SelectedItem != null)
                AdditionalServiceBookings.NewVM.AdditionalServiceRegion = (AdditionalServiceRegionDC)angebotscombobox.SelectedItem;
        }

        private void angebotsComboboxChange(object sender, RoutedEventArgs e)
        {
            if (angebotscombobox.SelectedItem == null)
                return;

            AdditionalServiceBookings.NewVM.AdditionalServiceRegion = (AdditionalServiceRegionDC)angebotscombobox.SelectedItem;
            
            UpdateTeilnahmeGrid();
        }

        private void btnShowHistory_Click(object sender, RoutedEventArgs e)
        {
            var vm = ((Button)sender).Tag as ServiceRecordVM;
            if (vm != null)
                srListBox.SelectedItem = vm;

            ShowHistory(GetSelectedServiceRecordFromListBox());
        }

        private void button_add_Click(object sender, RoutedEventArgs e)
        {
            var lValid = ValidationTrigger.Validate(root);
            var records = new List<ServiceRecordDC>();

            foreach (ServiceRecordVM iVM in ViewModel.CreateFromPrototype())
            {
                if (iVM.Customer == null)
                    break;

                iVM.Employee = _SelectedEmployee;
                records.Add(iVM.CommitToDataContract());
            }

            if (lValid)
                SaveSingleBooking();
            else
                foreach (var iVM in ViewModel.CreateFromPrototype())
                    MessageBox.Show("Der gewählte Zeitpunkt '" + iVM.DateAndTime.Value.ToShortDateString() + " " + iVM.DateAndTime.Value.ToShortTimeString() + "' überschneidet sich mit einem bereits existierenden Eintrag desselben Hilfeplans.\nSpeichern nicht möglich.", "Speichern nicht möglich", MessageBoxButton.OK, MessageBoxImage.Information);

        }

        private void linkExcelExport_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            var list = srListBox.ItemsSource as List<ServiceRecordVM>;
            var lHeaderCaptions = new List<string>();
            var lContent = new List<List<string>>();

            lHeaderCaptions.Add("Datum");
            lHeaderCaptions.Add("FLM");
            lHeaderCaptions.Add("FLM gerundet");
            lHeaderCaptions.Add("Mitarbeiter");
            lHeaderCaptions.Add("Klient");
            lHeaderCaptions.Add("Hilfeplan");
            lHeaderCaptions.Add("Kostenträger");
            lHeaderCaptions.Add("Kategorie");
            lHeaderCaptions.Add("Leistung");
            lHeaderCaptions.Add("Dokumentation");

            if (list != null)
            {
                foreach (var vm in list)
                {
                    var content = new List<string>();

                    content.Add(String.Format("{0:d}", (vm.StartTime != null && vm.StartTime.Value.Second == 0 ? vm.DateAndTime : vm.Date)));

                    content.Add(vm.AssistanceDuration.ToString());
                    content.Add(vm.RoundedDuration.ToString());

                    content.Add(vm.Employee != null ? vm.Employee.ToString() : string.Empty);

                    content.Add(vm.Customer != null ? vm.Customer.ToString() : string.Empty);

                    content.Add(vm.SupportConcept != null ? vm.SupportConcept.ToString() : string.Empty);

                    content.Add(vm.CostBearer != null ? vm.CostBearer.ToString() : string.Empty);

                    content.Add(vm.Category != null ? vm.Category.ToString() : string.Empty);

                    content.Add(vm.ServiceDescription != null ? vm.ServiceDescription.ToString() : string.Empty);

                    content.Add(vm.Notice);

                    lContent.Add(content);
                }
            }

            ServiceFacade.DoDownloadServiceSync(s => s.PrepareExcelFile(this.DownloadLinkEngine.ExcelFileId, lHeaderCaptions, lContent));

            var navitageUri = ((Hyperlink)sender).NavigateUri.ToString();
            BeWoUtils.NavigateToReportUri(navitageUri);

            //System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo((sender as System.Windows.Documents.Hyperlink).NavigateUri.ToString()));

            // Workaround Hyperlink mit neuem ersetzen, Navigate Uri lässt auf dem alten nicht ändern...
            this.textblock_link.Inlines.Clear();
            var lNewLink = new Hyperlink(new Run("Excel Export")) { NavigateUri = this.DownloadLinkEngine.GenerateNewExcelLink(), Foreground = Brushes.Black, TargetName = "newWindow" };
            lNewLink.RequestNavigate += this.linkExcelExport_RequestNavigate;
            this.textblock_link.Inlines.Add(lNewLink);
        }

        private void popupedit_employee_PopUpClick(object sender, RoutedEventArgs e)
        {
            popup_employee.IsOpen = true;
        }

        private void serviceRecordListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (!IsPartOf(e.OriginalSource, typeof(ScrollBar)))
                Edit(GetSelectedServiceRecordFromListBox());
        }

        private void UpdateAssessmentSheet(FlatSupportConceptTreeNodeDC selectedNode)
        {
            if (assessmentSheet == null) 
                return;

            //if (selectedNode != null && selectedNode.SupportConceptTreeNodeDC != null)
            //{
            //    CompactCustomerDC customer = selectedNode.SupportConceptTreeNodeDC.Customer;
            //    if (customer != null)
            //    {
            //        if (!customerContainsAssessmentCategories.ContainsKey(customer))
            //        {
            //            ServiceFacade.DoCustomerServiceAsync(
            //                s1 => s1.LoadCustomerAssessmentSheetCategoryList(customer.Oid.Value),

            //                cb => this.Dispatch(
            //                    delegate
            //                        {
            //                            customerContainsAssessmentCategories.Add(customer, cb);
            //                            UpdateAssessmentSheet(selectedNode.SupportConceptTreeNodeDC.Customer, cb);

            //                        }), false);
            //        }
            //        else
            //        {
            //            var cats = customerContainsAssessmentCategories[customer];
            //            UpdateAssessmentSheet(selectedNode.SupportConceptTreeNodeDC.Customer, cats);
            //        }
            //    }
            //}
            //else
            //{
                HideAssessmentSheet();
            //}
        }

        private DockLayoutManager dockLayoutManager;
        private Grid panel1;
        private Grid panel2;
        private Grid panel3;

        private void HideAssessmentSheet()
        {
            assessmentSheet.SetCustomer(null, null);
            assessmentSheet.Visibility = Visibility.Collapsed;

            if (dockLayoutManager != null)
                dockLayoutManager.Visibility = Visibility.Collapsed;


            if (FLSGrid.Children.Count != 0) 
                return;

            if (panel1 != null)
            {
                panel1.Children.Clear();
                panel2.Children.Clear();
                panel3.Children.Clear();
            }

            groupBoxNeueLeistung.Content = gridNeueLeistung;
            FLSGrid.Children.Add(groupBoxNeueLeistung);
            FLSGrid.Children.Add(serviceRecordListContent);
            FLSGrid.Children.Add(txtServiceListCount);
            FLSGrid.Children.Add(stackPanelInfoText);
            FLSGrid.Children.Add(punktebogenRootGrid);
        }

        public override void ModalPopUpCloseInvoked()
        {
            this.MainControl.CloseCurrentPopUp();
        }

        public override void ModalPopUpSaveInvoked()
        {
            if (_GroupOfPeopleModalPopUp != null)
            {
                this._GroupOfPeopleModalPopUp.SaveData();       
            }
            
        }

        void multiAddServGroupOfPeopleSelectionControl_EditGroupButtonClicked(object sender, EventArgs e)
        {
            OpenAddServGroupEditView();
        }

        private void OpenAddServGroupEditView()
        {
            VMFactory.CreateAdditinoalServiceGroupOfPeopleListVMAsync(
                    cb => this.Dispatch(delegate
                        {
                            _AdditionalServiceGroupOfPeoplePopUp = new AdditionalServiceGroupOfPeopleView(cb)
                                {
                                    MinWidth = 700,
                                    MaxWidth = 700,
                                    Height = 600
                                };
                            _AdditionalServiceGroupOfPeoplePopUp.GroupOfPeopleSavedOrUpdated +=
                                AdditionalServiceGroupOfPeoplePopUp_AdditionalServiceGroupOfPeopleSavedOrUpdated;
                            BeWoApp.MainControl.ShowControlAsModalPopUp(_AdditionalServiceGroupOfPeoplePopUp);
                            _AdditionalServiceGroupOfPeoplePopUp.Focus();
                        })
                );
        }

        private void LinkPdfExport_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            BeWoUtils.NavigateToReportUri(((Hyperlink)sender).NavigateUri.ToString());
        }

        private void AdditionalServiceGroupOfPeoplePopUp_AdditionalServiceGroupOfPeopleSavedOrUpdated(object sender, EventArgs<AdditionalServiceGroupOfPeopleListVM> e)
        {
            BeWoApp.MainControl.CloseCurrentPopUp();
        }

        private void MultiAddServGroupOfPeopleSelectionControl_OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var groupSearchControl = sender as MultiAddServGroupOfPeopleSelectionControl;
            AdditionalServiceBookings.NewVM.CustomerList = groupSearchControl.CurrentGroup.CustomerList.ToDictionary(customer => customer, customer => true);

            ServiceFacade.DoCustomerServiceSync(o => supportConceptSelectionControl.SupportConceptList = o.GetAllActiveSupportConceptsCompact().Where(x => AdditionalServiceBookings.NewVM.CustomerList.ContainsKey(x.Customer)).ToList());
        }

        private void FLSAnlegenBtn_OnClick(object sender, RoutedEventArgs e)
        {
            if (teilnahmeGrid.Visibility == Visibility.Visible)
            {
                teilnahmeGrid.Visibility = Visibility.Collapsed;
                MonatsLabel.Visibility = Visibility.Collapsed;
                MonatsCombobox.Visibility = Visibility.Collapsed;
                JahresLabel.Visibility = Visibility.Collapsed;
                JahresCombobox.Visibility = Visibility.Collapsed;
                saveBtn.Visibility = Visibility.Collapsed;

                FLSInfoGrid.Visibility = Visibility.Visible;
            }
            else
            {
                teilnahmeGrid.Visibility = Visibility.Visible;
                MonatsLabel.Visibility = Visibility.Visible;
                MonatsCombobox.Visibility = Visibility.Visible;
                JahresLabel.Visibility = Visibility.Visible;
                JahresCombobox.Visibility = Visibility.Visible;
                saveBtn.Visibility = Visibility.Visible;

                FLSInfoGrid.Visibility = Visibility.Collapsed;

                if (AdditionalServiceBookings.NewVM.EmployeeList.Count > 0)
                {
                    _SelectedEmployee = AdditionalServiceBookings.NewVM.EmployeeList.First();
                    popupedit_employee.Text = _SelectedEmployee.ToString();
                }
            }

            FLSGrid.Visibility = FLSGrid.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
        }

        private void supportConceptSelectionControl_ItemSelected(object sender, EventArgs<FlatSupportConceptTreeNodeDC> e)
        {
            ViewModel.ChangeTreeItemSelection(e.Data);
            ViewModel.RefreshServiceRecordsForSelectedTreeNode();
            UpdateServiceRecordListReportUrl(e.Data);
        }
    }

    public class Teilnehmer
    {
        public CompactCustomerDC Customer { get; set; }

        #region Anwesenheiten
        private bool _t0; public bool t0 { get { return _t0; } set { _t0 = value; TeilnahmenForUpdating[0] = value; } }
        private bool _t1; public bool t1 { get { return _t1; } set { _t1 = value; TeilnahmenForUpdating[1] = value; } }
        private bool _t2; public bool t2 { get { return _t2; } set { _t2 = value; TeilnahmenForUpdating[2] = value; } }
        private bool _t3; public bool t3 { get { return _t3; } set { _t3 = value; TeilnahmenForUpdating[3] = value; } }
        private bool _t4; public bool t4 { get { return _t4; } set { _t4 = value; TeilnahmenForUpdating[4] = value; } }
        private bool _t5; public bool t5 { get { return _t5; } set { _t5 = value; TeilnahmenForUpdating[5] = value; } }
        private bool _t6; public bool t6 { get { return _t6; } set { _t6 = value; TeilnahmenForUpdating[6] = value; } }
        private bool _t7; public bool t7 { get { return _t7; } set { _t7 = value; TeilnahmenForUpdating[7] = value; } }
        private bool _t8; public bool t8 { get { return _t8; } set { _t8 = value; TeilnahmenForUpdating[8] = value; } }
        private bool _t9; public bool t9 { get { return _t9; } set { _t9 = value; TeilnahmenForUpdating[9] = value; } }

        private bool _t10; public bool t10 { get { return _t10; } set { _t10 = value; TeilnahmenForUpdating[10] = value; } }
        private bool _t11; public bool t11 { get { return _t11; } set { _t11 = value; TeilnahmenForUpdating[11] = value; } }
        private bool _t12; public bool t12 { get { return _t12; } set { _t12 = value; TeilnahmenForUpdating[12] = value; } }
        private bool _t13; public bool t13 { get { return _t13; } set { _t13 = value; TeilnahmenForUpdating[13] = value; } }
        private bool _t14; public bool t14 { get { return _t14; } set { _t14 = value; TeilnahmenForUpdating[14] = value; } }
        private bool _t15; public bool t15 { get { return _t15; } set { _t15 = value; TeilnahmenForUpdating[15] = value; } }
        private bool _t16; public bool t16 { get { return _t16; } set { _t16 = value; TeilnahmenForUpdating[16] = value; } }
        private bool _t17; public bool t17 { get { return _t17; } set { _t17 = value; TeilnahmenForUpdating[17] = value; } }
        private bool _t18; public bool t18 { get { return _t18; } set { _t18 = value; TeilnahmenForUpdating[18] = value; } }
        private bool _t19; public bool t19 { get { return _t19; } set { _t19 = value; TeilnahmenForUpdating[19] = value; } }

        private bool _t20; public bool t20 { get { return _t20; } set { _t20 = value; TeilnahmenForUpdating[20] = value; } }
        private bool _t21; public bool t21 { get { return _t21; } set { _t21 = value; TeilnahmenForUpdating[21] = value; } }
        private bool _t22; public bool t22 { get { return _t22; } set { _t22 = value; TeilnahmenForUpdating[22] = value; } }
        private bool _t23; public bool t23 { get { return _t23; } set { _t23 = value; TeilnahmenForUpdating[23] = value; } }
        private bool _t24; public bool t24 { get { return _t24; } set { _t24 = value; TeilnahmenForUpdating[24] = value; } }
        private bool _t25; public bool t25 { get { return _t25; } set { _t25 = value; TeilnahmenForUpdating[25] = value; } }
        private bool _t26; public bool t26 { get { return _t26; } set { _t26 = value; TeilnahmenForUpdating[26] = value; } }
        private bool _t27; public bool t27 { get { return _t27; } set { _t27 = value; TeilnahmenForUpdating[27] = value; } }
        private bool _t28; public bool t28 { get { return _t28; } set { _t28 = value; TeilnahmenForUpdating[28] = value; } }
        private bool _t29; public bool t29 { get { return _t29; } set { _t29 = value; TeilnahmenForUpdating[29] = value; } }

        private bool _t30; public bool t30 { get { return _t30; } set { _t30 = value; TeilnahmenForUpdating[30] = value; } }
        #endregion

        public Dictionary<long, BookingRelationDictionaryValue> BookingRelation { get; set; }
        public bool[] TeilnahmenForUpdating { get; set; }

        public bool ContainsOneRelationOnly { get; set; }

        public Teilnehmer(CompactCustomerDC customer, IList<bool> teilnahmen, Dictionary<long, BookingRelationDictionaryValue> bookingRelation, bool containsOneRelationOnly = false)
        {
            Customer = customer;

            ContainsOneRelationOnly = containsOneRelationOnly;

            if (BookingRelation == null)
                BookingRelation = new Dictionary<long, BookingRelationDictionaryValue>();

            BookingRelation = BookingRelation.Union(bookingRelation).ToDictionary(k => k.Key, v => v.Value);
            TeilnahmenForUpdating = teilnahmen.ToArray();

            t0 = teilnahmen[0];
            t1 = teilnahmen[1];
            t2 = teilnahmen[2];
            t3 = teilnahmen[3];
            t4 = teilnahmen[4];
            t5 = teilnahmen[5];
            t6 = teilnahmen[6];
            t7 = teilnahmen[7];
            t8 = teilnahmen[8];
            t9 = teilnahmen[9];
            t10 = teilnahmen[10];
            t11 = teilnahmen[11];
            t12 = teilnahmen[12];
            t13 = teilnahmen[13];
            t14 = teilnahmen[14];
            t15 = teilnahmen[15];
            t16 = teilnahmen[16];
            t17 = teilnahmen[17];
            t18 = teilnahmen[18];
            t19 = teilnahmen[19];
            t20 = teilnahmen[20];
            t21 = teilnahmen[21];
            t22 = teilnahmen[22];
            t23 = teilnahmen[23];
            t24 = teilnahmen[24];
            t25 = teilnahmen[25];
            t26 = teilnahmen[26];
            t27 = teilnahmen[27];

            if (teilnahmen.Count >= 29)
                t28 = teilnahmen[28];
            if (teilnahmen.Count >= 30)
                t29 = teilnahmen[29];
            if (teilnahmen.Count == 31)
                t30 = teilnahmen[30];
        }
    }

    public struct BookingRelationDictionaryValue
    {
        public DateTime Datum, StartDate, EndDate;

        public BookingRelationDictionaryValue(DateTime d, DateTime s, DateTime e)
        {
            Datum = d;
            StartDate = s;
            EndDate = e;
        }
    }

    public class CheckEditTag
    {
        public Teilnehmer Teilnehmer { get; set; }
        public GridColumn Column { get; set; }

        public CheckEditTag(Teilnehmer teilnehmer, GridColumn column)
        {
            Teilnehmer = teilnehmer;
            Column = column;
        }

        public int GetHeaderAsDay()
        {
            if (Column.Header.ToString().Equals(string.Empty))
                return 0;

            var tag = int.Parse(Column.Header.ToString().Split('.')[0], NumberStyles.Integer);
            return tag;
        }
    }
}