using System;
using System.Data;
using System.Globalization;
using System.Threading;
using System.Web.Mvc;
using System.Web.WebPages;
using DayPilot.Web.Mvc;
using DayPilot.Web.Mvc.Data;
using DayPilot.Web.Mvc.Enums;
using DayPilot.Web.Mvc.Events;
using DayPilot.Web.Mvc.Events.Common;
using DayPilot.Web.Mvc.Events.Scheduler;
using DayPilot.Web.Mvc.Json;
using DayPilot.Web.Mvc.Utils;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class SchedulerController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult EventLinks()
        {
            return View();
        }

        public ActionResult CssContinue()
        {
            return View();
        }

        public ActionResult EventInlineEditing()
        {
            return View();
        }

        public ActionResult AutoCellWidth()
        {
            return View();
        }

        public ActionResult ScaleHours()
        {
            return View();
        }

        public ActionResult Milestones()
        {
            return View();
        }

        public ActionResult ScaleDays()
        {
            return View();
        }

        public ActionResult ScaleWeeks()
        {
            return View();
        }

        public ActionResult ScaleMonths()
        {
            return View();
        }

        public ActionResult ScaleYears()
        {
            return View();
        }

        public ActionResult ScaleCustom()
        {
            return View();
        }

        public ActionResult HidingWeekends()
        {
            return View();
        }

        public ActionResult ThemeTransparent()
        {
            return View();
        }
        
        public ActionResult Notify()
        {
            return View();
        }
        
        public ActionResult RowCreating()
        {
            return View();
        }

        public ActionResult RowEditing()
        {
            return View();
        }

        public ActionResult RowProgressive()
        {
            return View();
        }
        
        public ActionResult RowMoving()
        {
            return View();
        }
        
        public ActionResult RowSelecting()
        {
            return View();
        }
        
        public ActionResult ThemeSilver()
        {
            return RedirectToAction("ThemeTraditional");
        }
        
        public ActionResult ThemeWhite()
        {
            return View();
        }
        
        public ActionResult ThemeGreen()
        {
            return View();
        }

        public ActionResult Theme8()
        {
            return View();
        }

        public ActionResult ThemeGreenWithDurationBar()
        {
            return RedirectToAction("ThemeGreen");
        }

        public ActionResult ThemeBlue()
        {
            return View();
        }
        
        public ActionResult ThemeTraditional()
        {
            return View();
        }
        
        public ActionResult ActiveAreas()
        {
            return View();
        }        

        public ActionResult CellsDisabled()
        {
            return View();
        }        

        public ActionResult PercentComplete()
        {
            return View();
        }        

        public ActionResult RowHeaderAutoFit()
        {
            return View();
        }        

        public ActionResult RowHeaderHiding()
        {
            return View();
        }        
        public ActionResult RowHeaderScrolling()
        {
            return View();
        }        
        
        public ActionResult PreventParentUsage()
        {
            return View();
        }       
        
        public ActionResult LimitEventMoving()
        {
            return View();
        }
        
        public ActionResult EventMoveToPosition()
        {
            return View();
        }

        public ActionResult EventMultiSelecting()
        {
            return View();
        }

        public ActionResult EventMultiMoving()
        {
            return View();
        }

        public ActionResult EventMultiResizing()
        {
            return View();
        }

        public ActionResult MultiRange()
        {
            return View();
        }

        public ActionResult EventDragDropIndicators()
        {
            return View();
        }

        public ActionResult Gantt()
        {
            return View();
        }

        public ActionResult Timesheet()
        {
            return View();
        }

        public ActionResult ExternalDragDrop()
        {
            return View();
        }

        public ActionResult JQuery()
        {
            return View();
        }

        public ActionResult RecurringEvents()
        {
            return View();
        }

        public ActionResult Message()
        {
            return View();
        }

        public ActionResult Scrolling()
        {
            return View();
        }

        public ActionResult Crosshair()
        {
            return View();
        }

        public ActionResult ContextMenu()
        {
            return View();
        }

        public ActionResult AutoRefresh()
        {
            return View();
        }

        public ActionResult DynamicEventLoading()
        {
            return View();
        }

        public ActionResult DynamicTreeLoading()
        {
            return View();
        }

        public ActionResult RowHeaderColumns()
        {
            return View();
        }
        
        public ActionResult RowHeight()
        {
            return View();
        }

        public ActionResult EventSelecting()
        {
            return View();
        }
        public ActionResult EventsGroupConcurrent()
        {
            return View();
        }

        public ActionResult EventDeleting()
        {
            return View();
        }

        public ActionResult EventOverlapping()
        {
            return View();
        }

        public ActionResult TimeHeaders()
        {
            return View();
        }

        public ActionResult Hijri()
        {
            return View();
        }        

        public ActionResult Hebrew()
        {
            return View();
        }        

        public ActionResult Japanese()
        {
            return View();
        }        

        public ActionResult Korean()
        {
            return View();
        }        

        public ActionResult Taiwan()
        {
            return View();
        }        

        public ActionResult ThaiBuddhist()
        {
            return View();
        }

        public ActionResult TimeRangeSelecting()
        {
            return View();
        }        

        public ActionResult EventStackingLineHeight()
        {
            return View();
        }

        public ActionResult ResourceUtilization()
        {
            return View();
        }

        public ActionResult Backend()
        {
            return new Dps().CallBack(this);
        }

        public ActionResult Edit(string id)
        {
            var e = new EventManager(this).Get(id) ?? new EventManager.Event();
            return View(e);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(FormCollection form)
        {
            new EventManager(this).EventEdit(form["Id"], form["Text"]);
            return JavaScript(SimpleJsonSerializer.Serialize("OK"));
        }

        class Dps : DayPilotScheduler
        {
            //private bool useViewPort;
            Random random = new Random();

            protected override void OnInit(InitArgs ea)
            {

                //StartDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
                //Days = DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month);

                if (Id == "dps_rowheadercolumns") // Scheduler/RowHeaderColumns
                {
                    foreach (Resource r in Resources)
                    {                        
                        foreach (Resource c in r.Children)
                        {
                            c.Columns.Add(new ResourceColumn("Col A"));
                            c.Columns.Add(new ResourceColumn("Col B"));
                        }
                    }
                }
                if (Id == "dps_jquery") // Scheduler/JQuery
                {
                    for (var i = 'A'; i < 'Z'; i++)
                    {
                        Resources.Add("" + i, i.ToString());
                    }
                }
                if (Id == "dps_progressive")
                {
                    for (var i = 0; i < 10000; i++)
                    {
                        Resources.Add("Resource " + i, i.ToString());
                    }
                }
                if (Id == "dps_hebrew")
                {
                    DateTimeFormatInfo = new CultureInfo("he-il", false).DateTimeFormat;
                    DateTimeFormatInfo.Calendar = new HebrewCalendar();

                    int year = Calendar.GetYear(DateTime.Today);
                    StartDate = new DateTime(year, 1, 1, Calendar);
                    Days = Calendar.GetDaysInYear(year);
                }
                if (Id == "dps_hijri")
                {
                    DateTimeFormatInfo = new CultureInfo("ar-sa", false).DateTimeFormat;
                    DateTimeFormatInfo.Calendar = new HijriCalendar();

                    int year = Calendar.GetYear(DateTime.Today);
                    StartDate = new DateTime(year, 1, 1, Calendar);
                    Days = Calendar.GetDaysInYear(year);
                }
                if (Id == "dps_japanese")
                {
                    DateTimeFormatInfo = new CultureInfo("ja-jp", false).DateTimeFormat;
                    DateTimeFormatInfo.Calendar = new JapaneseCalendar();

                    int year = Calendar.GetYear(DateTime.Today);
                    StartDate = new DateTime(year, 1, 1, Calendar);
                    Days = Calendar.GetDaysInYear(year);
                }
                if (Id == "dps_korean")
                {
                    DateTimeFormatInfo = new CultureInfo("ko-kr", false).DateTimeFormat;
                    DateTimeFormatInfo.Calendar = new KoreanCalendar();

                    int year = Calendar.GetYear(DateTime.Today);
                    StartDate = new DateTime(year, 1, 1, Calendar);
                    Days = Calendar.GetDaysInYear(year);
                }
                if (Id == "dps_taiwan")
                {
                    DateTimeFormatInfo = new CultureInfo("zh-tw", false).DateTimeFormat;
                    DateTimeFormatInfo.Calendar = new TaiwanCalendar();

                    int year = Calendar.GetYear(DateTime.Today);
                    StartDate = new DateTime(year, 1, 1, Calendar);
                    Days = Calendar.GetDaysInYear(year);
                }
                if (Id == "dps_thaibuddhist")
                {
                    DateTimeFormatInfo = new CultureInfo("th-th", false).DateTimeFormat;
                    DateTimeFormatInfo.Calendar = new ThaiBuddhistCalendar();

                    int year = Calendar.GetYear(DateTime.Today);
                    StartDate = new DateTime(year, 1, 1, Calendar);
                    Days = Calendar.GetDaysInYear(year);
                }

                if (Id == "dps_scrolling" || Id == "dps_dynamic")
                {
                    int year = Calendar.GetYear(DateTime.Today);
                    StartDate = new DateTime(year, 1, 1, Calendar);
                    Days = Calendar.GetDaysInYear(year);
                }

                if (Id == "dps_timeline")
                {
                    DateTime start = new DateTime(2015, 1, 1, 12, 0, 0);
                    DateTime end = new DateTime(2016, 1, 1, 12, 0, 0);

                    Timeline = new TimeCellCollection();
                    for (DateTime cell = start; cell < end; cell = cell.AddDays(1))
                    {
                        Timeline.Add(cell, cell.AddDays(1));
                    }

                }

                if (Id == "dps_links")
                {
                    Links = new TaskManager(Controller).LinkData;
                }

                ScrollTo(DateTime.Today);

                UpdateWithMessage("Welcome!", CallBackUpdateType.Full);
            }

            protected override void OnEventSelect(EventSelectArgs e)
            {
                if (e.Event.Id == "1" && e.Change == EventSelectChange.Selected)
                {
                    SelectedEvents.Add(EventInfo.Create("13"));
                }
                Update();
            }

            protected override void OnEventDelete(EventDeleteArgs e)
            {
                new EventManager(Controller, Id).EventDelete(e.Id);
                UpdateWithMessage("Event deleted.");
            }

            protected override void OnEventEdit(EventEditArgs e)
            {
                if (e.Id == "NEW")
                {
                    new EventManager(Controller, Id).EventCreate(e.Start, e.End, e.NewText, e.Resource);
                }
                else
                {
                    new EventManager(Controller, Id).EventEdit(e.Id, e.NewText);
                }
                Update();
            }

            protected override void OnLoadNode(LoadNodeArgs e)
            {
                Resource child = new Resource("Test", Guid.NewGuid().ToString());
                child.DynamicChildren = true;

                e.Resource.Children.Add(child);
                e.Resource.Expanded = true;

                Update(CallBackUpdateType.Full);
            }

            protected override void OnRowEdit(RowEditArgs e)
            {
                e.Resource.Name = e.NewText;
                Update(CallBackUpdateType.Full);
            }

            protected override void OnRowSelect(RowSelectArgs e)
            {
                UpdateWithMessage("Number of selected rows: " + SelectedRows.Count);
            }

            protected override void OnCommand(CommandArgs e)
            {
                switch (e.Command)
                {
                    case "filter":
                        Update();
                        break;
                    case "refresh":
                        UpdateWithMessage("Refreshed");
                        break;
                    case "next":
                        StartDate = StartDate.AddYears(1);
                        Days = Year.Days(StartDate);
                        Update(CallBackUpdateType.Full);
                        break;
                    case "previous":
                        StartDate = StartDate.AddYears(-1);
                        Days = Year.Days(StartDate);
                        Update(CallBackUpdateType.Full);
                        break;
                    case "this":
                        StartDate = Year.First(DateTime.Today);
                        Days = Year.Days(StartDate);
                        Update(CallBackUpdateType.Full);
                        break;
                    case "selected":
                        if (SelectedEvents.Count > 0)
                        {
                            EventInfo ei = SelectedEvents[0];
                            SelectedEvents.RemoveAt(0);
                            UpdateWithMessage("Event removed from selection: " + ei.Text);
                        }

                        break;
                    case "delete":
                        string id = (string)e.Data["id"];
                        new EventManager(Controller, Id).EventDelete(id);
                        Update(CallBackUpdateType.EventsOnly);
                        break;
                }
            }

            protected override void OnRowMove(RowMoveArgs e)
            {
                e.Move();
                Update(CallBackUpdateType.Full);
            }

            protected override void  OnBeforeCellRender(BeforeCellRenderArgs e)
            {
                if (Id == "dps_parents")
                {
                    if (Resources.FindById(e.ResourceId).Children.Count > 0)
                    {
                        e.BackgroundColor = "white";
                    }
                }

                if (Id == "dps_areas")
                {
                    e.Areas.Add(
                        new Area().Start(e.Start.AddHours(6))
                            .End(e.End.AddHours(-6))
                            .Top(0)
                            .Bottom(0)
                            .Style("background-color: red; opacity: .1;")
                            .Visible());
                    
                }

                if (Id == "dps_cellsdisabled")
                {
                    if (e.Start < DateTime.Today)
                    {
                        e.Disabled = true;
                        e.BackgroundColor = "#ccc";
                    }
                }

            }

            protected override void OnBeforeResHeaderRender(BeforeResHeaderRenderArgs e)
            {
                if (Id == "dps_areas")
                {
                    e.Areas.Add(new Area().Width(17).Bottom(1).Right(0).Top(0).CssClass("resource_action_menu").Html("<div><div></div></div>").JavaScript("alert(e.Value);"));
                }

                if (e.Columns.Count > 0)
                {
                    e.Columns[0].Html = "10 seats";
                }

                if (e.Id == "C")
                {
                    e.MoveEnabled = false;
                }                

            }

            protected override void OnEventBubble(EventBubbleArgs e)
            {
                e.BubbleHtml = "Event details for id: " + e.Id + "<br/>" + e.Start + " " + e.End;
            }

            protected override void OnTimeRangeSelected(TimeRangeSelectedArgs e)
            {
                if (e.Multirange != null)
                {
                    foreach (TimeRangeSelectedArgs item in e.Multirange)
                    new EventManager(Controller, Id).EventCreate(item.Start, item.End, "Default name", item.Resource);
                }
                else
                {
                    new EventManager(Controller, Id).EventCreate(e.Start, e.End, "Default name", e.Resource);
                }
                UpdateWithMessage("New event created", CallBackUpdateType.EventsOnly);
            }

            protected override void OnEventMove(EventMoveArgs e)
            {
                if (new EventManager(Controller, Id).Get(e.Id) != null)
                {
                    if (e.Multimove != null)
                    {
                        e.Multimove.ForEach(ei => new EventManager(Controller, Id).EventMove(ei.Id, ei.NewStart, ei.NewEnd, ei.NewResource));
                    }
                    else
                    {
                        new EventManager(Controller, Id).EventMove(e.Id, e.NewStart, e.NewEnd, e.NewResource);
                    }
                }
                else // external drag&drop
                {
                    new EventManager(Controller, Id).EventCreate(e.NewStart, e.NewEnd, e.Text, e.NewResource, e.Id);
                }
                if (Id == "dps_position")
                {
                    UpdateWithMessage("Moved to position: " + e.Position);
                }
                else
                {
                    UpdateWithMessage("Event moved.");
                }

            }

            protected override void OnEventResize(EventResizeArgs e)
            {
                if (e.Multiresize != null)
                {
                    e.Multiresize.ForEach(ei => new EventManager(Controller, Id).EventMove(ei.Id, ei.NewStart, ei.NewEnd));
                }
                else
                {
                    new EventManager(Controller, Id).EventMove(e.Id, e.NewStart, e.NewEnd);
                }
                Update();
            }

            protected override void OnBeforeEventRender(BeforeEventRenderArgs e)
            {
                if (Id == "dps_limit")
                {
                    int id = 0;
                    int.TryParse(e.Id, out id);

                    if (id % 2 == 0)
                    {
                        e.DurationBarColor = "red";
                        e.EventMoveVerticalEnabled = false;
                    }
                    else
                    {
                        e.DurationBarColor = "blue";
                        e.EventMoveHorizontalEnabled = false;
                    }
                }
                else if (Id == "dps_areas")
                {
                    e.Areas.Add(new Area().Width(17).Height(17).Right(2).Top(4).CssClass("event_action_delete").JavaScript("dps_areas.commandCallBack('delete', {id:e.value() });"));
                    e.Areas.Add(new Area().Width(17).Height(17).Right(19).Top(4).CssClass("event_action_menu").ContextMenu("menu"));

                    e.Areas.Add(
                        new Area().Start(DateTime.Today)
                            .End(DateTime.Today.AddDays(1))
                            .Top(0)
                            .Bottom(0)
                            .Style("background-color: red; opacity: .5;")
                            .Visible());
                }
                else if (Id == "dps_complete")
                {
                    int complete = random.Next(100);
                    e.PercentComplete = complete;

                    string cs = String.Format("{0}%", complete);
                    e.Html = cs;

                }

                if (e.Recurrent)
                {
                    e.Html += " (R)";
                }

                if (e.Id == "1")
                {
                    e.EventDeleteEnabled = false;
                }

            }

            protected override void OnEventMenuClick(EventMenuClickArgs e)
            {
                switch (e.Command)
                {
                    case "Delete":
                        new EventManager(Controller, Id).EventDelete(e.Id);
                        Update();
                        break;
                }
            }

            protected override void OnEventClick(EventClickArgs e)
            {
                if (Id == "dps_message")
                {
                    UpdateWithMessage("Event clicked: " + e.Text);
                }
            }

            protected override void OnBeforeTimeHeaderRender(BeforeTimeHeaderRenderArgs e)
            {
                if (Id == "dps_timeheaders")
                {
                    if (e.Level == 1)
                    {
                        DateTime monday = Week.Monday(e.Start, ResolvedWeekStart);
                        e.InnerHtml = String.Format("Week {0}", Week.WeekNrISO8601(monday));
                    }
                }

                if (Id == "dps_areas")
                {
                    e.Areas.Add(
                        new Area().Start(e.Start.AddHours(6))
                            .End(e.End.AddHours(-6))
                            .Top(0)
                            .Bottom(0)
                            .Style("background-color: blue; opacity: .1;")
                            .Visible());

                }


            }

            protected override void OnIncludeCell(IncludeCellArgs e)
            {
                /*
                if (e.Start.DayOfWeek == DayOfWeek.Saturday || e.Start.DayOfWeek == DayOfWeek.Sunday)
                {
                    e.Visible = false;
                }
                 * */

            }

            protected override void OnLinkCreate(LinkCreateArgs e)
            {
                UpdateWithMessage("Link created: " + e.FromId + " " + e.ToId);
            }

            protected override void OnResourceExpand(ResourceExpandArgs args)
            {
                UpdateWithMessage("expanded " + args.Resource.Id);
            }

            protected override void OnNotify(NotifyArgs e)
            {
                foreach(DayPilotArgs a in e.Queue)
                {
                    if (a is EventUpdateArgs)
                    {
                        EventUpdateArgs updateArgs = (EventUpdateArgs) a;
                        string id = updateArgs.Event.Id;
                        string newText = updateArgs.New.Text;
                        // update the db
                    }
                }
            }

            protected override void OnRowCreate(RowCreateArgs e)
            {
                Resources.Add(e.Text, Guid.NewGuid().ToString());
                UpdateWithMessage("Row added: " + e.Text, CallBackUpdateType.Full);
            }

            protected override void OnScroll(ScrollArgs e)
            {
                Update(CallBackUpdateType.EventsOnly);
            }

            protected override void OnBeforeEventRecurrence(BeforeEventRecurrenceArgs e)
            {
            }

            protected override void OnFinish()
            {
                // only load the data if an update was requested by an Update() call
                if (UpdateType == CallBackUpdateType.None)
                {
                    return;
                }


                DateTime start = DynamicLoading ? ViewPort.Start : StartDate;
                DateTime end = DynamicLoading ? ViewPort.End : EndDate;


                Events = new EventManager(Controller, Id).FilteredData(start, end, (string)ClientState["filter"]).AsEnumerable();
                switch (Id)
                {
                    case "dps_recurring":                        
                        DataRecurrenceField = "recurrence";
                        break;
                    case "dps_milestones":
                        DataMilestoneField = "milestone";
                        break;
                }

                //Separators.Clear();
                //Separators.Add(DateTime.Now, Color.Red);


                DataStartField = "start";
                DataEndField = "end";
                DataTextField = "text";
                DataIdField = "id";
                DataResourceField = "resource";

                DataTagFields = "id, text, resource";
                
            }

        }

    }
}
