using System;
using System.Collections.Generic;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Report.ReportObjects;
using BeWo.Report;
using DevExpress.XtraReports.UI;
using System.Data;

namespace BeWo.LebenshilfeDuisburgReports
{
    public partial class Schulbetreuung : DevExpress.XtraReports.UI.XtraReport, IBeWoReport<QueryRO>
    {
		public Schulbetreuung()
        {
            InitializeComponent();

        }

        public void SetReportDataSource(QueryRO pRO)
        {
            InitTable(pRO);
            this.bindingSource1.DataSource = pRO;
        }

        private void InitTable(QueryRO ro)
        {
            decimal gesamt = 0;
	        
			DateTime startMonat = DateTime.MinValue;
			DateTime endMonat = DateTime.MinValue;
            foreach (BeWo.Report.ReportObjects.QueryRO.Row row in ro.Rows)
            {
				if (startMonat == DateTime.MinValue)
                {
					startMonat = DateTime.Parse(row.Field1.ToString());
                }
				if (endMonat == DateTime.MinValue)
				{
					endMonat = DateTime.Parse(row.Field2.ToString());
				}

				long oid = 0;
				if (Int64.TryParse(row.Field3.ToString(), out oid))
				{
					var emp = DAOFactory.GenericDAO.LoadByID<Employee>(oid);

					lblMitarbeiter.Text = String.Format("{0} {1}", emp.Person.FirstName, emp.Person.LastName);
				}
				
				oid = 0;
				if (Int64.TryParse(row.Field4.ToString(), out oid))
				{
					var cust = DAOFactory.GenericDAO.LoadByID<Customer>(oid);

					lblKlient.Text = String.Format("{0} {1}", cust.Person.FirstName, cust.Person.LastName);
				}
				
            }

			ro.Rows.Clear();

	        while (startMonat <= endMonat)
	        {
				var monthRow = new QueryRO.Row();
				monthRow.ChildRows1 = new List<QueryRO.Row>();
				ro.Rows.Add(monthRow);

		        monthRow.Field1 = String.Format("{0:MMMM yyyy}", startMonat);

				DateTime startDay = new DateTime(startMonat.Year, startMonat.Month, 1);

				for (int i = 1; i <= DateTime.DaysInMonth(startMonat.Year, startMonat.Month); i++)
				{
					var dayRow = new QueryRO.Row();
					dayRow.Field1 = String.Format("{0:ddd, dd.MM.yyyy}", startDay);

					var ferien = GetFerien(startDay);
					if (ferien != null)
					{
						dayRow.Field5 = "1";
						if (startDay == ferien.Start)
						{
							dayRow.Field6 = ferien.Name;
						}
					}
					Feiertag ft = GetFeiertag(startDay);
					if (ft != null)
					{
						dayRow.Field5 = "1";
						dayRow.Field6 = ft.Name;
					}
					monthRow.ChildRows1.Add(dayRow);

					startDay = startDay.AddDays(1);
				}
		        startMonat = startMonat.AddMonths(1);
	        }
			

        }

		private Ferien GetFerien(DateTime start)
		{
			var ferienList = GetFerien();

			foreach (var ferien in ferienList)
			{
				if (start >= ferien.Start && start <= ferien.Ende)
					return ferien;
			}
			return null;
		}

		private Feiertag GetFeiertag(DateTime start)
		{
			List<Feiertag> feiertage = GetFeiertage(start.Year);

			foreach (var ft in feiertage)
			{
				if (start ==  ft.Datum)
					return ft;
			}
			return null;
		}

