379 lines
14 KiB
C#

#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using DevComponents.Schedule.Model.Primitives;
namespace DevComponents.Schedule.Model
{
/// <summary>
/// Represents appointment recurrence definition.
/// </summary>
public class AppointmentRecurrence : INotifyPropertyChanged, INotifySubPropertyChanged
{
#region Internal Implementation
public AppointmentRecurrence()
{
_SkippedRecurrences = new CustomCollection<DateTime>();
_SkippedRecurrences.CollectionChanged += new NotifyCollectionChangedEventHandler(SkippedRecurrencesCollectionChanged);
}
private eRecurrenceRangeLimitType _RangeType = eRecurrenceRangeLimitType.NoEndDate;
/// <summary>
/// Gets or sets the range type for the recurrence. Default value is no end date for recurrence.
/// </summary>
[DefaultValue(eRecurrenceRangeLimitType.NoEndDate)]
public eRecurrenceRangeLimitType RangeLimitType
{
get { return _RangeType; }
set
{
if (_RangeType != value)
{
eRecurrenceRangeLimitType oldValue = _RangeType;
_RangeType = value;
OnRangeTypeChanged(oldValue, _RangeType);
}
}
}
private void OnRangeTypeChanged(eRecurrenceRangeLimitType oldValue, eRecurrenceRangeLimitType newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RangeLimitType"));
}
private DateTime _RangeEndDate = DateTime.MinValue;
/// <summary>
/// Gets or sets the recurrence end date. To specify the end date for recurrence set this property and RangeLimitType property to RangeEndDate.
/// </summary>
public DateTime RangeEndDate
{
get { return _RangeEndDate; }
set
{
if (_RangeEndDate != value)
{
DateTime oldValue = _RangeEndDate;
_RangeEndDate = value;
OnRangeEndDateChanged(oldValue, _RangeEndDate);
}
}
}
private void OnRangeEndDateChanged(DateTime oldValue, DateTime newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RangeEndDate"));
}
private int _RangeNumberOfOccurrences = 0;
/// <summary>
/// Gets or sets number of occurrences after which recurrence ends. To specify limited number of recurrences
/// set this property and set RangeLimitType to RangeNumberOfOccurrences.
/// </summary>
[DefaultValue(0)]
public int RangeNumberOfOccurrences
{
get { return _RangeNumberOfOccurrences; }
set
{
if (_RangeNumberOfOccurrences != value)
{
if (value < 0) throw new ArgumentException("Negative values not allows for range limit.");
int oldValue = _RangeNumberOfOccurrences;
_RangeNumberOfOccurrences = value;
OnRangeNumberOfOccurrencesChanged(oldValue, _RangeNumberOfOccurrences);
}
}
}
private void OnRangeNumberOfOccurrencesChanged(int oldValue, int newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RangeNumberOfOccurrences"));
}
private object _Tag = null;
/// <summary>
/// Gets or sets additional data associated with the object.
/// </summary>
[DefaultValue(null)]
public object Tag
{
get { return _Tag; }
set
{
if (value != _Tag)
{
object oldValue = _Tag;
_Tag = value;
OnTagChanged(oldValue, value);
}
}
}
private void OnTagChanged(object oldValue, object newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("Tag"));
}
private eRecurrencePatternType _RecurrenceType = eRecurrencePatternType.Daily;
/// <summary>
/// Gets or sets the recurring frequency for appointment i.e. daily, weekly, monthly or yearly.
/// Default value is Daily.
/// </summary>
[DefaultValue(eRecurrencePatternType.Daily)]
public eRecurrencePatternType RecurrenceType
{
get { return _RecurrenceType; }
set
{
if (value != _RecurrenceType)
{
eRecurrencePatternType oldValue = _RecurrenceType;
_RecurrenceType = value;
OnRecurrenceTypeChanged(oldValue, value);
}
}
}
private void OnRecurrenceTypeChanged(eRecurrencePatternType oldValue, eRecurrencePatternType newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RecurrenceType"));
}
internal void GenerateSubset(AppointmentSubsetCollection subsetCollection, DateTime startDate, DateTime endDate)
{
IRecurrenceGenerator generator = GetRecurrenceGenerator();
if (_RecurrenceType == eRecurrencePatternType.Daily)
{
generator.GenerateDailyRecurrence(subsetCollection, this, startDate, endDate);
}
else if (_RecurrenceType == eRecurrencePatternType.Weekly)
{
generator.GenerateWeeklyRecurrence(subsetCollection, this, startDate, endDate);
}
else if (_RecurrenceType == eRecurrencePatternType.Monthly)
{
generator.GenerateMonthlyRecurrence(subsetCollection, this, startDate, endDate);
}
else if (_RecurrenceType == eRecurrencePatternType.Yearly)
{
generator.GenerateYearlyRecurrence(subsetCollection, this, startDate, endDate);
}
}
private IRecurrenceGenerator _Generator = null;
private IRecurrenceGenerator GetRecurrenceGenerator()
{
if (_Generator == null) _Generator = new RecurrenceGenerator();
return _Generator;
}
private Appointment _Appointment;
/// <summary>
/// Gets reference to appointment recurrence is assigned to.
/// </summary>
[Browsable(false)]
public Appointment Appointment
{
get { return _Appointment; }
internal set { _Appointment = value; }
}
private DailyRecurrenceSettings _Daily;
/// <summary>
/// Gets the settings for Daily recurrence type.
/// </summary>
[Browsable(false)]
public DailyRecurrenceSettings Daily
{
get
{
if (_Daily == null)
{
_Daily = new DailyRecurrenceSettings(this);
_Daily.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Daily;
}
}
private WeeklyRecurrenceSettings _Weekly;
/// <summary>
/// Gets the settings for Weekly recurrence type.
/// </summary>
public WeeklyRecurrenceSettings Weekly
{
get
{
if (_Weekly == null)
{
_Weekly = new WeeklyRecurrenceSettings(this);
_Weekly.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Weekly;
}
}
private MonthlyRecurrenceSettings _Monthly;
/// <summary>
/// Gets the settings for monthly recurrence type.
/// </summary>
[Browsable(false)]
public MonthlyRecurrenceSettings Monthly
{
get
{
if (_Monthly == null)
{
_Monthly = new MonthlyRecurrenceSettings(this);
_Monthly.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Monthly;
}
}
private YearlyRecurrenceSettings _Yearly = null;
/// <summary>
/// Gets the settings for yearly recurrence type.
/// </summary>
public YearlyRecurrenceSettings Yearly
{
get
{
if (_Yearly == null)
{
_Yearly = new YearlyRecurrenceSettings(this);
_Yearly.SubPropertyChanged += this.ChildPropertyChangedEventHandler;
}
return _Yearly;
}
}
private DateTime _RecurrenceStartDate = DateTime.MinValue;
/// <summary>
/// Gets or sets the recurrence start date. Default value is DateTime.MinValue which indicates that recurrence starts after
/// the appointment ends.
/// </summary>
public DateTime RecurrenceStartDate
{
get { return _RecurrenceStartDate; }
set
{
if (value != _RecurrenceStartDate)
{
DateTime oldValue = _RecurrenceStartDate;
_RecurrenceStartDate = value;
OnRecurrenceStartDateChanged(oldValue, value);
}
}
}
private void OnRecurrenceStartDateChanged(DateTime oldValue, DateTime newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("RecurrenceStartDate"));
}
private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null;
private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler
{
get
{
if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged);
return _ChildPropertyChangedEventHandler;
}
}
private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e)
{
OnSubPropertyChanged(e);
}
private CustomCollection<DateTime> _SkippedRecurrences = null;
/// <summary>
/// Gets or set the list of dates on which the recurrences are skipped.
/// </summary>
public CustomCollection<DateTime> SkippedRecurrences
{
get
{
return _SkippedRecurrences;
}
}
private void SkippedRecurrencesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(new PropertyChangedEventArgs("SkippedRecurrences"));
}
private bool _IndependentVisibility = false;
/// <summary>
/// Gets or sets whether generated recurring appointments have independent Visible property setting from root Appointment.
/// When set to true recurring appointment instances will not by default have Visible property set to the Visible property of root appointment.
/// Default value is false which means recurring instances by default have Visible property set to the root appointment Visible property.
/// </summary>
public bool IndependentVisibility
{
get { return _IndependentVisibility; }
set
{
if (value != _IndependentVisibility)
{
bool oldValue = _IndependentVisibility;
_IndependentVisibility = value;
OnIndependentVisibilityChanged(oldValue, value);
}
}
}
/// <summary>
/// Called when IndependentVisibility property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnIndependentVisibilityChanged(bool oldValue, bool newValue)
{
OnPropertyChanged(new PropertyChangedEventArgs("IndependentVisibility"));
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null) eh(this, e);
OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e));
}
#endregion
#region INotifySubPropertyChanged Members
/// <summary>
/// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key
/// difference that it occurs for the property changed of child objects as well.
/// </summary>
public event SubPropertyChangedEventHandler SubPropertyChanged;
/// <summary>
/// Raises the SubPropertyChanged event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e)
{
SubPropertyChangedEventHandler eh = SubPropertyChanged;
if (eh != null) eh(this, e);
}
#endregion
}
}
#endif