using System;
using System.Runtime.InteropServices;
using TaskSchedulerInterop;

namespace TaskScheduler
{
	[ComVisible(true)]
	public abstract class Trigger : ICloneable
	{
		[Flags]
		private enum TaskTriggerFlags
		{
			HasEndDate = 1,
			KillAtDurationEnd = 2,
			Disabled = 4
		}

		private ITaskTrigger iTaskTrigger;

		internal TaskTrigger taskTrigger;

		internal bool Bound
		{
			get
			{
				return this.iTaskTrigger != null;
			}
		}

		public DateTime BeginDate
		{
			get
			{
				return new DateTime((int)this.taskTrigger.BeginYear, (int)this.taskTrigger.BeginMonth, (int)this.taskTrigger.BeginDay);
			}
			set
			{
				this.taskTrigger.BeginYear = (ushort)value.Year;
				this.taskTrigger.BeginMonth = (ushort)value.Month;
				this.taskTrigger.BeginDay = (ushort)value.Day;
				this.SyncTrigger();
			}
		}

		public bool HasEndDate
		{
			get
			{
				return (this.taskTrigger.Flags & 1u) == 1u;
			}
			set
			{
				if (value)
				{
					throw new ArgumentException("HasEndDate can only be set false");
				}
				this.taskTrigger.Flags = (this.taskTrigger.Flags & 4294967294u);
				this.SyncTrigger();
			}
		}

		public DateTime EndDate
		{
			get
			{
				bool flag = this.taskTrigger.EndYear == 0;
				DateTime result;
				if (flag)
				{
					result = DateTime.MinValue;
				}
				else
				{
					result = new DateTime((int)this.taskTrigger.EndYear, (int)this.taskTrigger.EndMonth, (int)this.taskTrigger.EndDay);
				}
				return result;
			}
			set
			{
				this.taskTrigger.Flags = (this.taskTrigger.Flags | 1u);
				this.taskTrigger.EndYear = (ushort)value.Year;
				this.taskTrigger.EndMonth = (ushort)value.Month;
				this.taskTrigger.EndDay = (ushort)value.Day;
				this.SyncTrigger();
			}
		}

		public int DurationMinutes
		{
			get
			{
				return (int)this.taskTrigger.MinutesDuration;
			}
			set
			{
				bool flag = (long)value < (long)((ulong)this.taskTrigger.MinutesInterval);
				if (flag)
				{
					throw new ArgumentOutOfRangeException("DurationMinutes", value, "DurationMinutes must be greater than or equal the IntervalMinutes value");
				}
				this.taskTrigger.MinutesDuration = (uint)value;
				this.SyncTrigger();
			}
		}

		public int IntervalMinutes
		{
			get
			{
				return (int)this.taskTrigger.MinutesInterval;
			}
			set
			{
				bool flag = (long)value > (long)((ulong)this.taskTrigger.MinutesDuration);
				if (flag)
				{
					throw new ArgumentOutOfRangeException("IntervalMinutes", value, "IntervalMinutes must be less than or equal the DurationMinutes value");
				}
				this.taskTrigger.MinutesInterval = (uint)value;
				this.SyncTrigger();
			}
		}

		public bool KillAtDurationEnd
		{
			get
			{
				return (this.taskTrigger.Flags & 2u) == 2u;
			}
			set
			{
				if (value)
				{
					this.taskTrigger.Flags = (this.taskTrigger.Flags | 2u);
				}
				else
				{
					this.taskTrigger.Flags = (this.taskTrigger.Flags & 4294967293u);
				}
				this.SyncTrigger();
			}
		}

		public bool Disabled
		{
			get
			{
				return (this.taskTrigger.Flags & 4u) == 4u;
			}
			set
			{
				if (value)
				{
					this.taskTrigger.Flags = (this.taskTrigger.Flags | 4u);
				}
				else
				{
					this.taskTrigger.Flags = (this.taskTrigger.Flags & 4294967291u);
				}
				this.SyncTrigger();
			}
		}

		internal Trigger()
		{
			this.iTaskTrigger = null;
			this.taskTrigger = default(TaskTrigger);
			this.taskTrigger.TriggerSize = (ushort)Marshal.SizeOf(this.taskTrigger);
			this.taskTrigger.BeginYear = (ushort)DateTime.Today.Year;
			this.taskTrigger.BeginMonth = (ushort)DateTime.Today.Month;
			this.taskTrigger.BeginDay = (ushort)DateTime.Today.Day;
		}

