public ActionResult Create(AlumnoMaterium recordacademico)
        {
            int indice = recordacademico.Alumno.Nombre.IndexOf('-') + 2;
            if (indice != 1)
            {
                string ced = recordacademico.Alumno.Nombre.Substring(indice).Trim();
                int cedula = Convert.ToInt32(ced);
                recordacademico.Cedula = cedula;

                indice = recordacademico.Materium.Nombre.IndexOf(':') + 2;
                if (indice != 1)
                {
                    string id = recordacademico.Materium.Nombre.Substring(indice).Trim();
                    int idMateria = Convert.ToInt32(id);
                    recordacademico.IdMateria = idMateria;

                    if (ModelState.IsValid)
                    {
                        IRepositorio<AlumnoMaterium> myRepoRecordacademico = new AlumnoMateriumRepositorio();
                        String resultado = myRepoRecordacademico.Save(recordacademico);

                        if (resultado.Equals("true"))
                            return RedirectToAction("Index");
                    }
                }
            }
            return View(recordacademico);
        }
        public virtual bool Equals(AlumnoMaterium obj)
        {
            if (obj == null) return false;

            if (Equals(Cedula, obj.Cedula) == false) return false;
            if (Equals(HorasPersonales, obj.HorasPersonales) == false) return false;
            if (Equals(IdMateria, obj.IdMateria) == false) return false;
            return true;
        }
        private void HorasPersonales(IEnumerable<int?> misMaterias, Alumno alumno)
        {
            var miEdad = (int)((_fechaActual - alumno.FechaNac).Days / 365.25);

            IRepositorio<DatosSociales> repositorioDatosSociales = new DatosSocialesRepositorio();
            var misDatosSociales =
                repositorioDatosSociales.GetByUniqueAtribute(alumno.Cedula.ToString());

            IRepositorio<PromedioFactor> repositorioPromedioFactor = new PromedioFactorRepositorio();
            var promedioFactor = repositorioPromedioFactor.GetAll();

            IRepositorio<Materium> repositorioMaterium = new MateriumRepositorio();
            // Se obtienen las horas base y se customiza segun los parametros del estudiante.
            foreach (int idMateria in misMaterias)
            {
                double horasBase = repositorioMaterium.GetById(idMateria).HorasBase;

                double promHistorico = 0;
                decimal nota = 0;
                int cantPersonalizacion = 0;

                // Personaliza segun la edad
                var fEdad = (from factor in promedioFactor
                             where factor.Factor.CompareTo("Edad") == 0 &&
                                   factor.Clasificacion.CompareTo(miEdad.ToString()) == 0 &&
                                   factor.IdMateria == idMateria
                             select factor);
                if (fEdad.Count() > 0)
                {
                    cantPersonalizacion++;
                    nota = fEdad.First().Promedio;
                    promHistorico = promHistorico + (double)nota;
                }

                //Personaliza segun Trabajo
                cantPersonalizacion++;
                if (misDatosSociales.Trabaja.CompareTo("Si") == 0)
                {
                    nota = (from factor in promedioFactor
                            where factor.Factor.CompareTo("Trabajo") == 0 &&
                                  factor.Clasificacion.CompareTo(misDatosSociales.RelacionTrabCarr) == 0 &&
                                  factor.IdMateria == idMateria
                            select factor.Promedio).First();
                }
                else
                {
                    nota = (from factor in promedioFactor
                            where factor.Factor.CompareTo("Trabajo") == 0 &&
                                  factor.Clasificacion.CompareTo("No Trabaja") == 0 &&
                                  factor.IdMateria == idMateria
                            select factor.Promedio).First();
                }
                promHistorico = promHistorico + Convert.ToDouble(nota);

                //Personaliza segun la materia
                cantPersonalizacion++;
                nota = (from factor in promedioFactor
                        where factor.Factor.CompareTo("Promedio") == 0 &&
                              factor.IdMateria == idMateria
                        select factor.Promedio).First();
                promHistorico = promHistorico + Convert.ToDouble(nota);

                //Personaliza segun el record de las materias que prelan esta materia
                IRepositorio<Requisito> repositorioRequisito = new RequisitoRepositorio();
                var misRequisitos = (from r in repositorioRequisito.GetAll()
                                     where r.IdMateriaHijo == idMateria
                                     select r.IdMateriaPadre).ToList();

                var prom = 0.0;
                if (misRequisitos.Count > 0)
                {
                    IRepositorio<SlRecordAcademico> repositorioSlRecord = new SlRecordAcademicoRepositorio();
                    IRepositorio<SlSeccion> repositorioSlSeccion = new SlSeccionRepositorio();
                    IRepositorio<SlMaterium> repositorioSlMateria = new SlMateriumRepositorio();
                    var anioPerdiodo = Convert.ToInt32(_periodoActual.Substring(0, 4));
                    var periodo = Convert.ToInt32(_periodoActual.Substring(4));
                    if (periodo > 21)
                    {
                        periodo--;
                    }
                    else
                    {
                        anioPerdiodo--;
                    }
                    var periodoAnterior = Convert.ToInt32(anioPerdiodo.ToString() + periodo.ToString());
                    var sum = 0;
                    foreach (var requisito in misRequisitos)
                    {
                        var materia = repositorioMaterium.GetById(requisito);
                        var slMateria = repositorioSlMateria.GetAll().Where(m => m.Nombre.CompareTo(materia.Nombre) == 0).First();
                        var slSeccion = repositorioSlSeccion.GetAll().Where(s => s.IdMateria == slMateria.IdMateria &&
                                                                                 s.Periodo.CompareTo(periodoAnterior) == 0).ToList();
                        var n = (from record in repositorioSlRecord.GetAll()
                                 from seccion in slSeccion
                                 where record.Cedula == alumno.Cedula &&
                                       record.IdSeccion == seccion.IdSeccion
                                 select record.Nota);
                        if (n.Count() > 0)
                        {
                            sum++;
                            prom += Convert.ToDouble(n.First());
                        }
                    }
                    if (prom > 0.0)
                    {
                        cantPersonalizacion++;
                        promHistorico += (prom / sum);
                    }
                }

                promHistorico = promHistorico / cantPersonalizacion;

                /*
                 * Segun el promedio obtenido segun las caracteristicas
                 * personales del alumno se le aumentan o disminuyen las
                 * horas de estudio segun una regla.
                 */
                const double pendiente = -0.075;
                var factorM = (promHistorico * pendiente) + 1.75;
                var horasPersonalizadas = horasBase * factorM;

                var misHorasPersonales = new AlumnoMaterium()
                {
                    IdMateria = idMateria,
                    Cedula = alumno.Cedula,
                    HorasPersonales = horasPersonalizadas
                };

                //Segun las notas obtenidas en las evaluaciones anteriores se afecta las horas personales
                IRepositorio<ClaseEvaluacion> repositorioHorarioClase = new HorarioClaseRepositorio();
                var listCronograma = repositorioHorarioClase.GetAll().Where(alum => alum.Cedula == alumno.Cedula).ToList();

                IRepositorio<Actividad> repositorioActividad = new ActividadRepositorio();
                var listActividades = repositorioActividad.GetAll().Where(a => a.Periodo.CompareTo(_periodoActual) == 0).ToList();

                var misEvaluaciones = (from d in listCronograma
                                       from c in listActividades
                                       where c.Tipo.CompareTo("Evaluacion") == 0 &&
                                             d.IdActividad == c.IdActividad
                                       select c).ToList();

                foreach (var miEvaluacion in misEvaluaciones)
                {
                    var miNota = (from cE in listCronograma
                                  where cE.IdActividad == miEvaluacion.IdActividad
                                  select cE.Nota).First();
                    if (miNota != 0.0)
                    {
                        const int x1 = 10;
                        const int y1 = 0;
                        const int x2 = 20;
                        var y2 = (misHorasPersonales.HorasPersonales * (miEvaluacion.Ponderacion / 100.00)) * -1;
                        var pendiente1 = (y2 - y1) / (x2 - x1);
                        var factorMat = (miNota * pendiente1) - y2;
                        misHorasPersonales.HorasPersonales += factorMat;
                    }
                }

                if (prom > 0.00)
                {
                    if (prom < 4)
                    {
                        misHorasPersonales.Preferencia = 5;
                    }
                    else if (prom < 8)
                    {
                        misHorasPersonales.Preferencia = 4;
                    }
                    else if (prom < 12)
                    {
                        misHorasPersonales.Preferencia = 3;
                    }
                    else if (prom < 16)
                    {
                        misHorasPersonales.Preferencia = 2;
                    }
                    else if (prom <= 20)
                    {
                        misHorasPersonales.Preferencia = 1;
                    }
                }
                IRepositorio<AlumnoMaterium> repositorioAlumnoMateria = new AlumnoMateriumRepositorio();
                repositorioAlumnoMateria.Update(misHorasPersonales);
            }
        }
        private void GuardarActMejorHorario(DateTime miFecha, AlumnoMaterium alumnoMaterium, int diasEstudio)
        {
            var periodoActual = Helper.CalcularPeriodoActual();
            IRepositorio<HorarioPreferencia> repositorioHorarioPreferencia = new HorarioPreferenciaRepositorio();
            IRepositorio<AlumnoMaterium> repositorioAlumnoMateria = new AlumnoMateriumRepositorio();

            IRepositorio<Materium> repositorioMaterium = new MateriumRepositorio();
            IRepositorio<Actividad> repositorioActividad = new ActividadRepositorio();

            IRepositorio<ClaseEvaluacion> repositorioClaseEvaluacion = new HorarioClaseRepositorio();
            var listMisClasesEvaluacion = repositorioClaseEvaluacion.GetAll().Where(cE => cE.Cedula == alumnoMaterium.Cedula).ToList();

            var misActividades = (from a in repositorioActividad.GetAll()
                                  where a.Cedula == alumnoMaterium.Cedula
                                  select a).ToList();

            misActividades.AddRange(listMisClasesEvaluacion.Select(claseEvaluacion => repositorioActividad.GetById(claseEvaluacion.IdActividad)));

            var horarioDisponible = repositorioHorarioPreferencia.GetAll().
                        Where(hp => hp.Cedula == alumnoMaterium.Cedula &
                                    hp.Tipo.CompareTo("Definitivo") == 0).ToList();

            var miHorarioOcupado = (from a in misActividades
                                    where a.Cedula == alumnoMaterium.Cedula &
                                          a.HoraInicio.Date == miFecha.Date
                                    select a).ToList();

            foreach (var claseEvaluacion in listMisClasesEvaluacion)
            {
                var miActClase = repositorioActividad.GetById(claseEvaluacion.IdActividad);
                if (miActClase.HoraInicio.Date == miFecha.Date)
                {
                    miHorarioOcupado.Add(miActClase);
                }
            }

            //Elimino las horas ocupadas de HOY en el arreglo de disponibles
            foreach (var actividad in miHorarioOcupado)
            {
                DateTime horaFin = actividad.HoraFin.Minute > 0 ? actividad.HoraFin.AddHours(1) : actividad.HoraFin;
                for (int i = actividad.HoraInicio.Hour; i < horaFin.Hour; i++)
                {
                    var horaOcupada = (from hora in horarioDisponible
                                       where hora.HoraInicio.Hour == i
                                       select hora);
                    if (horaOcupada.Count() != 0)
                    {
                        horarioDisponible.Remove(horaOcupada.First());
                    }
                }
            }

            //Ordeno las horas disponibles segun su prioridad
            var miHorarioDisponible = (from horario in horarioDisponible
                                       orderby horario.Preferencia descending
                                       select horario).ToList();

            //Actualizo para c/hora disponible la fecha que voy a calendarizar
            foreach (var horarioPreferencia in miHorarioDisponible)
            {
                int horaIni = horarioPreferencia.HoraInicio.Hour;
                int horaFin = horarioPreferencia.HoraFin.Hour;
                horarioPreferencia.HoraInicio = new DateTime(miFecha.Year, miFecha.Month, miFecha.Day, horaIni, 0, 0);
                horarioPreferencia.HoraFin = new DateTime(miFecha.Year, miFecha.Month, miFecha.Day, horaFin, 0, 0);
            }

            //Calculo cuantas horas se calendarizaran
            var horaDiaria = Math.Ceiling(alumnoMaterium.HorasPersonales / diasEstudio);
            var horaDiariaReal = alumnoMaterium.HorasPersonales / diasEstudio;
            //Busco el mejor horario para calendarizar la actividad
            bool flag2;
            HorarioPreferencia preferenciaAux;
            double mayorPrioridad = 0;
            do
            {
                mayorPrioridad = miHorarioDisponible[0].Preferencia;
                var mayorPreferencia = new HorarioPreferencia();
                preferenciaAux = new HorarioPreferencia { MayorPreferencia = 0 };
                foreach (var horarioD in miHorarioDisponible)
                {
                    if (horarioD.Preferencia.CompareTo(mayorPrioridad) == 0)
                    {
                        mayorPreferencia.Cedula = horarioD.Cedula;
                        mayorPreferencia.HoraInicio = horarioD.HoraInicio;
                        mayorPreferencia.HoraFin = horarioD.HoraFin;
                        mayorPreferencia.Preferencia = horarioD.Preferencia;
                        mayorPreferencia.Tipo = horarioD.Tipo;
                        mayorPreferencia.IdPreferencia = horarioD.IdPreferencia;
                        mayorPreferencia.MayorPreferencia = horarioD.Preferencia;
                        for (int i = 1; i < horaDiaria; i++)
                        {
                            var horaBuscada = (from h in horarioDisponible
                                               where
                                                   h.HoraInicio.CompareTo(horarioD.HoraInicio.AddHours(i)) == 0
                                               select h);
                            if (horaBuscada.Count() != 0)
                            {
                                mayorPreferencia.MayorPreferencia += horaBuscada.First().Preferencia;
                            }
                            else
                            {
                                mayorPreferencia = new HorarioPreferencia();
                                break;
                            }
                        }
                        if (mayorPreferencia.Cedula != 0)
                        {
                            if (mayorPreferencia.MayorPreferencia > preferenciaAux.MayorPreferencia)
                            {
                                preferenciaAux.Cedula = mayorPreferencia.Cedula;
                                preferenciaAux.HoraInicio = mayorPreferencia.HoraInicio;
                                preferenciaAux.HoraFin = mayorPreferencia.HoraFin;
                                preferenciaAux.Preferencia = mayorPreferencia.Preferencia;
                                preferenciaAux.Tipo = mayorPreferencia.Tipo;
                                preferenciaAux.IdPreferencia = mayorPreferencia.IdPreferencia;
                                preferenciaAux.MayorPreferencia = mayorPreferencia.MayorPreferencia;
                            }
                        }
                    }
                }
                if (preferenciaAux.Cedula == 0)
                {
                    flag2 = true;
                    miHorarioDisponible.RemoveAt(0);
                }
                else
                {
                    flag2 = false;
                }
            } while (flag2 && miHorarioDisponible.Count != 0);

            //Si hay horario disponible se calendariza la actividad
            if (miHorarioDisponible.Count != 0)
            {
                var act = new Actividad
                {
                    HoraInicio = preferenciaAux.HoraInicio,
                    HoraFin = preferenciaAux.HoraInicio.AddHours(horaDiariaReal),
                    IdMateria = alumnoMaterium.IdMateria,
                    Nombre =
                        "Estudiar " +
                        repositorioMaterium.GetById(alumnoMaterium.IdMateria).Nombre,
                    Tipo = "Inteligente",
                    Periodo = periodoActual,
                    Cedula = alumnoMaterium.Cedula
                };
                repositorioActividad.Save(act);
                alumnoMaterium.HorasAcumuladas += horaDiariaReal;
                repositorioAlumnoMateria.Update(alumnoMaterium);
            }
        }
        private void Calendarizar(AlumnoMaterium alumnoMaterium, int diasEstudio)
        {
            var periodoActual = Helper.CalcularPeriodoActual();
            var fechaActual = DateTime.Now;
            IRepositorio<Materium> repositorioMaterium = new MateriumRepositorio();
            IRepositorio<Actividad> repositorioActividad = new ActividadRepositorio();
            IList<Actividad> listActividades = repositorioActividad.GetAll();

            IRepositorio<ClaseEvaluacion> repositorioClaseEvaluacion = new HorarioClaseRepositorio();
            var listMisClasesEvaluacion = repositorioClaseEvaluacion.GetAll().Where(cE => cE.Cedula == alumnoMaterium.Cedula).ToList();

            IRepositorio<SlMaterium> repositorioSlMateria = new SlMateriumRepositorio();
            IRepositorio<SlSeccion> repositorioSlSeccion = new SlSeccionRepositorio();

            var fechaIniSemestre = (from seccion in repositorioSlSeccion.GetAll()
                                        .Where(
                                            sec =>
                                            sec.IdMateria ==
                                            repositorioSlMateria.GetAll().Where(
                                                mat =>
                                                mat.Nombre.CompareTo(
                                                    repositorioMaterium.GetById(alumnoMaterium.IdMateria).Nombre) == 0).First()
                                                .IdMateria)
                                    where seccion.Periodo.CompareTo(Convert.ToInt32(periodoActual)) == 0
                                    select seccion.InicioSem).First();

            bool flag = true;
            //if (_fechaActual < fechaIniSemestre.AddDays(5))
            //{

            //    var misActividadesFechaActual = new List<Actividad>();
            //    foreach (var claseEvaluacion in listMisClasesEvaluacion)
            //    {
            //        var miActClase = repositorioActividad.GetById(claseEvaluacion.IdActividad);
            //        if (miActClase.Tipo.CompareTo("Clase") == 0 &&
            //            miActClase.HoraInicio.Date < _fechaActual.Date &&
            //            miActClase.IdMateria == alumnoMaterium.IdMateria)
            //        {
            //            misActividadesFechaActual.Add(miActClase);
            //        }
            //    }

            //    if (misActividadesFechaActual.Count > 0)
            //    {
            //        flag = false;
            //    }
            //}
            if (flag)
            {
                //OJO: VACACIONES
                var semanasRestantes = (16 - Math.Round((double)((fechaActual - fechaIniSemestre).Days / 7.0)));
                double horasAjustadas = alumnoMaterium.HorasPersonales * semanasRestantes;

                var miFecha = fechaActual.AddDays(1);
                var horasTotales = alumnoMaterium.HorasAcumuladas + horasAjustadas;
                while (alumnoMaterium.HorasAcumuladas < horasTotales)
                {
                    if (diasEstudio < 7)
                    {
                        var misActividadesSemana = (from a in listActividades
                                                    where a.Cedula == alumnoMaterium.Cedula &&
                                                          a.HoraInicio.Date < miFecha.AddDays(7).Date &&
                                                          a.HoraInicio.Date >= miFecha.Date
                                                    select a).ToList();

                        foreach (var claseEvaluacion in listMisClasesEvaluacion)
                        {
                            var miActClase = repositorioActividad.GetById(claseEvaluacion.IdActividad);
                            if (miActClase.HoraInicio.Date < miFecha.AddDays(7).Date &&
                                miActClase.HoraInicio.Date >= miFecha.Date)
                            {
                                misActividadesSemana.Add(miActClase);
                            }
                        }

                        var horasOcupadas = new double[7];
                        for (int i = 0; i < 7; i++)
                        {
                            foreach (var actividad in misActividadesSemana)
                            {
                                if (actividad.HoraInicio.Date == miFecha.AddDays(i).Date)
                                {
                                    horasOcupadas[i] += (actividad.HoraFin - actividad.HoraInicio).Hours;
                                }
                            }
                        }

                        var mejoresDias = new List<DateTime>();
                        double aux = 9999;
                        int dia = 0;
                        for (int i = 0; i < diasEstudio; i++)
                        {
                            for (int j = 0; j < 7; j++)
                            {
                                if (horasOcupadas[j] < aux)
                                {
                                    aux = horasOcupadas[j];
                                    dia = j;
                                }
                            }
                            horasOcupadas[dia] = 9999;
                            mejoresDias.Add(miFecha.AddDays(dia));
                            aux = 9999;
                            dia = 0;
                        }

                        foreach (var mejorDia in mejoresDias)
                        {
                            GuardarActMejorHorario(mejorDia, alumnoMaterium, diasEstudio);
                        }

                        miFecha = miFecha.AddDays(7);
                    }
                    else
                    {
                        miFecha = miFecha.AddDays(1);
                        GuardarActMejorHorario(miFecha, alumnoMaterium, diasEstudio);
                    }
                }
            }
        }
        public ActionResult Edit(AlumnoMaterium recordacademico, int id, FormCollection collection)
        {
            if(ModelState.IsValid)
            {
                IRepositorio<AlumnoMaterium> myRepoRecordacademico = new AlumnoMateriumRepositorio();
                //recordacademico.IdRecord = id; OJO HAY Q ACOMODARLO, el ID es compuesto.
                String resultado = myRepoRecordacademico.Update(recordacademico);

                if (resultado.Equals("true"))
                return RedirectToAction("Index");
            }
            return View(recordacademico);
        }