using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Web.UI.WebControls;

namespace ExWeb
{
    public partial class Mod_Calendar : Mod
    {
        public static string Help_Description =
            "Anzeige eines Kalenders"
            + "\r\n\r\nTermine in externer Textdatei 'Fil'"
            + "\r\nTermine werden im Kalender angezeigt"
            + "\r\nEintägiger Termin: <Datum>[ <Uhrzeit>],<text>,[<link>],[opt1],[opt2]..."
            + "\r\nMehrtägiger Termin: <DatumVon>=<DatumBis>,<text>,[<link>]"
            + "\r\n<Datum>: yyyy-mm-dd\r\n"
            + "\r\n<Datum Uhrzeit>: yyyy-mm-dd hh:mm\r\n"
            ;

        public static string[][] Help_Attributes = new string[][]
        {
            // Attribut, Wert, DefaultWert, Optional, Hilfe
            new string[] {"Fil", "string", "","opt","Name der Datendatei","Fil=\"Calendar.txt\""},
            new string[] {"ShowList","0 1","0","opt","Zeige alle Ereignisse des aktuellen Monats in einer Liste","ShowList=\"1\""},
            new string[] {"ShowMonths","0 1","0","opt","Zeige Monate","ShowMonths=\"1\""},
            new string[] {"Col_Date","string","Datum","opt","Name der Datumsspalte","Col_Date=\"Tag\""},
            new string[] {"Col_Text","string","Text","opt","Name der Überschriftsspalte","Col_Text=\"Was?\""},
            new string[] {"Col_Time","string","Uhrzeit","opt","Name der Uhrzeitspalte","Col_Time=\"Wann?\""},
            new string[] {"Col_Date","string","Datum","opt","Name der Datumsspalte","Col_Date=\"Wann?\""},
            new string[] {"DateFormat","1 2","2","opt","Format Datumsspalte","DateFormat=\"1?\""},
        };
        string[] Months = new string[] { "Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" };
        string[] MonthsShort = new string[] { "Jän", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" };
        string[] Days = new string[] { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" };
        string[] DaysShort = new string[] { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So" };
        protected string _Fil = "";
        public string Fil
        {
            set
            {
                if (value!="") _Fil = value;
            }
        }
        bool _ShowList = false;
        public string ShowList
        {
            set
            {
                _ShowList = value == "1";
            }
        }
        bool _ShowMonths = false;
        public string ShowMonths
        {
            set
            {
                _ShowMonths = value == "1";
            }
        }
        protected string _Col_Date = "Datum";
        public string Col_Date
        {
            set
            {
                if (value != "") _Col_Date = value;
            }
        }
        protected string _Col_Text = "Text";
        public string Col_Text
        {
            set
            {
                if (value != "") _Col_Text = value;
            }
        }
        protected string _Col_Time = "Uhrzeit";
        public string Col_Time
        {
            set
            {
                if (value != "") _Col_Time = value;
            }
        }
        protected enum DATEFORMAT { DDMMYYYY, WWDDMMM };
        protected DATEFORMAT _DateFormat = DATEFORMAT.DDMMYYYY;
        public string DateFormat
        {
            set
            {
                switch (value)
                {
                    case "1":
                        _DateFormat = DATEFORMAT.DDMMYYYY;
                        break;
                    case "2":
                        _DateFormat = DATEFORMAT.WWDDMMM;
                        break;
                    default:
                        break;
                }
            }
        }
        
        string[] ColumnNames = null;
        int LinkFieldPosition = -1;
        bool ColumnNamesIncluded = false;
        DataTable dt;

        protected void AddEvent(DateTime date, string[] Fields)
        {
            DataRow dr = dt.NewRow();
            dr[0] = date;
            if (Fields != null)
            {
                for (int i = 1; i < Fields.Length; i++)
                {
                    string AdditionalField = Fields[i];
                    dr[i] = Fields[i];
                }
            }
            if (LinkFieldPosition > -1) 
                dr["html"] = MakeLink(dr["text"].ToString(), dr["link"].ToString(), Target);
            DayOfWeek dow = date.DayOfWeek;
            dr["DateText"] =
                DaysShort[((int)dow)] + "<br/>"
                + date.Day.ToString() + ". "
                + MonthsShort[date.Month - 1];
            dr["TimeText"] =
                date.Hour + ":" + date.Minute.ToString().PadLeft(2, '0');
            dt.Rows.Add(dr);
        }
        protected void AddEvent(string strCalendarEntry, int YearVisible, int MonthVisible)
        {
            string[] EventParts = strCalendarEntry.Split(new char[] { ',' });
            string[] DateParts = EventParts[0].Trim().Split(new char[] { '=' });
            if (DateParts.Length == 1) // eintägiger Termin
            {
                DateTime date = DateTime.Parse(EventParts[0].Trim());
                if ((date.Year == YearVisible) && (date.Month == MonthVisible))
                {
                    AddEvent(date, EventParts);
                }
            }
            else
            {
                DateTime Start = DateTime.Parse(DateParts[0].Trim()).Date;
                DateTime End = DateTime.Parse(DateParts[1].Trim()).Date;
                int Days = End.Subtract(Start).Days;
                for (int d = 0; d < Days; d++)
                {
                    DateTime date = Start.AddDays(d);
                    if ((date.Year == YearVisible) && (date.Month == MonthVisible))
                    {
                        AddEvent(date, EventParts);
                    }
                }
            }
        }
        protected void Page_LoadComplete(object sender, EventArgs e)
        {
            SetPanelLayout(this.Controls);
        }
        protected new void Page_Load(object sender, EventArgs e)
        {
            Page.LoadComplete += new EventHandler(Page_LoadComplete);
            FillDataTable(DateTime.Now);
            GridView_List.Columns.Clear();
            TableCell_Months.Visible = (_ShowMonths ? true : false);
            TableCell_List.Visible = (_ShowList ? true : false);
            if (!IsPostBack)
            {
            }
        }
        protected void FillDataTable(DateTime MonthSelectedDate)
        {
            string[] strCalendarEntries = null;
            string _FilAbsolute = Server.MapPath(_Fil);
            try
            {
                strCalendarEntries = File.ReadAllLines(_FilAbsolute);
            }
            catch
            {
                return;
            }
            if (strCalendarEntries[0].ToLower().StartsWith("date")) // erste Zeile enthält Spaltennamen
            {
                ColumnNamesIncluded = true;
                ColumnNames = strCalendarEntries[0].Split(new char[] { ',' });
                for (int i = 0; i < ColumnNames.Length; i++)
                {
                    string ColumnName = ColumnNames[i];
                    ColumnName = ColumnName.Trim();
                    ColumnName = ColumnName.Substring(0, 1).ToUpper() + ColumnName.Substring(1);
                    ColumnNames[i] = ColumnName;
                }
            }
            else
            {
                if (strCalendarEntries.Length > 3) return;
                ColumnNames = new string[strCalendarEntries.Length];
                string[] ColumnNames0 = new string[] { "Date", "Text", "Link" };
                for (int i = 0; i < strCalendarEntries.Length; i++)
                {
                    ColumnNames[i] = ColumnNames0[i];
                }
            }
            dt = new DataTable();
            for (int i = 0; i < ColumnNames.Length; i++)
            {
                string ColumnName = ColumnNames[i];
                if (ColumnName.ToLower() == "link")
                    LinkFieldPosition = i;
                dt.Columns.Add(new DataColumn(ColumnName, Type.GetType((ColumnName.ToLower() == "date") ? "System.DateTime" : "System.String")));
            }
            if (LinkFieldPosition > -1) dt.Columns.Add(new DataColumn("Html", Type.GetType("System.String")));
            dt.Columns.Add(new DataColumn("DateText", Type.GetType("System.String")));
            dt.Columns.Add(new DataColumn("TimeText", Type.GetType("System.String")));

            int YearVisible = MonthSelectedDate.Year;
            int MonthVisible = MonthSelectedDate.Month;
            for (int i = (ColumnNamesIncluded ? 1 : 0); i < strCalendarEntries.Length; i++)
            {
                AddEvent(strCalendarEntries[i], YearVisible, MonthVisible);
            }
            if (_ShowList)
            {
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    string ColumnName = dt.Columns[i].ColumnName.ToLower();
                    BoundField bf = new BoundField();
                    switch (ColumnName)
                    {
                        case "text":
                            if (LinkFieldPosition > -1)
                            {
                                bf.DataField = "html";
                                bf.HeaderText = _Col_Text;
                                bf.HtmlEncode = false;
                            }
                            else
                            {
                                bf.DataField = ColumnName;
                                bf.HeaderText = ColumnName;
                            }
                            GridView_List.Columns.Add(bf);
                            break;
                        case "link":
                        case "html":
                            break;
                        case "date":
                            switch (_DateFormat)
                            {
                                case DATEFORMAT.DDMMYYYY:
                                    bf.DataField = "date";
                                    bf.HeaderText = _Col_Date;
                                    GridView_List.Columns.Add(bf);
                                    break;
                                case DATEFORMAT.WWDDMMM:
                                    bf.DataField = "datetext";
                                    bf.HeaderText = _Col_Date;
                                    bf.HtmlEncode = false;
                                    GridView_List.Columns.Add(bf);
                                    break;
                            }
                            break;
                        case "datetext":
                            break;
                        case "timetext":
                            bf.DataField = ColumnName;
                            bf.HeaderText = _Col_Time;
                            GridView_List.Columns.Add(bf);
                            break;
                        default:
                            bf.DataField = ColumnName;
                            bf.HeaderText = ColumnName;
                            GridView_List.Columns.Add(bf);
                            break;
                    }
                }
                DataView dv = new DataView(dt);
                dv.Sort = "date";
                GridView_List.Visible = true;
                GridView_List.DataSource = dv;
                GridView_List.DataBind();
            }
            else
            {
                GridView_List.Visible = false;
            }
        }
        int GetEventIndex(DateTime d)
        {
            if (dt == null) return -1;
            int Index = -1;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (DateTime.Parse(dt.Rows[i]["DATE"].ToString()) == d)
                {
                    Index = i;
                    break;
                }
            }
            return Index;
        }
        protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
        {
            e.Cell.Text = e.Day.Date.Day.ToString();
            if (e.Day.IsOtherMonth)
                e.Cell.Text = "";
            else if (e.Day.Date == DateTime.Now.Date)
            {
                e.Cell.CssClass = "CalendarToday";
            }
            DateTime d = e.Day.Date;
            int Index = GetEventIndex(d);
            if (Index > -1)
            {
                e.Cell.ToolTip = dt.Rows[Index]["TEXT"].ToString();
                e.Cell.CssClass = "CalendarEvent";
                if (LinkFieldPosition > -1)
                    e.Cell.Text = MakeLink(e.Cell.Text, dt.Rows[Index][LinkFieldPosition].ToString(), Target);
            }
        }
        protected void GridView_List_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            GridViewRow dr = e.Row;
            switch (dr.RowType)
            {
                case DataControlRowType.DataRow:
                    // Datumskorrektur: Zeit wird eliminiert
                    string s = dr.Cells[0].Text;
                    s = s.Replace("00:00:00", "");
                    dr.Cells[0].Text = s;
                    break;
                default:
                    break;
            }
        }
        protected void Calendar1_VisibleMonthChanged(object sender, MonthChangedEventArgs e)
        {
            FillDataTable(e.NewDate);
        }
        protected void Menu_Months_MenuItemClick(object sender, MenuEventArgs e)
        {
            int Year = DateTime.Now.Year;
            // int Year = int.Parse(DropDownList_Year.SelectedValue); //  DateTime.Now.Year;
            int Month = int.Parse(e.Item.Value);
            FillDataTable(new DateTime(Year, Month, 1));
        }
        class cal : IEquatable<cal>
        {
            DateTime Date;
            string Text;
            public cal(DateTime Date, string Text)
            {
                this.Date = Date;
                this.Text = Text;
            }
            public bool Equals(cal otherDate)
            {
                if (this.Date == otherDate.Date)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }
}