using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Sched.CustomClasses;
using Sched.CustomSubwindows;
using Sched.CustomDialogs;
using Sched.ScheduleAlgorithm;

namespace Sched
{
    /// <summary>
    /// Interaction logic for AutoscheduleWindow.xaml
    /// </summary>
    public partial class AutoscheduleWindow : Window
    {
        public AssignmentData AD = new AssignmentData();
        
        public AutoscheduleWindow()
        {
            this.DataContext = AD;
            InitializeComponent();

            BTN_CourseCheck.Click += BTN_CourseCheck_Click;
            DG_Courses.AutoGeneratingColumn += DG_Courses_AutoGeneratingColumn;

            AddHandler(ScheduleForPanel.LoadCoursesEvent, new RoutedEventHandler(LoadCourses));
            AddHandler(ScheduleForPanel.UnloadCoursesEvent, new RoutedEventHandler(LoadCourses));
            AddHandler(ScheduleForPanel.GenerateScheduleEvent, new RoutedEventHandler(GenerateSchedule));

            Loaded += AutoscheduleWindow_Loaded;
            
        }

        private void AutoscheduleWindow_Loaded(object sender, RoutedEventArgs e)
        {
            SetDataGrids();
            BTN_CourseCheck.IsEnabled = false;
        }

        private void BTN_CourseCheck_Click(object sender, RoutedEventArgs e)
        {
            List<Lesson> lessonColl = GenerateLessons();
            TimetableCourseCheckDialog dlg = new TimetableCourseCheckDialog(AD.SemesterId, AD.CategoryId, new ObservableCollection<Lesson>(lessonColl));
            dlg.ShowDialog();
        }

        private List<Lesson> GenerateLessons()
        {
            DataTable dtLessons = Panel_Lessons.GetTable();
            DataTable dtLessonRoom = Panel_LessonRoom.GetTable();
            DataTable dtLessonTeacher = Panel_LessonTeacher.GetTable();
            DataTable dtLessonStudentGroup = Panel_LessonStudentGroup.GetTable();

            //ConstructLessons
            //Set default Stardate as StartDate of Semester
            Semester sem = (Semester)DBI.GetItemById("Semester", AD.SemesterId);
            int studentGroupId = AD.CategoryId;

            List<Lesson> lessonColl = new List<Lesson>();
            foreach (DataRow dr in dtLessons.Rows)
            {
                Lesson lesson = new Lesson();
                lesson.Id = (int)dr["Id"];
                lesson.CourseId = (int)dr["CourseId"];
                lesson.LessonTypeId = (int)dr["LessonTypeId"];
                lesson.Periodicity = (int)dr["Periodicity"];
                lesson.Hours = (int)dr["Hours"];
                lesson.StartDateDT = sem.DateStartDT;
                lesson.SemesterId = sem.Id;

                List<int> idsMN = new List<int>();
                foreach (DataRow dr2 in dtLessonTeacher.Rows)
                {
                    if ((int)dr["Id"] == (int)dr2["LessonId"])
                    {
                        idsMN.Add((int)dr2["TeacherId"]);
                    }
                }
                lesson.SetEntities("Teacher", idsMN);

                idsMN.Clear();
                foreach (DataRow dr2 in dtLessonRoom.Rows)
                {
                    if ((int)dr["Id"] == (int)dr2["LessonId"])
                    {
                        idsMN.Add((int)dr2["RoomId"]);
                    }
                }
                lesson.SetEntities("Room", idsMN);

                idsMN.Clear();
                foreach (DataRow dr2 in dtLessonStudentGroup.Rows)
                {
                    if ((int)dr["Id"] == (int)dr2["LessonId"])
                    {
                        idsMN.Add((int)dr2["StudentGroupId"]);
                    }
                }
                if (!idsMN.Contains(studentGroupId))    //every lesson must contain the group
                {
                    idsMN.Add(studentGroupId);
                }

                lesson.SetEntities("StudentGroup", idsMN);

                //Debug.WriteLine(lesson.GetInfoStringExtended());
                lessonColl.Add(lesson);
            }

            return lessonColl;
        }

        private void DG_Courses_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            string localizedHeader = "Str_" + e.Column.Header.ToString();
            e.Column.Header = (string)Application.Current.Resources.MergedDictionaries[App._languageResDictIndex][localizedHeader];
        }

