/// <summary>
 /// Graba un registro en la Base de datos en la Tabla Clima.
 /// Realiza trace del estado de los planetas en ese momento (Si es que esta habilitada el trace en archivo de configuración).
 /// </summary>
 /// <param name="unitOfWork"></param>
 /// <param name="diaAbsoluto"></param>
 /// <param name="enumTipoClima"></param>
 private void GrabarClima(UOWClimaSistemaSolar unitOfWork, int diaAbsoluto, TipoClima.enumTipoClima enumTipoClima)
 {
     unitOfWork.ClimaRepository.Create(new Clima()
     {
         dia = diaAbsoluto, enumTipoClima = enumTipoClima
     });
     unitOfWork.Commit();
     TraceEstadoPlanetas(diaAbsoluto, enumTipoClima);
 }
 /// <summary>
 /// Incrementa el Contador de Periodos.
 /// Graba un registro en la Base de datos en la Tabla Clima.
 /// Realiza trace del estado de los planetas en ese momento (Si es que esta habilitada el trace en archivo de configuración).
 /// </summary>
 /// <param name="diaAbsoluto"></param>
 /// <param name="enumTipoClima"></param>
 /// <param name="dicContPeriodos"></param>
 /// <param name="unitOfWork"></param>
 /// <param name="blInicioEpocaLluvia"></param>
 private void IncrementaContadorPeriodosGrabaClima(int diaAbsoluto,
                                                   TipoClima.enumTipoClima enumTipoClima,
                                                   Dictionary <TipoClima.enumTipoClima, int> dicContPeriodos,
                                                   UOWClimaSistemaSolar unitOfWork,
                                                   ref bool blInicioEpocaLluvia)
 {
     dicContPeriodos[enumTipoClima]++;
     blInicioEpocaLluvia = false;
     GrabarClima(unitOfWork, diaAbsoluto, enumTipoClima);
 }
 /// <summary>
 /// Hace un Update del registro que pertence al dia con el Pico máximo de lluvia.
 /// </summary>
 /// <param name="unitOfWork"></param>
 /// <param name="iDiaPicoMaximoLluvia"></param>
 private static void GrabaPicoMaximoLluvia(UOWClimaSistemaSolar unitOfWork, int iDiaPicoMaximoLluvia)
 {
     if (iDiaPicoMaximoLluvia > 0)
     {
         unitOfWork.ClimaRepository.Update(new Clima()
         {
             Id = iDiaPicoMaximoLluvia, enumTipoClima = TipoClima.enumTipoClima.LluviaPicoMaximo
         });
         unitOfWork.Commit();
     }
 }
        /// <summary>
        /// Ejecuta la simulación del clima durante los años ingresados por parametro (Deafault = 10 años).
        /// Almacena en base de datos la informacion diaria sólo de los siguientes tipos de clima:
        /// -sequía.
        /// -lluvia.
        /// -pico máximo de lluvia (dia puntual).
        /// -condiciones óptimas.
        /// Emite un reporte de la cantidad de de periodos de cada uno de los períodos
        /// y el día que será el pico máximo de lluvia
        /// </summary>
        /// <returns></returns>
        public string SimulacionClima()
        {
            string strMetodo = "SimulacionClima"; //No se utiliza reflection para obtener nombre de metodo para mejorar performance

            Logger.TraceStart(strMetodo);
            Dictionary <TipoClima.enumTipoClima, int> dicContPeriodos = InicializarContadorPeriodos();
            //Alamacena el dia del perimetro maximo formado por los planetas que tambien es el de pico maximo de lluvia.
            int iDiaPerimetroMaximo = 0;

            using (UOWClimaSistemaSolar unitOfWork = new UOWClimaSistemaSolar())
            {
                if (TablaClimaVacia(unitOfWork))
                {
                    string strMsg = "Datos existentes. La simulación no se ejecutará. Primero se deben borrar los datos. Ejecute api/clima/DeleteAll.";
                    Logger.Trace(TraceEventType.Warning, strMsg);
                    return(strMsg);
                }

                //Flag que controla inicio de epocas de lluvia para que el contador cuente las temporadas (conjunto de varios dias juntos) y no que cuente los dias de lluvia.
                bool blInicioEpocaLluvia = false;
                //Variables que almacenan el maximo perimetro del triangulo formado por los planetas y el dia que sucede
                //Para determinar el dia de Pico máximo de Lluvia.
                double dblPerimetroMaximo = 0;

                //Se separo en 2 for por si a futuro se quiere realizar algun procedimiento que se ejecute para cada año.
                for (int anio = 1; anio <= Constants.ANIOS; anio++)
                {
                    for (int dia = 1; dia <= 360; dia++)
                    {
                        ProcesarDia(dicContPeriodos, ref iDiaPerimetroMaximo, unitOfWork, ref blInicioEpocaLluvia, ref dblPerimetroMaximo, anio, dia);
                    }
                }
                GrabaPicoMaximoLluvia(unitOfWork, iDiaPerimetroMaximo);
            }

            Logger.TraceStop(strMetodo);
            return(ReportePeriodos(dicContPeriodos, iDiaPerimetroMaximo));
        }
 /// <summary>
 /// Verifica si exiten datos en la tabla Clima.
 /// </summary>
 /// <param name="unitOfWork"></param>
 /// <returns></returns>
 private bool TablaClimaVacia(UOWClimaSistemaSolar unitOfWork)
 {
     return(unitOfWork.ClimaRepository.RetrieveQueryable().Count() > 0);
 }
        private void ProcesarDia(Dictionary <TipoClima.enumTipoClima, int> dicContPeriodos, ref int iDiaPerimetroMaximo, UOWClimaSistemaSolar unitOfWork, ref bool blInicioEpocaLluvia, ref double dblPerimetroMaximo, int anio, int dia)
        {
            int diaAbsoluto = dia + ((anio - 1) * 360);

            if (EsSequia())
            {
                IncrementaContadorPeriodosGrabaClima(diaAbsoluto, TipoClima.enumTipoClima.Sequia, dicContPeriodos, unitOfWork, ref blInicioEpocaLluvia);
            }
            else if (EsOptima())
            {
                IncrementaContadorPeriodosGrabaClima(diaAbsoluto, TipoClima.enumTipoClima.Optimo, dicContPeriodos, unitOfWork, ref blInicioEpocaLluvia);
            }
            else if (EsLluvia())
            {
                if (!blInicioEpocaLluvia)
                {
                    dicContPeriodos[TipoClima.enumTipoClima.Lluvia]++;
                    blInicioEpocaLluvia = true;
                }
                GrabarClima(unitOfWork, diaAbsoluto, TipoClima.enumTipoClima.Lluvia);
                DiaPicoMaximoLluvia(diaAbsoluto, ref iDiaPerimetroMaximo, ref dblPerimetroMaximo);
            }
            else
            {
                blInicioEpocaLluvia = false;
            }

            CalcularNuevaPosicionPlanetas();
        }