context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web.Mvc;
  using CmsData;
  using CmsData.Codes;
  using CmsData.Registration;
  using CmsData.View;
  using CmsWeb.Areas.Org.Models;
  using UtilityExtensions;
  
  namespace CmsWeb.Areas.Manage.Models
  {
  	public class VolunteerCommitmentsModel
  	{
  		public string SmallGroup1 { get; set; }
  		public string SmallGroup2 { get; set; }
  		public bool SortByWeek { get; set; }
  
  		public class NameId
  		{
  			public string Name { get; set; }
  			public int PeopleId { get; set; }
  			public int? Commitment { get; set; }
              public bool OtherCommitments { get; set; }
  			public string CommitmentText
  			{
  				get
  				{
  					return CmsData.Codes.AttendCommitmentCode.Lookup(Commitment);
  				}
  			}
  		}
  //		public IEnumerable<DateTime> times;
  		public string OrgName { get; set; }
  		public int OrgId { get; set; }
  		public bool IsLeader { get; set; }
  
          //        public class VolunteerInfo
          //        {
          //            public string Name { get; set; }
          //            public int commits { get; set; }
          //            public int PeopleId { get; set; }
          //            public int OrgId { get; set; }
          //        }
  		public SelectList SmallGroups()
  		{
  			var q = from m in DbUtil.Db.MemberTags
  					where m.OrgId == OrgId
  					where m.OrgMemMemTags.Any()
  					orderby m.Name
  					select m.Name;
  			var list = q.ToList();
  			list.Insert(0, "(not specified)");
  			return new SelectList(list);
  		}
  
          private List<VolunteerCalendar> volunteers;
          public IEnumerable<VolunteerCalendar> Volunteers()
  		{
              if (volunteers != null)
                  return volunteers;
              var q = from mm in DbUtil.Db.VolunteerCalendar(OrgId, SmallGroup1, SmallGroup2)
                      orderby mm.PeopleId
                      select mm;
              return volunteers = q.ToList();
  		}
  		public List<TimeSlots.TimeSlot> TimeSlots { get; set; }
  		public DragDropInfo ddinfo { get; set; }
  		public VolunteerCommitmentsModel(int id)
  		{
  			OrgName = (from o in DbUtil.Db.Organizations where o.OrganizationId == id select o.OrganizationName).Single();
  			OrgId = id;
  //			times = from ts in Regsettings.TimeSlots.list
  //					orderby ts.DayOfWeek, ts.Time
  //					select ts.Datetime(Sunday);
  		    TimeSlots = Regsettings.TimeSlots.list;
  
  			IsLeader = OrganizationMember.VolunteerLeaderInOrg(DbUtil.Db, id);
  		}
  		public class Slot
  		{
  			public DateTime Time { get; set; }
  			public long ticks { get { return Time.Ticks; } }
  			public DateTime Sunday { get; set; }
  			public int Week { get; set; }
  			public bool Disabled { get; set; }
  			public DateTime DayHour { get; set; }
  			public List<NameId> Persons { get; set; }
  			public int Count
  			{
  			    get { return Persons.Count(pp => AttendCommitmentCode.committed.Contains(pp.Commitment ?? 0)); }
  			}
  			public List<NameId> OrderedPersons()
  			{
  				return (from p in Persons
  						orderby CmsData.Codes.AttendCommitmentCode.Order(p.Commitment), p.Name
  						select p).ToList();
  			}
  			public int Limit { get; set; }
  			public int MeetingId { get; set; }
  		}
  
  		public IEnumerable<List<Slot>> FetchSlotWeeks()
  		{
  			if (SortByWeek)
  				return from slot in FetchSlots()
  					   group slot by slot.Sunday into g
  					   where g.Any(gg => gg.Time > DateTime.Today)
  					   orderby g.Key.WeekOfMonth(), g.Key
  					   select g.OrderBy(gg => gg.Time).ToList();
  			else
  				return from slot in FetchSlots()
  					   group slot by slot.Sunday into g
  					   where g.Any(gg => gg.Time > DateTime.Today)
  					   orderby g.Key
  					   select g.OrderBy(gg => gg.Time).ToList();
  		}
  		public IEnumerable<Slot> FetchSlots()
  		{
  			var mlist = (from m in DbUtil.Db.Meetings
  			             where m.MeetingDate > Util.Now.Date
  			             where m.OrganizationId == OrgId
  			             orderby m.MeetingDate
  			             select m).ToList();
  
              var alist = (from a in DbUtil.Db.AttendCommitments(OrgId)
  						 orderby a.MeetingDate
                           select a).ToList();
              //            var alist = (from a in DbUtil.Db.Attends
              //                         where a.MeetingDate > Util.Now.Date
              //                         where a.OrganizationId == OrgId
              //                         where a.Commitment != null
              //                         let other = (from oa in a.Person.Attends
              //                                      where oa.OrganizationId != OrgId
              //                                      where oa.MeetingDate == a.MeetingDate
              //                                      where oa.Commitment == AttendCommitmentCode.Attending
              //                                      select oa.AttendId).Count()
              //                         orderby a.MeetingDate
              //                         select new
              //                         {
              //                             a.MeetingId,
              //                             a.MeetingDate,
              //                             a.PeopleId,
              //                             Name = a.Person.Name2,
              //                             a.Commitment,
              //                             other,
              //                         }).ToList();
  
  			var list = new List<Slot>();
  			for (var sunday = Sunday; sunday <= EndDt; sunday = sunday.AddDays(7))
  			{
  				var dt = sunday;
  				{
  					var u = from ts in Regsettings.TimeSlots.list
  							orderby ts.Datetime()
  							let time = ts.Datetime(dt)
  							let meeting = mlist.SingleOrDefault(mm => mm.MeetingDate == time)
  							let needed = meeting != null ? 
  									(from e in meeting.MeetingExtras
  								     where e.Field == "TotalVolunteersNeeded"
  									 select e.Data).SingleOrDefault().ToInt2() : null
  							let meetingid = meeting != null ? meeting.MeetingId : 0
  							select new Slot()
  									{
  										Time = time,
  										Sunday = dt,
  										Week = dt.WeekOfMonth(),
  										Disabled = time < DateTime.Now,
  										Limit = needed.ToInt2() ?? ts.Limit ?? 0,
  										Persons = (from a in alist
  												   where a.MeetingDate == time
                                                     orderby a.Name2
  												   select new NameId 
  												   { 
                                                         Name = a.Name2,
  													   PeopleId = a.PeopleId, 
                                                         Commitment = a.Commitment,
                                                         OtherCommitments = a.Conflicts == true
  												   }).ToList(),
  										MeetingId = meetingid
  									};
  					list.AddRange(u);
  				}
  			}
  			return list;
  		}
  		private Organization _org;
  		public Organization Org
  		{
  			get
  			{
  				return _org ??
  					(_org = DbUtil.Db.Organizations.Single(oo => oo.OrganizationId == OrgId));
  			}
  		}
  		private DateTime? _endDt;
  		public DateTime EndDt
  		{
  			get
  			{
  				if (!_endDt.HasValue)
  				{
  					var dt = Org.LastMeetingDate ?? DateTime.MinValue;
  					if (dt == DateTime.MinValue)
  
gt: 						dt = DateTime.Today.AddMonths(7);