using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.Entity;
using Bowin.Common.Linq;
using Bowin.Common.Linq.Entity;
using Bowin.Common.Utility;
using EMIS.DataLogic.Common.CalendarManage;
using EMIS.Entities;
using EMIS.ViewModel;
using EMIS.ViewModel.CalendarManage;
using EMIS.Utility;
using Aspose.Cells;
using System.Data;

namespace EMIS.CommonLogic.CalendarManage
{
    public partial class SchoolYearServices : BaseServices, ISchoolYearServices
    {
        public SchoolYearDAL schoolYearDAL { get; set; }
        public CoursesTimeDAL CoursesTimeDAL { get; set; }

        /// <summary>
        /// 查询学年学期信息
        /// </summary>
        /// <param name="configuretView">查询条件实体</param>
        /// <param name="SchoolyearsType">活动类型</param>
        /// <param name="timesSegment">时间段</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">显示页数</param>
        /// <returns></returns>
        public IGridResultSet<SchoolYearView> GetSchoolYearViewGrid(ConfiguretView configuretView, int? isCurrent, int pageIndex, int pageSize)
        {
            var query = schoolYearDAL.GetSchoolYearQueryable(x => true);
            if (isCurrent > -1)
            {
                bool current = isCurrent == 1 ? true : false;
                query = query.Where(x => x.IsCurrent == current);
            }
            if (!string.IsNullOrEmpty(configuretView.ConditionValue))
                return query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue).OrderByDescending(x => x.Years).ThenBy(t => t.SchoolcodeID).ToGridResultSet<SchoolYearView>(pageIndex, pageSize);
            return query.OrderByDescending(x => x.Value).ToGridResultSet<SchoolYearView>(pageIndex, pageSize);
        }