        private void LoadCourses(object sender, RoutedEventArgs e)
        {
            if (e.RoutedEvent.Name == "LoadCourses")
            {
                DataTable dt = DBI.GetCourseList(AD.CategoryId);
                DG_Courses.ItemsSource = dt.DefaultView;

                ObservableCollection<ObservableCollection<object>> coll = new ObservableCollection<ObservableCollection<object>>();
                coll.Add(DBI.GetItemsBySemesterIdAndOrderByParameter("StudentGroup", AD.SemesterId, "Name"));
                dt = DBI.GetEmptyTableByName("LessonStudentGroup");
                Panel_LessonStudentGroup.SetTableAndComboCols(dt, new List<string>() { "StudentGroupId" }, coll);

                BTN_CourseCheck.IsEnabled = true;
            }
            else
            {
                DG_Courses.ItemsSource = null;
                BTN_CourseCheck.IsEnabled = false;
            }
        } 

        private void SetDataGrids()
        {
            ObservableCollection<ObservableCollection<object>> coll = new ObservableCollection<ObservableCollection<object>>();
            coll.Add(DBI.GetItemsAndOrderByParameter("Course", "Abbreviation"));
            coll.Add(DBI.GetItemsAndOrderByParameter("LessonType", "Abbreviation"));
            DataTable dt = DBI.GetModifiedEmptyLessonTable();
            Panel_Lessons.SetTableAndComboCols(dt, new List<string>() { "CourseId", "LessonTypeId" },coll);

            coll = new ObservableCollection<ObservableCollection<object>>();
            coll.Add(DBI.GetItemsAndOrderByParameter("Room", "Name"));
            dt = DBI.GetEmptyTableByName("LessonRoom");
            Panel_LessonRoom.SetTableAndComboCols(dt, new List<string>() { "RoomId"}, coll);

            coll = new ObservableCollection<ObservableCollection<object>>();
            coll.Add(DBI.GetItemsAndOrderByParameter("Teacher", "LastName"));
            dt = DBI.GetEmptyTableByName("LessonTeacher");
            Panel_LessonTeacher.SetTableAndComboCols(dt, new List<string>() { "TeacherId" }, coll);
        }

        private void GenerateSchedule(object sender, RoutedEventArgs e)
        {
            //Run
            List<int> dpRange = AD.Asd.GetDayPeriodRange();
            GreedyAlgorithm GA = new GreedyAlgorithm(dpRange[0], dpRange[1], dpRange[2], dpRange[3], AD.SemesterId, AD.CategoryId, AD.Asd.LessonTypePreference);
            List<Lesson> lessonCollDefined = GenerateLessons();

            //Check all lessons have teachers and rooms
            string noTeacher = "";
            string noRoom = "";
            foreach (Lesson lssn in lessonCollDefined)
            {
                if (lssn.GetEntities("Teacher").Count == 0)
                {
                    if (noTeacher.Length > 0)
                    {
                        noTeacher += ",";
                    }
                    noTeacher += lssn.Id.ToString();
                }
                if (lssn.GetEntities("Room").Count == 0)
                {
                    if (noRoom.Length > 0)
                    {
                        noRoom += ",";
                    }
                    noRoom += lssn.Id.ToString();
                }
            }

            if ((noTeacher.Length > 0) || (noRoom.Length > 0))
            {
                string msg = (string)Application.Current.Resources.MergedDictionaries[App._languageResDictIndex]["AS_MissingTeacherOrRoom_msg"];
                msg += "\n"+ (string)Application.Current.Resources.MergedDictionaries[App._languageResDictIndex]["Str_Teacher"];
                msg += "\t" + "{" + noTeacher + "}";
                msg += "\n"+ (string)Application.Current.Resources.MergedDictionaries[App._languageResDictIndex]["Str_Room"];
                msg += "\t" + "{" + noRoom + "}";
                msg += "\n" + (string)Application.Current.Resources.MergedDictionaries[App._languageResDictIndex]["AS_MissingTeacherOrRoom_msg_prompt"];

                if (MessageBox.Show(msg, App.AppName, MessageBoxButton.YesNo) == MessageBoxResult.No)
                {
                    return;
                }
            }

            //RUN optimize
            List<Lesson> lessonCollAssigned = GA.Run(lessonCollDefined);

            //Show results
            string unassignedIds = "";
            foreach (Lesson lssn in lessonCollDefined)
            {
                bool isIdAssigned = false;
                foreach (Lesson lssnA in lessonCollAssigned)
                {
                    if (lssn.Id == lssnA.Id)
                    {
                        isIdAssigned = true;
                        break;
                    }
                }
                if (!isIdAssigned)
                {
                    if (unassignedIds.Length > 0)
                    {
                        unassignedIds += ",";
                    }
                    unassignedIds += lssn.Id.ToString();
                }
            }
            unassignedIds = "{" + unassignedIds + "}";

            GeneratedTimetableViewDialog dlg = new GeneratedTimetableViewDialog(new ObservableCollection<object>(lessonCollAssigned), unassignedIds, lessonCollDefined.Count,lessonCollAssigned.Count);
            dlg.DataContext = this.DataContext;
            dlg.ShowDialog();
        }
    }
}
