using C1.Xaml.Calendar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.Serialization;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;

namespace ControlExplorer.Controls.Calendar
{
    /// <summary>
    /// Binds calendar to custom data and use custom BoldedDaySlotTemplate to show information about events. 
    /// Double tap on day to review detailed information about events.
    /// </summary>
    public partial class CustomData : UserControl
    {
        private AppointmentCollection _appointments = new AppointmentCollection();
        private int _appNumber = 1;

        public CustomData()
        {
            InitializeComponent();

            // bind C1Calendar to the AppointmentCollection
            cal1.StartTimePath = "Start";
            cal1.EndTimePath = "End";
            cal1.DataSource = _appointments;

            // create some default appointments
            CreateTestEvent(DateTime.Today.AddDays(1));
            CreateTestEvent(DateTime.Today.AddDays(2));
            CreateTestEvent(DateTime.Today.AddDays(12));
            CreateTestEvent(DateTime.Today.AddDays(10));
            CreateTestEvent(DateTime.Today.AddDays(12));
            CreateTestEvent(DateTime.Today.AddDays(15));
            CreateTestEvent(DateTime.Today.AddDays(-21));
            CreateTestEvent(DateTime.Today.AddDays(-11));
            CreateTestEvent(DateTime.Today.AddDays(-3));
            CreateTestEvent(DateTime.Today.AddDays(2));
            CreateTestEvent(DateTime.Today.AddDays(-21));
            CreateTestEvent(DateTime.Today.AddDays(12));
        }

        private void CreateTestEvent(DateTime start)
        {
            Appointment app = new Appointment();
            app.Start = start;
            app.Duration = TimeSpan.FromDays(1);
            app.Subject = "test " + _appNumber.ToString();
            _appNumber++;
            _appointments.Add(app);
        }

        private void cal1_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
        {
            // show the list of appointments for the bolded day
            FrameworkElement fel = e.OriginalSource as FrameworkElement;
            if (fel != null)
            {
                DaySlot slot = fel.DataContext as DaySlot;
                if (slot != null)
                {
                    DateTime date = slot.Date;
                    string message = date.ToString("d");
                    if (slot.DataSource == null || slot.DataSource.Count == 0)
                    {
                        message += "\r\nNo events for this day.";
                    }
                    else
                    {
                        foreach (Appointment app in slot.DataSource)
                        {
                            message += "\r\n" + app.Subject;
                        }
                    }
                    var dialog = new MessageDialog(message);
                    dialog.ShowAsync();
                }
            }
        }
    }

    [DataContract(Name = "Appointment", Namespace = "http://www.componentone.com")]
    public class Appointment : INotifyPropertyChanged
    {
        public Appointment()
        {
            Id = Guid.NewGuid();
        }
        [DataMember]
        public Guid Id { get; private set; }

        private string _subject = "";
        [DataMember]
        public string Subject
        {
            get { return _subject; }
            set
            {
                if (_subject != value)
                {
                    _subject = value;
                    OnPropertyChanged("Subject");
                }
            }
        }

        private string _location = "";
        [DataMember]
        public string Location
        {
            get { return _location; }
            set
            {
                if (_location != value)
                {
                    _location = value;
                    OnPropertyChanged("Location");
                }
            }
        }

        private DateTime _start;
        [DataMember]
        public DateTime Start
        {
            get { return _start; }
            set
            {
                if (_start != value)
                {
                    _start = value;
                    OnPropertyChanged("Start");
                }
            }
        }

        [DataMember]
        public DateTime End
        {
            get { return _start.Add(_duration); }
            set
            {
                if (value >= _start)
                {
                    Duration = (value.Subtract(_start));
                    OnPropertyChanged("End");
                }
            }
        }

        private TimeSpan _duration;
        public TimeSpan Duration
        {
            get { return _duration; }
            set
            {
                if (_duration != value)
                {
                    _duration = value;
                    OnPropertyChanged("Duration");
                }
            }
        }

        private string _description = "";
        [DataMember]
        public string Description
        {
            get { return _description; }
            set
            {
                if (_description != value)
                {
                    _description = value;
                    OnPropertyChanged("Description");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    // inherit from ObservableCollection to allow auto refresh in calendar
    public class AppointmentCollection : ObservableCollection<Appointment>
    {
        public AppointmentCollection()
        {
        }
    }

    public class EventsToStringConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            IList<object> list = value as IList<object>;
            if (list != null && list.Count > 0)
            {
                if (list.Count == 1)
                {
                    return ((Appointment)list[0]).Subject;
                }
                else
                {
                    return list.Count + " events";
                }
            }
            return string.Empty;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
}
