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

namespace TaskScheduler
{
	[ComVisible(true)]
	public class MonthlyTrigger : StartableTrigger
	{
		public MonthsOfTheYear Months
		{
			get
			{
				return (MonthsOfTheYear)this.taskTrigger.Data.monthlyDate.Months;
			}
			set
			{
				this.taskTrigger.Data.monthlyDOW.Months = (ushort)value;
				base.SyncTrigger();
			}
		}

		public int[] Days
		{
			get
			{
				return MonthlyTrigger.MaskToIndices((int)this.taskTrigger.Data.monthlyDate.Days);
			}
			set
			{
				this.taskTrigger.Data.monthlyDate.Days = (uint)MonthlyTrigger.IndicesToMask(value);
				base.SyncTrigger();
			}
		}

		public MonthlyTrigger(short hour, short minutes, int[] daysOfMonth, MonthsOfTheYear months)
		{
			base.SetStartTime((ushort)hour, (ushort)minutes);
			this.taskTrigger.Type = TaskTriggerType.TIME_TRIGGER_MONTHLYDATE;
			this.taskTrigger.Data.monthlyDate.Months = (ushort)months;
			this.taskTrigger.Data.monthlyDate.Days = (uint)MonthlyTrigger.IndicesToMask(daysOfMonth);
		}

		public MonthlyTrigger(short hour, short minutes, int[] daysOfMonth) : this(hour, minutes, daysOfMonth, MonthsOfTheYear.January | MonthsOfTheYear.February | MonthsOfTheYear.March | MonthsOfTheYear.April | MonthsOfTheYear.May | MonthsOfTheYear.June | MonthsOfTheYear.July | MonthsOfTheYear.August | MonthsOfTheYear.September | MonthsOfTheYear.October | MonthsOfTheYear.November | MonthsOfTheYear.December)
		{
		}

		internal MonthlyTrigger(ITaskTrigger iTrigger) : base(iTrigger)
		{
		}

		private static int[] MaskToIndices(int mask)
		{
			int num = 0;
			int num2 = 0;
			while (mask >> num2 > 0)
			{
				num += (1 & mask >> num2);
				num2++;
			}
			int[] array = new int[num];
			num = 0;
			int num3 = 0;
			while (mask >> num3 > 0)
			{
				bool flag = (1 & mask >> num3) == 1;
				if (flag)
				{
					array[num++] = num3 + 1;
				}
				num3++;
			}
			return array;
		}

		private static int IndicesToMask(int[] indices)
		{
			int num = 0;
			for (int i = 0; i < indices.Length; i++)
			{
				int num2 = indices[i];
				bool flag = num2 < 1 || num2 > 31;
				if (flag)
				{
					throw new ArgumentException("Days must be in the range 1..31");
				}
				num |= 1 << num2 - 1;
			}
			return num;
		}
	}
}