        /// <summary>
        /// 查询学年学期信息
        /// </summary>
        /// <param name="configuretView">查询条件实体</param>
        /// <returns></returns>
        public List<SchoolYearView> GetSchoolYearViewList(ConfiguretView configuretView, int? isCurrent)
        {

            var query = schoolYearDAL.GetSchoolYearQueryable(x => true);
            if (isCurrent > -1)
            {
                bool current = isCurrent == 1 ? true : false;
                query = query.Where(x => x.IsCurrent == current);
            }
            if (!string.IsNullOrEmpty(configuretView.ConditionValue))
                return query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue).OrderByDescending(x => x.Years).ThenBy(t => t.SchoolcodeID).ToList();
            return query.OrderByDescending(x => x.Value).ToList();
        }

        /// <summary>
        /// 查询之后的学年学期信息
        /// </summary>
        /// <returns></returns>
        public List<SchoolYearView> GetSchoolYearViewListAfterCurrent()
        {
            var currentSchoolYear = schoolYearDAL.schoolyearRepository.GetSingle(x => x.IsCurrent == true);
            if (currentSchoolYear == null)
            {
                throw new Exception("请先设置当前的学年学期。");
            }
            var query = schoolYearDAL.GetSchoolYearQueryable(x => x.Value >= currentSchoolYear.Value);
            return query.OrderByDescending(x => x.Value).ToList();
        }

        /// <summary>
        /// 查询之前的学年学期信息
        /// </summary>
        /// <returns></returns>
        public List<SchoolYearView> GetSchoolYearViewListBeforeCurrent()
        {
            var currentSchoolYear = schoolYearDAL.schoolyearRepository.GetSingle(x => x.IsCurrent == true);
            if (currentSchoolYear == null)
            {
                throw new Exception("请先设置当前的学年学期。");
            }
            var query = schoolYearDAL.GetSchoolYearQueryable(x => x.Value <= currentSchoolYear.Value);

            return query.OrderByDescending(x => x.Value).ToList();
        }
        /// <summary>
        /// 查询前一个学年学期信息
        /// </summary>
        /// <returns></returns>
        public SchoolYearView GetSchoolYearViewBeforeCurrent()
        {
            var currentSchoolYear = schoolYearDAL.schoolyearRepository.GetSingle(x => x.IsCurrent == true);
            if (currentSchoolYear == null)
            {
                throw new Exception("请先设置当前的学年学期。");
            }
            var query = schoolYearDAL.GetSchoolYearQueryable(x => x.Value ==currentSchoolYear.Value-1);

            return query.OrderByDescending(x => x.Value).FirstOrDefault();
        }
        /// <summary>
        /// 获取学年学期信息
        /// </summary>
        /// <param name="SchoolyearsID">主键ID</param>
        /// <returns></returns>
        public EMIS.Entities.CF_Schoolyear GetSchoolYear(Guid? schoolyearID)
        {
            //查询条件
            Expression<Func<EMIS.Entities.CF_Schoolyear, bool>> expression = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expression = (x => x.SchoolyearID == schoolyearID);
            return schoolYearDAL.schoolyearRepository.GetSingle(expression);
        }

        /// <summary>
        /// 获取学年学期信息
        /// </summary>
        /// <param name="SchoolyearsID">主键ID</param>
        /// <returns></returns>
        public EMIS.Entities.CF_Schoolyear GetSchoolYearByValue(int value)
        {
            //查询条件
            Expression<Func<EMIS.Entities.CF_Schoolyear, bool>> expression = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expression = (x => x.Value == value);
            return schoolYearDAL.schoolyearRepository.GetSingle(expression);
        }

        /// <summary>
        /// 获取学年学期信息
        /// </summary>
        /// <param name="schoolyearID">主键ID</param>
        /// <param name="IsCurrent">是否当前学期</param>
        /// <returns></returns>
        public List<EMIS.Entities.CF_Schoolyear> GetSchoolYearList(Guid? schoolyearID, bool IsCurrent)
        {
            var schoolyearList = schoolYearDAL.schoolyearRepository.Entities.Where(w => w.SchoolyearID != schoolyearID && w.IsCurrent == IsCurrent).ToList();
            return schoolyearList;
        }

        /// <summary>
        /// 获取学年学期信息
        /// </summary>
        /// <param name="Years">学年</param>
        /// <param name="Name">学期名称</param>
        /// <returns></returns>
        public EMIS.Entities.CF_Schoolyear GetSchoolYear(int Years, int SchoolcodeID)
        {
            //查询条件
            Expression<Func<EMIS.Entities.CF_Schoolyear, bool>> expression = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expression = (x => x.Years == Years && x.SchoolcodeID == SchoolcodeID);
            return schoolYearDAL.schoolyearRepository.GetSingle(expression);
        }


        /// <summary>
        /// 获取学年学期信息
        /// </summary>
        /// <param name="schoolyearID">主键ID</param>
        /// <returns></returns>
        public SchoolYearView GetSchoolYearView(Guid? schoolyearID)
        {
            SchoolYearView schoolYearView = new SchoolYearView();
            if (schoolyearID.HasValue)
                schoolYearView = schoolYearDAL.GetSchoolYearQueryable(x => true).Where(x => x.SchoolYearID == schoolyearID).FirstOrDefault();
            return schoolYearView;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="schoolyear">实体</param>
        /// <returns></returns>
        public bool SchoolYearAdd(SchoolYearView schoolyearView)
        {
            try
            {
                if(this.schoolYearDAL.schoolyearRepository.GetList(x=>x.RecordStatus>(int)SYS_STATUS.UNUSABLE&&x.Code==schoolyearView.Code).Count()>0)
                {
                    throw new Exception("学年学期"+schoolyearView.Code+"已存在,请重新输入!");
                }
                if (this.schoolYearDAL.schoolyearRepository
                             .GetList(x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE
                             && x.Years == schoolyearView.Years && x.SchoolcodeID == schoolyearView.SchoolcodeID).Count() > 0)
                {
                    var schoolCode = DictionaryHelper.GetSingleDictionary(schoolyearView.SchoolcodeID.Value, DictionaryItem.CF_Semester.ToString());
                    throw new Exception(schoolyearView.Years.Value.ToString() + "年下已存在" + schoolCode.Name + ",请重新输入!");
                }
                EMIS.Entities.CF_Schoolyear schoolyear = new EMIS.Entities.CF_Schoolyear();
                schoolyear.SchoolyearID = Guid.NewGuid();
                schoolyear.Code = schoolyearView.Code;
                schoolyear.Years = schoolyearView.Years.Value;
                schoolyear.SchoolcodeID = schoolyearView.SchoolcodeID.Value;
                schoolyear.WeeksNum = schoolyearView.WeeksNum.Value;
                schoolyear.FirstWeek = schoolyearView.FirstWeek.Value;
                schoolyear.IsCurrent = schoolyearView.IsCurrent;
                schoolyear.WeekDays = schoolyearView.WeekDays.Value;
                schoolyear.Value = (schoolyearView.Years.Value * 2) - 1 + (schoolyearView.SchoolcodeID.Value - 1);
                this.SetNewStatus(schoolyear);
                UnitOfWork.Add(schoolyear);

                if (schoolyearView.IsCurrent == true)//如果该数据为当前学期,则把其他数据的是否当前学期改成否
                {
                    var schoolyearList = GetSchoolYearList(schoolyear.SchoolyearID, true);
                    if (schoolyearList.Count > 0)
                    {
                        SchoolYearUpdateList(schoolyearList);
                    }
                }
                UnitOfWork.Commit();
                return true;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="SchoolyearsSets">实体</param>
        /// <returns></returns>
        public bool SchoolYearUpdate(SchoolYearView schoolyearView)
        {
            try
            {
                if (this.schoolYearDAL.schoolyearRepository.GetList(x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE && x.Code == schoolyearView.Code&&x.SchoolyearID!=schoolyearView.SchoolYearID).Count() > 0)
                {
                    throw new Exception("学年学期" + schoolyearView.Code + "已存在,请重新输入!");
                }
                if (this.schoolYearDAL.schoolyearRepository
                             .GetList(x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE
                             && x.Years == schoolyearView.Years && x.SchoolcodeID == schoolyearView.SchoolcodeID
                             && x.SchoolyearID != schoolyearView.SchoolYearID).Count() > 0)
                {
                    var schoolCode = DictionaryHelper.GetSingleDictionary(schoolyearView.SchoolcodeID.Value, DictionaryItem.CF_Semester.ToString());
                    throw new Exception(schoolyearView.Years.Value.ToString() + "年下已存在" + schoolCode.Name + ",请重新输入!");
                }
                var schoolyear = GetSchoolYear(schoolyearView.SchoolYearID);
                if (schoolyear == null)
                {
                    throw new Exception("保存失败,未能找到相对应的数据!");
                }
                schoolyear.Code = schoolyearView.Code;
                schoolyear.Years = schoolyearView.Years.Value;
                schoolyear.SchoolcodeID = schoolyearView.SchoolcodeID.Value;
                schoolyear.WeeksNum = schoolyearView.WeeksNum.Value;
                schoolyear.FirstWeek = schoolyearView.FirstWeek.Value;
                schoolyear.IsCurrent = schoolyearView.IsCurrent;
                schoolyear.WeekDays = schoolyearView.WeekDays.Value;
                schoolyear.Value = (schoolyearView.Years.Value * 2) - 1 + (schoolyearView.SchoolcodeID.Value - 1);
                this.SetModifyStatus(schoolyear);

                if (schoolyearView.IsCurrent == true)//如果该数据为当前学期,则把其他数据的是否当前学期改成否
                {
                    var schoolyearList = GetSchoolYearList(schoolyear.SchoolyearID, true);
                    if (schoolyearList.Count > 0)
                    {
                        SchoolYearUpdateList(schoolyearList);
                    }
                }
                UnitOfWork.Commit();
                return true;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="schoolyearList">实体集合</param>
        /// <returns></returns>
        private bool SchoolYearUpdateList(List<EMIS.Entities.CF_Schoolyear> schoolyearList)
        {
            try
            {
                foreach (var schoolyear in schoolyearList)
                {
                    schoolyear.IsCurrent = false;
                }

                return true;
            }
            catch (Exception)
            {

                throw;
            }
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="schoolyearIDs"></param>
        /// <returns></returns>
        public bool SchoolYearDelete(List<Guid> schoolyearIDs)
        {
            try
            {
                UnitOfWork.Delete<EMIS.Entities.CF_Schoolyear>(x => schoolyearIDs.Contains(x.SchoolyearID));
                UnitOfWork.Commit();
                return true;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public IGridResultSet<SchoolYearView> GetYearsViewGrid(ConfiguretView configuretView, int? isCurrent, int pageIndex, int pageSize)
        {
            var query = schoolYearDAL.GetYearsQueryable(x => true);
            //if (isCurrent > -1)
            //{
            //    bool current = isCurrent == 1 ? true : false;
            //    query = query.Where(x => x.IsCurrent == current);
            //}
            if (!string.IsNullOrEmpty(configuretView.ConditionValue))
                return query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue).OrderByDescending(x => x.Years).ThenBy(t => t.SchoolcodeID).ToGridResultSet<SchoolYearView>(pageIndex, pageSize);
            return query.OrderByDescending(x => x.Years).ToGridResultSet<SchoolYearView>(pageIndex, pageSize);
        }

        /// <summary>
        /// 获取当前校历启用的学年学期ID
        /// </summary>
        /// <returns></returns>
        public SchoolYearView GetCurrentSchoolYear()
        {
            var curSchoolYear = schoolYearDAL.GetSchoolYearQueryable(x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE && x.IsCurrent == true)
                .FirstOrDefault();
            if (curSchoolYear == null)
            {
                throw new Exception("请先设置当前启用的学年学期。");
            }

            return curSchoolYear;
        }

        /// <summary>
        /// 获取当前校历启用的下一个学年学期ID
        /// </summary>
        /// <returns></returns>
        public SchoolYearView GetNextSchoolYear()
        {
            var curSchoolYear = GetCurrentSchoolYear();
            var nextSchoolYear = schoolYearDAL.GetSchoolYearQueryable(x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE && x.Value > curSchoolYear.Value)
                .OrderBy(x => x.Value).FirstOrDefault();

            if (nextSchoolYear == null)
            {
                throw new Exception("当前启用的学年学期对应的下一学期信息为空,请添加。");
            }
            return nextSchoolYear;
        }

        public void UpdateCurrentSchoolYear()
        {
            var currentSchoolYear = this.GetCurrentSchoolYear();
            this.UnitOfWork.Update<EMIS.Entities.CF_Schoolyear>((x => new EMIS.Entities.CF_Schoolyear { IsCurrent = false }), (x => true));
            var dbSchoolYear = this.GetSchoolYear(currentSchoolYear.SchoolYearID);
            dbSchoolYear.IsCurrent = true;
            this.UnitOfWork.Commit();
        }




        /// <summary>
        /// 获取当前学年学期
        /// </summary>
        /// <param name="IsCurrent"></param>
        /// <returns></returns>
        public Entities.CF_Schoolyear GetSchoolYearIsCurrent(bool IsCurrent)
        {
            //查询条件
            Expression<Func<EMIS.Entities.CF_Schoolyear, bool>> expression = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            expression = (x => x.IsCurrent == IsCurrent);
            return schoolYearDAL.schoolyearRepository.GetSingle(expression);
        }

        /// <summary>
        /// 自动创建充足的学年学期和学年字典
        /// (仅针对松山,松山的学年学期记法比较怪异)
        /// </summary>
        public void AutoCreateSchoolyearAndYearsSS()
        {
            int year = DateTime.Today.Year;
            //设置要预留多少年的数据
            int addYears = 3;
            int endYear = year + addYears;
            int weeksNum = 20; //默认20,因为没有特定的规律判断到底是多少周,只能按一般大学的标准设置成20,如果不对,用户可以自己在页面上调整
            int weekdays = 5; //一周5天工作制,如果不对,用户可以自己在页面上调整

            var schoolyearList = schoolYearDAL.schoolyearRepository.GetList(x => x.Years >= year && x.Years <= endYear).ToList();
            var yearList = schoolYearDAL.dictionaryItemRepository.GetList(x => x.DictionaryCode == typeof(EMIS.ViewModel.CF_Year).Name
                                    && x.Value >= year && x.Value <= endYear).ToList();

            for (int i = 0; i <= addYears; i++)
            {
                var curYear = (year + i);
                if (!yearList.Any(x => x.Value == curYear))
                {
                    Sys_DictionaryItem dictionaryItem = new Sys_DictionaryItem();
                    dictionaryItem.DictionaryItemID = Guid.NewGuid();
                    dictionaryItem.Code = "Year" + curYear.ToString();
                    dictionaryItem.DictionaryCode = typeof(EMIS.ViewModel.CF_Year).Name;
                    dictionaryItem.Value = curYear;
                    dictionaryItem.Name = curYear.ToString();
                    dictionaryItem.OrderNo = (short)(curYear - 2005);
                    dictionaryItem.RecordStatus = (int)SYS_STATUS.USABLE;
                    dictionaryItem.IsEditable = false;
                    this.UnitOfWork.Add(dictionaryItem);
                }

                if (!schoolyearList.Any(x => x.Years == curYear && x.SchoolcodeID == 1))
                {
                    var firstDay = new DateTime(curYear, 3, 1);
                    switch (firstDay.DayOfWeek)
                    {
                        case DayOfWeek.Sunday: 
                            firstDay = firstDay.AddDays(1);
                            break;
                        case DayOfWeek.Saturday:
                            firstDay = firstDay.AddDays(2);
                            break;
                        default:
                            firstDay = firstDay.AddDays(1 - (int)firstDay.DayOfWeek);
                            break;
                    }

                    EMIS.Entities.CF_Schoolyear schoolyear = new Entities.CF_Schoolyear();
                    schoolyear.SchoolyearID = Guid.NewGuid();
                    schoolyear.Code = (curYear - 1).ToString() + "-" + curYear.ToString() + "02";
                    schoolyear.Years = curYear;
                    schoolyear.SchoolcodeID = 1;
                    schoolyear.WeeksNum = weeksNum;
                    schoolyear.FirstWeek = firstDay;
                    schoolyear.IsCurrent = false;
                    schoolyear.WeekDays = weekdays;
                    schoolyear.RecordStatus = (int)SYS_STATUS.USABLE;
                    schoolyear.CreateTime = schoolyear.ModifyTime = DateTime.Now;
                    schoolyear.Value = (curYear * 2 - 1);
                    this.UnitOfWork.Add(schoolyear);
                }
                if (!schoolyearList.Any(x => x.Years == curYear && x.SchoolcodeID == 2))
                {
                    var firstDay = new DateTime(curYear, 9, 1);
                    switch (firstDay.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            firstDay = firstDay.AddDays(1);
                            break;
                        case DayOfWeek.Saturday:
                            firstDay = firstDay.AddDays(2);
                            break;
                        default:
                            firstDay = firstDay.AddDays(1 - (int)firstDay.DayOfWeek);
                            break;
                    }

                    EMIS.Entities.CF_Schoolyear schoolyear = new Entities.CF_Schoolyear();
                    schoolyear.SchoolyearID = Guid.NewGuid();
                    schoolyear.Code = curYear.ToString() + "-" + (curYear + 1).ToString() + "01";
                    schoolyear.Years = curYear;
                    schoolyear.SchoolcodeID = 2;
                    schoolyear.WeeksNum = weeksNum;
                    schoolyear.FirstWeek = firstDay;
                    schoolyear.IsCurrent = false;
                    schoolyear.WeekDays = weekdays;
                    schoolyear.RecordStatus = (int)SYS_STATUS.USABLE;
                    schoolyear.CreateTime = schoolyear.ModifyTime = DateTime.Now;
                    schoolyear.Value = (curYear * 2 - 1) + 1;
                    this.UnitOfWork.Add(schoolyear);
                }
            }

            this.UnitOfWork.Commit();
        }

        /// <summary>
        /// 自动创建充足的学年学期和学年字典
        /// </summary>
        public void AutoCreateSchoolyearAndYears()
        {
            int year = DateTime.Today.Year;
            //设置要预留多少年的数据
            int addYears = 3;
            int endYear = year + addYears;
            int weeksNum = 20; //默认20,因为没有特定的规律判断到底是多少周,只能按一般大学的标准设置成20,如果不对,用户可以自己在页面上调整
            int weekdays = 5; //一周5天工作制,如果不对,用户可以自己在页面上调整

            var schoolyearList = schoolYearDAL.schoolyearRepository.GetList(x => x.Years >= year && x.Years <= endYear).ToList();
            var yearList = schoolYearDAL.dictionaryItemRepository.GetList(x => x.DictionaryCode == typeof(EMIS.ViewModel.CF_Year).Name
                                    && x.Value >= year && x.Value <= endYear).ToList();

            for (int i = 0; i <= addYears; i++)
            {
                var curYear = (year + i);
                if (!yearList.Any(x => x.Value == curYear))
                {
                    Sys_DictionaryItem dictionaryItem = new Sys_DictionaryItem();
                    dictionaryItem.DictionaryItemID = Guid.NewGuid();
                    dictionaryItem.Code = "Year" + curYear.ToString();
                    dictionaryItem.DictionaryCode = typeof(EMIS.ViewModel.CF_Year).Name;
                    dictionaryItem.Value = curYear;
                    dictionaryItem.Name = curYear.ToString();
                    dictionaryItem.OrderNo = (short)(curYear - 2005);
                    dictionaryItem.RecordStatus = (int)SYS_STATUS.USABLE;
                    dictionaryItem.IsEditable = false;
                    this.UnitOfWork.Add(dictionaryItem);
                }

                if (!schoolyearList.Any(x => x.Years == curYear && x.SchoolcodeID == 1))
                {
                    var firstDay = new DateTime(curYear, 9, 1);
                    switch (firstDay.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            firstDay = firstDay.AddDays(1);
                            break;
                        case DayOfWeek.Saturday:
                            firstDay = firstDay.AddDays(2);
                            break;
                        default:
                            firstDay = firstDay.AddDays(1 - (int)firstDay.DayOfWeek);
                            break;
                    }

                    EMIS.Entities.CF_Schoolyear schoolyear = new Entities.CF_Schoolyear();
                    schoolyear.SchoolyearID = Guid.NewGuid();
                    schoolyear.Code = curYear.ToString() + "-" + (curYear + 1).ToString() + "-1";
                    schoolyear.Years = curYear;
                    schoolyear.SchoolcodeID = 1;
                    schoolyear.WeeksNum = weeksNum;
                    schoolyear.FirstWeek = firstDay;
                    schoolyear.IsCurrent = false;
                    schoolyear.WeekDays = weekdays;
                    schoolyear.RecordStatus = (int)SYS_STATUS.USABLE;
                    schoolyear.CreateTime = schoolyear.ModifyTime = DateTime.Now;
                    schoolyear.Value = (curYear * 2 - 1);
                    this.UnitOfWork.Add(schoolyear);
                }
                if (!schoolyearList.Any(x => x.Years == curYear && x.SchoolcodeID == 2))
                {
                    var firstDay = new DateTime(curYear + 1, 3, 1);
                    switch (firstDay.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            firstDay = firstDay.AddDays(1);
                            break;
                        case DayOfWeek.Saturday:
                            firstDay = firstDay.AddDays(2);
                            break;
                        default:
                            firstDay = firstDay.AddDays(1 - (int)firstDay.DayOfWeek);
                            break;
                    }

                    EMIS.Entities.CF_Schoolyear schoolyear = new Entities.CF_Schoolyear();
                    schoolyear.SchoolyearID = Guid.NewGuid();
                    schoolyear.Code = curYear.ToString() + "-" + (curYear + 1).ToString() + "-2";
                    schoolyear.Years = curYear;
                    schoolyear.SchoolcodeID = 2;
                    schoolyear.WeeksNum = weeksNum;
                    schoolyear.FirstWeek = firstDay;
                    schoolyear.IsCurrent = false;
                    schoolyear.WeekDays = weekdays;
                    schoolyear.RecordStatus = (int)SYS_STATUS.USABLE;
                    schoolyear.CreateTime = schoolyear.ModifyTime = DateTime.Now;
                    schoolyear.Value = (curYear * 2 - 1) + 1;
                    this.UnitOfWork.Add(schoolyear);
                }
            }

            this.UnitOfWork.Commit();
        }

        public List<int> GetCurrentSchoolyearWeekNumList()
        {
            List<int> result = new List<int>();
            var schoolyear = this.GetCurrentSchoolYear();

            for (int i = 1; i <= schoolyear.WeeksNum; i++)
            {
                result.Add(i);
            }

            return result;
        }

        public List<int> GetSchoolyearWeekNumList(Guid? SchoolYearID)
        {
            
            List<int> result = new List<int>();
            if (SchoolYearID.HasValue)
            {
                var schoolyear = schoolYearDAL.schoolyearRepository.GetList(x => x.SchoolyearID == SchoolYearID).FirstOrDefault();
                if (schoolyear != null)
                {
                    for (int i = 1; i <= schoolyear.WeeksNum; i++)
                    {
                        result.Add(i);
                    }
                }
            }
            else 
            {
                result=GetCurrentSchoolyearWeekNumList();
            }
            return result;
        }

        public List<WeekDayView> GetFutureWeekdayList(int weekNum)
        {
            var curDate = DateTime.Today;
            var curSchoolyear = this.schoolYearDAL.schoolyearRepository.GetSingle(x => x.IsCurrent == true);
            var firstWeek = curSchoolyear.FirstWeek.AddDays(1 - (int)curSchoolyear.FirstWeek.DayOfWeek);
            var nowWeekNum = (curDate.Subtract(firstWeek).Days + 7) / 7;
            var nowWeekday = (int)curDate.DayOfWeek == 0 ? 7 : (int)curDate.DayOfWeek;
            var weekList = WeekHelper.WeekDictionary;
            if (weekNum < nowWeekNum)
            {
                weekList = new Dictionary<int,string>();
            }
            if (weekNum == nowWeekNum)
            {
                weekList = weekList.Where(x => (x.Key == 0 ? 7 : x.Key) >= nowWeekday).ToDictionary(x => x.Key, x => x.Value);
            }

            return weekList.Select(x => new WeekDayView { WeekDay = x.Key, ChineseName = x.Value }).ToList();
        }

        public List<CoursesTimeView> GetFutureCourseTimeList(int weekNum, int weekday)
        {
            var curDate = DateTime.Today;
            var curTimeValue = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
            var curSchoolyear = this.schoolYearDAL.schoolyearRepository.GetSingle(x => x.IsCurrent == true);
            var firstWeek = curSchoolyear.FirstWeek.AddDays(1 - (int)curSchoolyear.FirstWeek.DayOfWeek);
            var nowWeekNum = (curDate.Subtract(firstWeek).Days + 7) / 7;
            var nowWeekday = (int)curDate.DayOfWeek == 0 ? 7 : (int)curDate.DayOfWeek;
            Expression<Func<EM_CoursesTime, bool>> exp = (x => true);

            if (weekNum < nowWeekNum)
            {
                return new List<CoursesTimeView>();
            }
            if (weekNum == nowWeekNum && (weekday == 0 ? 7 : weekday) < nowWeekday)
            {
                return new List<CoursesTimeView>();
            }
            if (weekNum == nowWeekNum && (weekday == 0 ? 7 : weekday) == nowWeekday)
            {
                exp = exp.And(x => (x.StartHour * 60 + x.StartMinutes) > curTimeValue);
            }

            var courseTimeList = CoursesTimeDAL.GetCoursesTimeQueryable(exp).ToList();

            return courseTimeList;
        }

        public bool IsTimePassed(SchoolYearView currentSchoolyear, int? weekNum, int? weekday, int? startHour, int? startMinute)
        {
            if (!weekNum.HasValue || !weekday.HasValue)
            {
                return true;
            }
            var curDate = DateTime.Today;
            var curTimeValue = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
            var firstWeek = currentSchoolyear.FirstWeek.Value.AddDays(1 - (int)currentSchoolyear.FirstWeek.Value.DayOfWeek);
            var nowWeekNum = (curDate.Subtract(firstWeek).Days + 7) / 7;
            var nowWeekday = (int)curDate.DayOfWeek == 0 ? 7 : (int)curDate.DayOfWeek;

            if (weekNum < nowWeekNum)
            {
                return true;
            }
            if (weekNum == nowWeekNum && (weekday == 0 ? 7 : weekday) < nowWeekday)
            {
                return true;
            }
            if (weekNum == nowWeekNum && (weekday == 0 ? 7 : weekday) == nowWeekday && (startHour * 60 + startMinute) < curTimeValue)
            {
                return true;
            }

            return false;
        }

        public List<FullCoursesTimeView> GetCoursesTimeByDateTime(Guid schoolyearID, IList<StartEndTimeView> datetimeList)
        {
            var schoolyear = this.GetSchoolYearView(schoolyearID);
            var firstWeek = schoolyear.FirstWeek.Value.AddDays(1 - (int)schoolyear.FirstWeek.Value.DayOfWeek);
            var lastDay = firstWeek.AddDays(7 * (schoolyear.WeeksNum ?? 0));
            var courseTimeList = CoursesTimeDAL.GetCoursesTimeQueryable(x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE).ToList();
            var availableDateTimeList = datetimeList
                .Where(x => x.StartTime.HasValue && x.StartTime >= firstWeek && x.StartTime < lastDay
                    && x.EndTime.HasValue && x.EndTime >= firstWeek && x.EndTime < lastDay 
                    && x.StartTime.Value.Date == x.EndTime.Value.Date).ToList();
            var fullCoursesTimeViewList = new List<FullCoursesTimeView>();
            availableDateTimeList.ForEach(x =>
            {
                var courseTime = courseTimeList.Where(w => new DateTime(x.StartTime.Value.Year, x.StartTime.Value.Month, x.StartTime.Value.Day,
                    w.StartHour.Value, w.StartMinutes.Value, 0) <= x.EndTime.Value
                    && new DateTime(x.StartTime.Value.Year, x.StartTime.Value.Month, x.StartTime.Value.Day,
                    w.EndHour.Value, w.EndMinutes.Value, 0) >= x.StartTime.Value).ToList();

                courseTime.ForEach(w => 
                    fullCoursesTimeViewList.Add(new FullCoursesTimeView
                    {
                        WeekNum = x.StartTime.Value.Date.Subtract(firstWeek).Days / 7 + 1,
                        Weekday = (int)x.StartTime.Value.DayOfWeek,
                        CoursesTimeID = w.CoursesTimeID,
                        Date = x.StartTime.Value.Date,
                        StartHour = w.StartHour,
                        StartMinute = w.StartMinutes,
                        EndHour = w.EndHour,
                        EndMinute = w.EndMinutes
                    })
                );
            });

            return fullCoursesTimeViewList;
        }

        public List<StartEndTimeView> GetCoursesTimeByDateTime(Guid schoolyearID, IList<FullCoursesTimeView> coursesTimeList)
        {
            var schoolyear = this.GetSchoolYearView(schoolyearID);
            var firstWeek = schoolyear.FirstWeek.Value.AddDays(1 - (int)schoolyear.FirstWeek.Value.DayOfWeek);

            return coursesTimeList.Select(x => new StartEndTimeView 
            { 
                StartTime = firstWeek.AddDays((double)(((x.WeekNum ?? 0) - 1) * 7 + (x.Weekday == 0 ? 7 : x.Weekday ?? 1) - 1))
                    .AddHours((double)x.StartHour.Value).AddMinutes((double)x.StartMinute.Value),
                EndTime = firstWeek.AddDays((double)(((x.WeekNum ?? 0) - 1) * 7 + (x.Weekday == 0 ? 7 : x.Weekday ?? 1) - 1))
                    .AddHours((double)x.EndHour.Value).AddMinutes((double)x.EndMinute.Value)
            }).ToList();
        }

        public List<DateTime> GetDateByCoursesTime(Guid schoolyearID, IList<FullCoursesTimeView> coursesTimeList)
        {
            var schoolyear = this.GetSchoolYearView(schoolyearID);
            var firstWeek = schoolyear.FirstWeek.Value.AddDays(1 - (int)schoolyear.FirstWeek.Value.DayOfWeek);
            var lastDay = firstWeek.AddDays(7 * (schoolyear.WeeksNum ?? 0));
            var courseTimeDbList = CoursesTimeDAL.GetCoursesTimeQueryable(x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE).ToList();

            return coursesTimeList.Select(x => firstWeek.AddDays((double)(((x.WeekNum ?? 0) - 1) * 7 + (x.Weekday == 0 ? 7 : x.Weekday ?? 1) - 1))).ToList();
        }

        public StartEndTimeView GetStartEndTimeByCourseTime(DateTime firstWeek, FullCoursesTimeView coursesTime)
        {
            return new StartEndTimeView
            {
                StartTime = firstWeek.AddDays((double)(((coursesTime.WeekNum ?? 0) - 1) * 7 + (coursesTime.Weekday == 0 ? 7 : coursesTime.Weekday ?? 1) - 1))
                    .AddHours((double)coursesTime.StartHour.Value).AddMinutes((double)coursesTime.StartMinute.Value),
                EndTime = firstWeek.AddDays((double)(((coursesTime.WeekNum ?? 0) - 1) * 7 + (coursesTime.Weekday == 0 ? 7 : coursesTime.Weekday ?? 1) - 1))
                    .AddHours((double)coursesTime.EndHour.Value).AddMinutes((double)coursesTime.EndMinute.Value)
            };
        }


        

        

        /// <summary>
        /// 获取空格和当行最大行数
        /// </summary>
        /// <param name="ws"></param>
        /// <param name="weekDay"></param>
        /// <param name="firstCol"></param>
        /// <param name="lineEnd"></param>
        /// <param name="maxRow">最大行数</param>
        /// <returns>空格</returns>
        private Cell GetLastCell(Worksheet ws,int weekDay,int firstCol,int lineEnd, ref int maxRow)
        {
            int curRow = 0;
            int curCol = weekDay == 0 ? 7 : weekDay;

           curCol+=firstCol;

           while (ws.Cells[curRow + lineEnd, curCol].Value != null)
           {
                curRow++;
                
            }

            if (maxRow < curRow) {
                maxRow = curRow;
            }


            return ws.Cells[curRow + lineEnd, curCol];
        }
        
    }
}