using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Navigation;

using BeWo.Converter;
using BeWo.Core;
using BeWo.Security;
using BeWo.ServiceProxy;
using BeWo.View.Navigation.Filter;

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

namespace BeWo.View.Navigation
{
    public partial class MainNaviReplacement : BeWoView
    {
        internal CustomFilter customFilter;

        private readonly string _DetailsLoadLock = string.Empty;

        private bool _DetailsLoadRunning;

        private IFilterableDC _SelectedItem;

        private bool _ShowDetailPanel;

        private AbstractSorter mSorter;

        public MainNaviReplacement()
        {
            InitializeComponent();

            ArchiveButtonVisible = false;
            SortPanel.Visibility = Visibility.Collapsed;

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

            ObjectHistoryListBox.SelectionChanged += (s, e) =>
            {
                if (e.AddedItems.Count > 0)
                {
                    ObjectListBox.SelectedIndex = -1;
                }
            };
            ObjectListBox.SelectionChanged += (s, e) =>
            {
                if (e.AddedItems.Count > 0)
                {
                    ObjectHistoryListBox.SelectedIndex = -1;
                }
            };

            TextboxSearch.PreviewKeyDown += (s, e) =>
            {
                if (e.Key == Key.Enter)
                {
                    OpenSelectedObject();
                }
                else if (e.Key == Key.Down)
                {
                    ObjectListBox.Focus();
                }
            };

            ObjectListBox.PreviewKeyDown += (s, e) =>
            {
                if (e.Key == Key.Enter)
                {
                    OpenSelectedObject();
                }
            };
        }

        public delegate bool ArchiveObjectDelegate(IFilterableDC obj);

        public delegate void CreateNewObjectDelegate();

        public delegate bool DeleteObjectDelegate(IFilterableDC obj);

        public delegate void OpenObjectDelegate(IFilterableDC obj);

        public delegate void ReloadDataDelegate();

        public event ArchiveObjectDelegate ArchiveObject;

        public event CreateNewObjectDelegate CreateNewObject;

        public event DeleteObjectDelegate DeleteObject;

        public event EventHandler<EventArgs<IEnumerable<IFilterableDC>>> ExcelExport;

        public event OpenObjectDelegate OpenObject;

        public event ReloadDataDelegate OnReloadData;

        public event PropertyChangedEventHandler PropertyChanged;