		internal Trigger(ITaskTrigger iTrigger)
		{
			bool flag = iTrigger == null;
			if (flag)
			{
				throw new ArgumentNullException("iTrigger", "ITaskTrigger instance cannot be null");
			}
			this.taskTrigger = default(TaskTrigger);
			this.taskTrigger.TriggerSize = (ushort)Marshal.SizeOf(this.taskTrigger);
			iTrigger.GetTrigger(ref this.taskTrigger);
			this.iTaskTrigger = iTrigger;
		}

		public object Clone()
		{
			Trigger trigger = (Trigger)base.MemberwiseClone();
			trigger.iTaskTrigger = null;
			return trigger;
		}

		internal static Trigger CreateTrigger(ITaskTrigger iTaskTrigger)
		{
			bool flag = iTaskTrigger == null;
			if (flag)
			{
				throw new ArgumentNullException("iTaskTrigger", "Instance of ITaskTrigger cannot be null");
			}
			TaskTrigger taskTrigger = default(TaskTrigger);
			taskTrigger.TriggerSize = (ushort)Marshal.SizeOf(taskTrigger);
			iTaskTrigger.GetTrigger(ref taskTrigger);
			Trigger result;
			switch (taskTrigger.Type)
			{
			case TaskTriggerType.TIME_TRIGGER_ONCE:
				result = new RunOnceTrigger(iTaskTrigger);
				break;
			case TaskTriggerType.TIME_TRIGGER_DAILY:
				result = new DailyTrigger(iTaskTrigger);
				break;
			case TaskTriggerType.TIME_TRIGGER_WEEKLY:
				result = new WeeklyTrigger(iTaskTrigger);
				break;
			case TaskTriggerType.TIME_TRIGGER_MONTHLYDATE:
				result = new MonthlyTrigger(iTaskTrigger);
				break;
			case TaskTriggerType.TIME_TRIGGER_MONTHLYDOW:
				result = new MonthlyDOWTrigger(iTaskTrigger);
				break;
			case TaskTriggerType.EVENT_TRIGGER_ON_IDLE:
				result = new OnIdleTrigger(iTaskTrigger);
				break;
			case TaskTriggerType.EVENT_TRIGGER_AT_SYSTEMSTART:
				result = new OnSystemStartTrigger(iTaskTrigger);
				break;
			case TaskTriggerType.EVENT_TRIGGER_AT_LOGON:
				result = new OnLogonTrigger(iTaskTrigger);
				break;
			default:
				throw new ArgumentException("Unable to recognize type of trigger referenced in iTaskTrigger", "iTaskTrigger");
			}
			return result;
		}

		protected void SyncTrigger()
		{
			bool flag = this.iTaskTrigger != null;
			if (flag)
			{
				this.iTaskTrigger.SetTrigger(ref this.taskTrigger);
			}
		}

		internal void Bind(ITaskTrigger iTaskTrigger)
		{
			bool flag = this.iTaskTrigger != null;
			if (flag)
			{
				throw new ArgumentException("Attempt to bind an already bound trigger");
			}
			this.iTaskTrigger = iTaskTrigger;
			iTaskTrigger.SetTrigger(ref this.taskTrigger);
		}

		internal void Bind(Trigger trigger)
		{
			this.Bind(trigger.iTaskTrigger);
		}

		internal void Unbind()
		{
			bool flag = this.iTaskTrigger != null;
			if (flag)
			{
				Marshal.ReleaseComObject(this.iTaskTrigger);
				this.iTaskTrigger = null;
			}
		}

		public override string ToString()
		{
			bool flag = this.iTaskTrigger != null;
			string result;
			if (flag)
			{
				IntPtr lpwstr;
				this.iTaskTrigger.GetTriggerString(out lpwstr);
				result = CoTaskMem.LPWStrToString(lpwstr);
			}
			else
			{
				result = "Unbound " + base.GetType().ToString();
			}
			return result;
		}

		public override bool Equals(object obj)
		{
			return this.taskTrigger.Equals(((Trigger)obj).taskTrigger);
		}

		public override int GetHashCode()
		{
			return this.taskTrigger.GetHashCode();
		}
	}
}
