using System;
using System.Collections;
using System.Data;
using System.Linq;
using System.Web.Script.Services;
using System.Web.Services;
using Data;
using DayPilot.Utils;
using DayPilot.Web.Ui.Data;
using DayPilot.Web.Ui.Enums;
using DayPilot.Web.Ui.Events;
using DayPilot.Web.Ui.Events.Calendar;
using Newtonsoft.Json;
using BeforeTimeHeaderRenderEventArgs = DayPilot.Web.Ui.Events.Calendar.BeforeTimeHeaderRenderEventArgs;
using CommandEventArgs = DayPilot.Web.Ui.Events.CommandEventArgs;

public partial class _Default : System.Web.UI.Page
{
    private DataTable blocks;

    protected void Page_Load(object sender, EventArgs e)
    {
        blocks = new DataManager().GetBlocks();

        if (!IsPostBack)
        {
            DayPilotCalendar1.StartDate = Week.FirstWorkingDayOfWeek(DayPilotNavigator1.SelectionStart);
            DayPilotCalendar1.Days = 5;

            DayPilotCalendar1.DataSource = new DataManager().GetAssignments(DayPilotCalendar1);
            DayPilotCalendar1.DataBind();
        }
    }

    protected void DayPilotCalendar1_OnBeforeTimeHeaderRender(BeforeTimeHeaderRenderEventArgs ea)
    {
        int id = ea.Start.Hours;
        DataRow r = FindBlock(id);

        if (r != null)
        {
            ea.InnerHTML = String.Format("Block {0}<br/>{1}<br/>{2}", id,
                TimeFormatter.GetHourMinutes((DateTime) r["BlockStart"], DayPilotCalendar1.TimeFormat),
                TimeFormatter.GetHourMinutes((DateTime) r["BlockEnd"], DayPilotCalendar1.TimeFormat));
        }
        else
        {
            ea.InnerHTML = "Unknown Block.";
        }

        ea.Areas.Add(new Area().Width(15).Top(0).Bottom(0).Right(0).CssClass("resource_action_menu")
            .Html("<div><div></div></div>").JavaScript("editBlock(e);"));
    }


    private DataRow FindBlock(int i)
    {
        return blocks.Rows.Cast<DataRow>().FirstOrDefault(dr => Convert.ToInt32(dr["BlockId"]) == i);
    }

    protected void DayPilotCalendar1_OnCommand(object sender, CommandEventArgs e)
    {
        switch (e.Command)
        {
            case "navigate":
                DayPilotCalendar1.StartDate = Week.FirstWorkingDayOfWeek((DateTime) e.Data["start"]);
                DayPilotCalendar1.Update();
                LoadEvents();
                break;

            case "refresh":
                LoadEvents();

                if (e.Data != null && e.Data["message"] != null)
                {
                    DayPilotCalendar1.UpdateWithMessage((string) e.Data["message"]);
                }
                else
                {
                    DayPilotCalendar1.UpdateWithMessage("Updated.");
                }

                break;
        }
    }

    private void LoadEvents()
    {
        DayPilotCalendar1.DataSource = new DataManager().GetAssignments(DayPilotCalendar1);
        DayPilotCalendar1.DataBind();
    }

    protected void DayPilotCalendar1_EventMove(object sender, EventMoveEventArgs e)
    {
        new DataManager().MoveAssignment(Convert.ToInt32(e.Value), e.NewStart, e.NewEnd);
        DayPilotCalendar1.DataSource = new DataManager().GetAssignments(DayPilotCalendar1);
        DayPilotCalendar1.DataBind();
        DayPilotCalendar1.Update();
    }

    protected void DayPilotCalendar1_EventResize(object sender, EventResizeEventArgs e)
    {
        new DataManager().MoveAssignment(Convert.ToInt32(e.Value), e.NewStart, e.NewEnd);
        DayPilotCalendar1.DataSource = new DataManager().GetAssignments(DayPilotCalendar1);
        DayPilotCalendar1.DataBind();
        DayPilotCalendar1.Update();
    }

    protected void DayPilotCalendar1_BeforeEventRender(object sender,
        DayPilot.Web.Ui.Events.Calendar.BeforeEventRenderEventArgs e)
    {
        string color = (string) e.DataItem["AssignmentColor"];
        if (!String.IsNullOrEmpty(color) && color != "default")
        {
            e.BackgroundColor = color;
            e.BorderColor = color;
            e.FontColor = "#ffffff";
        }
    }