        public bool ArchiveButtonVisible
        {
            get
            {
                return this.BtnArchive.Visibility == Visibility.Visible;
            }

            set
            {
                this.BtnArchive.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public Style ContentGroupStyle
        {
            get
            {
                return this.ContentGroup.Style;
            }

            set
            {
                this.ContentGroup.Style = value;
            }
        }

        [TypeConverter(typeof(UserRightTypeArrayConverter))]
        public UserRightType[] CreateDemands
        {
            set
            {
                DemandUserRight.SetVisibleDemands(this.BtnNew, value);
            }
        }

        public CustomFilter CustomFilter
        {
            get
            {
                return this.customFilter;
            }

            set
            {
                this.customFilter = value;

                this.FirePropertyChanged("CustomFilter");

                // if (listBoxMultiBinding.Bindings.Count == 4)
                // listBoxMultiBinding.Bindings.RemoveAt(3);

                // if (customFilter != null) 
                // {
                // MultiBinding mb = BindingOperations.GetMultiBinding(objectListBox, System.Windows.Controls.ListBox.ItemsSourceProperty);
                // BindingOperations.ClearBinding(objectListBox, System.Windows.Controls.ListBox.ItemsSourceProperty);

                // MultiBinding newMb = new MultiBinding();
                // newMb.Converter = mb.Converter;

                // foreach (var b in mb.Bindings)
                // {
                // newMb.Bindings.Add(b);
                // }

                // Binding binding = new Binding();
                // binding.Source = customFilter;
                // binding.Mode = BindingMode.OneWay;

                // newMb.Bindings.Add(binding);

                // objectListBox.SetBinding(System.Windows.Controls.ListBox.ItemsSourceProperty, newMb);

                // // objectListBox.ItemsSource = mb;
                // }
            }
        }

        public bool DeleteButtonVisible
        {
            get
            {
                return this.BtnDelete.Visibility == Visibility.Visible;
            }

            set
            {
                this.BtnDelete.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        [TypeConverter(typeof(UserRightTypeArrayConverter))]
        public UserRightType[] DeleteDemands
        {
            set
            {
                DemandUserRight.SetVisibleDemands(this.BtnDelete, value);
            }
        }

        public DataTemplate DetailPanelItemTemplate
        {
            get
            {
                return this.DetailsPresenter.ContentTemplate;
            }

            set
            {
                this.DetailsPresenter.ContentTemplate = value;
            }
        }

        public DownloadLinkEngine DownloadLinkEngine { get; set; }

        public bool EditButtonsVisible
        {
            get
            {
                return this.BtnNew.Visibility == Visibility.Visible;
            }

            set
            {
                this.BtnNew.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
                this.DeleteButtonVisible = value;
                this.ArchiveButtonVisible = value;
            }
        }

        public Style HistoryListItemStyle
        {
            set
            {
                this.ObjectHistoryListBox.ItemContainerStyle = value;
            }
        }

        public object MainGroupHeader
        {
            get
            {
                return this.MainGroup.Header;
            }

            set
            {
                this.MainGroup.Header = value;
                this.ChkShowArchived.Content = " Archivierte " + value + " anzeigen";
            }
        }

        public Style MainListItemStyle
        {
            set
            {
                this.ObjectListBox.ItemContainerStyle = value;
            }
        }

        public bool ShowArchivedObjectsVisible
        {
            get
            {
                return this.ChkShowArchived.Visibility == Visibility.Visible;
            }

            set
            {
                this.ChkShowArchived.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public bool ShowDetailsPanel
        {
            get
            {
                return this._ShowDetailPanel;
            }

            set
            {
                this._ShowDetailPanel = value;
                if (value)
                {
                    this.StackPanleDetails.Visibility = Visibility.Visible;
                }
                else
                {
                    this.StackPanleDetails.Visibility = Visibility.Hidden;
                }
            }
        }

        public AbstractSorter Sorter
        {
            get
            {
                return this.mSorter;
            }

            set
            {
                this.mSorter = value;
                this.SortCombo.Items.Clear();

                if (this.mSorter != null)
                {
                    this.SortPanel.Visibility = this.mSorter.SortItems.Count > 0 ? Visibility.Visible : Visibility.Collapsed;

                    foreach (SortItem item in this.mSorter.SortItems)
                    {
                        this.SortCombo.Items.Add(item);
                    }

                    this.SortCombo.SelectedIndex = 0;
                }
            }
        }

        public void AddControlToSortPanel(UIElement element)
        {
            this.SortPanel.Children.Add(element);
        }

        public void OnDetailsLoadedCompleted(object details, object item)
        {
            this.Dispatch(delegate { this.DetailsPresenter.DataContext = details; });

            lock (this._DetailsLoadLock)
            {
                if (this._SelectedItem != item)
                {
                    if (this._SelectedItem is CompactSupportConceptDC)
                    {
                        var dc = this._SelectedItem as CompactSupportConceptDC;
                        ServiceFacade.DoOperationsServiceAsyncNoWait(s => s.GetSupportConceptInfosForSupportConceptOid(dc.SupportConceptOid), this.OnDetailsLoadedCompleted, dc);
                    }
                    else if (this._SelectedItem is CompactCustomerDC)
                    {
                        var dc = this._SelectedItem as CompactCustomerDC;
                        ServiceFacade.DoOperationsServiceAsyncNoWait(s => s.GetCustomerInfosForCustomerOid(dc.CustomerOid), this.OnDetailsLoadedCompleted, dc);
                    }
                }
                else
                {
                    this._DetailsLoadRunning = false;
                }
            }
        }

        public void ShowHistory(IEnumerable<IFilterableDC> result)
        {
            this.ObjectHistoryListBox.ItemsSource = result.ToObservableSortCollection();
        }

        public void ShowSearchResult(IEnumerable<IFilterableDC> result)
        {
            this.SortSearchResult(result);
        }

        public void SortSearchResult(IEnumerable<IFilterableDC> result)
        {
            if (this.mSorter == null)
            {
                this.ObjectListBox.DataContext = result.ToObservableSortCollection();
            }
            else
            {
                SortItem item = this.SortCombo.SelectedItem as SortItem;
                if (item != null)
                {
                    this.SortSearchResult(item, result);
                }
            }
        }

        public void SortSearchResult(SortItem item, IEnumerable<IFilterableDC> result)
        {
            if (this.mSorter != null && item != null)
            {
                IEnumerable<IFilterableDC> items = result;

                if (items != null)
                {
                    AbstractSorter.SortDirection dir = AbstractSorter.SortDirection.Ascending;
                    if (this.SortDirectionToggleButton.IsChecked.Value)
                    {
                        dir = AbstractSorter.SortDirection.Descending;
                    }

                    this.ObjectListBox.DataContext = items.ToObservableSortCollection(this.mSorter.GetComparison(item, dir));
                }
            }
        }

        protected virtual void FirePropertyChanged(string pPropertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(pPropertyName));
            }
        }

        private void ExcelCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            // e.CanExecute = listPerson.Items.Count > 0;
        }

        private void ExcelCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            // bool lRes = lClient.PrepareExcelFile((string)e.Parameter, listPerson.GetHeader(), listPerson.GetContent());
            // ProxyFactory.CloseDownloadServiceClient.Close();
        }

        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 OnLoaded(object sender, RoutedEventArgs e)
        {
            this.TextboxSearch.Focus();
        }

        private void OnOpenObject()
        {
            if (this.OpenObject != null)
            {
                object obj = this.ObjectListBox.SelectedItem != null ? this.ObjectListBox.SelectedItem : this.ObjectHistoryListBox.SelectedItem;

                if (obj is IFilterableDC)
                {
                    this.OpenObject(obj as IFilterableDC);
                }
            }
        }

        private void OpenCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            // e.CanExecute = listPerson.SelectedItem != null;
        }

        private void OpenCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            // CompactPersonDC lPerson = listPerson.SelectedItem as CompactPersonDC;

            // if (lPerson != null && PersonSelected != null)
            // PersonSelected(this, new EventArgs<CompactPersonDC>(lPerson));
        }