		private List<Feiertag> GetFeiertage(int year)
		{
			List<Feiertag> list = new List<Feiertag>();

			list.Add(new Feiertag() {Datum = new DateTime(year, 1, 1), Name = "Neujahr"});
			
			
			list.Add(new Feiertag() {Datum = new DateTime(year, 5, 1), Name = "Tag der Arbeit"});
			list.Add(new Feiertag() {Datum = new DateTime(year, 10, 3), Name = "Tag der dt. Einheit"});
			list.Add(new Feiertag() {Datum = new DateTime(year, 11, 1), Name = "Allerheiligen"});
			list.Add(new Feiertag() {Datum = new DateTime(year, 12, 24), Name = "Heilig Abend"});
			list.Add(new Feiertag() {Datum = new DateTime(year, 12, 25), Name = "1. Weihnachtstag"});
			list.Add(new Feiertag() {Datum = new DateTime(year, 12, 26), Name = "2. Weihnachtstag"});

			DateTime osterSonntag = GetOsterSonntag(year);
			list.Add(new Feiertag() {Datum = osterSonntag.AddDays(-2), Name = "Karfreitag"});
			list.Add(new Feiertag() {Datum = osterSonntag.AddDays(1), Name = "Ostermontag"});
			list.Add(new Feiertag() {Datum = osterSonntag.AddDays(39), Name = "Christi Himmelfahrt"});
			
			list.Add(new Feiertag() {Datum = osterSonntag.AddDays(50), Name = "Pfingstmontag"});
			list.Add(new Feiertag() { Datum = osterSonntag.AddDays(60), Name = "Fronleichnam" });

			return list;
		}


		protected DateTime GetOsterSonntag(int year)
		{

			int g, h, c, j, l, i;

			g = year % 19;
			c = year / 100;
			h = ((c - (c / 4)) - (((8 * c) + 13) / 25) + (19 * g) + 15) % 30;
			i = h - (h / 28) * (1 - (29 / (h + 1)) * ((21 - g) / 11));
			j = (year + (year / 4) + i + 2 - c + (c / 4)) % 7;

			l = i - j;
			int month = (int)(3 + ((l + 40) / 44));
			int day = (int)(l + 28 - 31 * (month / 4));

			return new DateTime(year, month, day);

		}

		private List<Ferien> GetFerien()
		{
			List<Ferien> list = new List<Ferien>();
			list.Add(new Ferien() {Name = "Sommerferien", Start = new DateTime(2014, 7, 7), Ende = new DateTime(2014, 8, 19)});
			list.Add(new Ferien() {Name = "Herbstferien", Start = new DateTime(2014, 10, 6), Ende = new DateTime(2014, 10, 18)});
			list.Add(new Ferien() {Name = "Weihnachtsferien", Start = new DateTime(2014, 12, 22), Ende = new DateTime(2015, 1, 6)});
			
			list.Add(new Ferien() {Name = "Osterferien", Start = new DateTime(2015, 3, 30), Ende = new DateTime(2015, 4, 11)});
			list.Add(new Ferien() {Name = "Sommerferien", Start = new DateTime(2015, 6, 29), Ende = new DateTime(2015, 8, 11)});
			list.Add(new Ferien() {Name = "Herbstferien", Start = new DateTime(2015, 10, 5), Ende = new DateTime(2015, 10, 17)});
			list.Add(new Ferien() {Name = "Weihnachtsferien", Start = new DateTime(2015, 12, 23), Ende = new DateTime(2016, 1, 6)});

			list.Add(new Ferien() {Name = "Osterferien", Start = new DateTime(2016, 3, 21), Ende = new DateTime(2016, 4, 2)});
			list.Add(new Ferien() {Name = "Sommerferien", Start = new DateTime(2016, 7, 11), Ende = new DateTime(2016, 8, 23)});
			list.Add(new Ferien() {Name = "Herbstferien", Start = new DateTime(2016, 10, 10), Ende = new DateTime(2016, 10, 21)});
			list.Add(new Ferien() {Name = "Weihnachtsferien", Start = new DateTime(2016, 12, 23), Ende = new DateTime(2017, 1, 6)});
			
			list.Add(new Ferien() {Name = "Osterferien", Start = new DateTime(2017, 4, 10), Ende = new DateTime(2017, 4, 22)});
			list.Add(new Ferien() {Name = "Sommerferien", Start = new DateTime(2017, 7, 17), Ende = new DateTime(2017, 8, 29)});

			
			return list;
		}
    }

	class Ferien
	{
		public String Name { get; set; }
		public DateTime Start { get; set; }
		public DateTime Ende { get; set; }
	}

	class Feiertag
	{
		public String Name { get; set; }
		public DateTime Datum { get; set; }
	}
}