    [WebMethod, ScriptMethod(UseHttpGet = true)]
    public static string GetBlocks()
    {
        // int id = Convert.ToInt32(idStr);

        DataTable blocks = new DataManager().GetBlocks();

        ArrayList items = new ArrayList();

        foreach (DataRow r in blocks.Rows)
        {
            int id = Convert.ToInt32(r["BlockId"]);
            DateTime start = (DateTime) r["BlockStart"];
            DateTime end = (DateTime) r["BlockEnd"];
            string name = String.Format("Block {0} ({1} - {2})", id,
                TimeFormatter.GetHourMinutes(start, TimeFormat.Auto),
                TimeFormatter.GetHourMinutes(end, TimeFormat.Auto));
            Hashtable item = new Hashtable();
            item["name"] = name;
            item["id"] = id;
            items.Add(item);
        }


        Hashtable result = new Hashtable();
        result["data"] = items;
        return JsonConvert.SerializeObject(result);
    }

    [WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public static string Create(DateTime day, int start, int duration, string description, string color)
    {
        int totalBlocks = 8;
        duration = start + duration > totalBlocks
            ? totalBlocks - start
            : duration; // make sure it's within the visible range

        day = day.Date;
        DateTime startDate = day.Add(TimetableManager.MapBlock(start));
        DateTime endDate = startDate.Add(TimetableManager.MapBlock(duration));

        new DataManager().CreateAssignment(startDate, endDate, description, color);

        Hashtable result = new Hashtable();
        result["status"] = "OK";
        result["message"] = "Created";
        return JsonConvert.SerializeObject(result);
    }


    [WebMethod, ScriptMethod(UseHttpGet = true)]
    public static string GetAssignment(int id)
    {
        DataRow dr = new DataManager().GetAssignment(id);
        Hashtable result = new Hashtable();

        DateTime start = TimetableManager.UnmapEventStart((DateTime) dr["AssignmentStart"]);
        DateTime end = TimetableManager.UnmapEventEnd((DateTime) dr["AssignmentEnd"]);

        result["id"] = id;
        result["start"] = start;
        result["end"] = end;
        result["description"] = Convert.ToString(dr["AssignmentNote"]);
        result["color"] = (string)dr["AssignmentColor"];

        return JsonConvert.SerializeObject(result);
    }


    [WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public static string Update(int id, string description, string color)
    {
        new DataManager().UpdateAssignmentNote(id, description, color);

        Hashtable result = new Hashtable();
        result["status"] = "OK";
        result["message"] = "Updated";
        return JsonConvert.SerializeObject(result);
    }

    [WebMethod, ScriptMethod(UseHttpGet = true)]
    public static string GetBlock(int id)
    {
        DataRow dr = new DataManager().GetBlock(id);
        Hashtable result = new Hashtable();

        result["id"] = id;
        result["startMinutes"] = ((DateTime)dr["BlockStart"]).TimeOfDay.TotalMinutes;
        result["endMinutes"] = ((DateTime)dr["BlockEnd"]).TimeOfDay.TotalMinutes;

        return JsonConvert.SerializeObject(result);
    }


    [WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public static string UpdateBlock(int id, int startMinutes, int endMinutes)
    {
        TimeSpan start = TimeSpan.FromMinutes(startMinutes);
        TimeSpan end = TimeSpan.FromMinutes(endMinutes);

        DataRow block = new DataManager().GetBlock(id);
        if (block == null)
        {
            new DataManager().InsertBlock(id, start, end);
        }
        else
        {
            new DataManager().UpdateBlock(id, start, end);
        }

        Hashtable result = new Hashtable();
        result["status"] = "OK";
        result["message"] = "Updated";
        return JsonConvert.SerializeObject(result);
    }

    protected void DayPilotCalendar1_OnEventDelete(object sender, EventDeleteEventArgs e)
    {
        new DataManager().DeleteAssignment(Convert.ToInt32(e.Id));
        DayPilotCalendar1.DataSource = new DataManager().GetAssignments(DayPilotCalendar1);
        DayPilotCalendar1.DataBind();
        DayPilotCalendar1.Update();
    }
}