        private void OpenSelectedObject()
        {
            if (this.OpenObject != null)
            {
                object selectedObj = this.ObjectListBox.SelectedItem;
                if (selectedObj == null)
                {
                    IEnumerator enu = this.ObjectListBox.ItemsSource.GetEnumerator();
                    enu.MoveNext();
                    selectedObj = enu.Current;
                }

                if (selectedObj != null && selectedObj is IFilterableDC)
                {
                    this.OpenObject(selectedObj as IFilterableDC);
                }
            }
        }

        private void btnArchive_Click(object sender, RoutedEventArgs e)
        {
            if (this.ArchiveObject != null)
            {
                IFilterableDC obj = this.ObjectListBox.SelectedItem as IFilterableDC;
                if (obj != null)
                {
                    if (this.ArchiveObject(obj))
                    {
                        obj.ActivationType = ActivationTypeId.Archived;
                        var test = this.ObjectListBox.DataContext;
                        this.ObjectListBox.DataContext = null;
                        this.ObjectListBox.DataContext = test;
                    }
                }
            }
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (this.DeleteObject != null)
            {
                IFilterableDC obj = this.ObjectListBox.SelectedItem as IFilterableDC;
                if (obj != null)
                {
                    if (this.DeleteObject(obj))
                    {
                        var test = this.ObjectListBox.DataContext;
                        (test as ObservableCollection<IFilterableDC>).Remove(obj);
                        this.ObjectListBox.DataContext = null;
                        this.ObjectListBox.DataContext = test;
                        (this.ObjectHistoryListBox.ItemsSource as ObservableCollection<IFilterableDC>).Remove(obj);
                    }
                }
            }
        }

        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            this.OnOpenObject();
        }

        private void btnNew_Click(object sender, RoutedEventArgs e)
        {
            if (this.CreateNewObject != null)
            {
                this.CreateNewObject();
            }
        }

        private ObservableSortCollection<IFilterableDC> GetFilteredList(ObservableSortCollection<IFilterableDC> results)
        {
            if (this.ChkShowArchived.Visibility == Visibility.Visible && !this.ChkShowArchived.IsChecked.Value)
            {
                if (results.Count > 0)
                {
                    IFilterableDC firstDC = results[0];
                    if (firstDC.SupportsActivationType)
                    {
                        ObservableSortCollection<IFilterableDC> filteredList = new ObservableSortCollection<IFilterableDC>();
                        foreach (IFilterableDC dc in results)
                        {
                            if (dc.ActivationType == ActivationTypeId.Active)
                            {
                                filteredList.Add(dc);
                            }
                        }

                        return filteredList;
                    }
                }
            }

            return results;
        }

        private void linkExcelExport_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            if (ExcelExport != null)
                ExcelExport(this, new EventArgs<IEnumerable<IFilterableDC>>(ObjectListBox.ItemsSource as IEnumerable<IFilterableDC>));
        }

        private void objectHistoryListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            OnOpenObject();
        }

        private void objectListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (!IsPartOf(e.OriginalSource, typeof(ScrollBar)))
                OnOpenObject();
        }

        private void objectListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var lb = sender as ListBox;
            if (lb.SelectedItem != null)
            {
                lock (_DetailsLoadLock)
                {
                    _SelectedItem = lb.SelectedItem as IFilterableDC;

                    if (!_DetailsLoadRunning)
                    {
                        if (_SelectedItem is CompactSupportConceptDC)
                        {
                            var dc = _SelectedItem as CompactSupportConceptDC;
                            ServiceFacade.DoOperationsServiceAsyncNoWait(
                                s => s.GetSupportConceptInfosForSupportConceptOid(dc.SupportConceptOid),
                                OnDetailsLoadedCompleted, dc);

                            _DetailsLoadRunning = true;
                        }
                        else if (_SelectedItem is CompactCustomerDC)
                        {
                            var dc = _SelectedItem as CompactCustomerDC;

                            ServiceFacade.DoOperationsServiceAsyncNoWait(
                                s => s.GetCustomerInfosForCustomerOid(dc.CustomerOid), OnDetailsLoadedCompleted, dc);
                            _DetailsLoadRunning = true;
                        }
                    }
                }
            }
            else
            {
                DetailsPresenter.DataContext = null;
            }
        }

        private void sortCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
                SortSearchResult(e.AddedItems[0] as SortItem, ObjectListBox.ItemsSource as IEnumerable<IFilterableDC>);
        }

        private void sortDirectionToggleButton_Click(object sender, RoutedEventArgs e)
        {
            SortSearchResult(ObjectListBox.ItemsSource as IEnumerable<IFilterableDC>);
        }

        private void ReloadButton_OnClick(object sender, RoutedEventArgs e)
        {
            if (OnReloadData != null)
                OnReloadData();
        }
    }
}
