import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_fonts/google_fonts.dart';

import '../pages/resultado.dart';
import '../models/info_calculadora.dart';
import '../providers/info_calculadora_provider.dart';

import 'dart:math' as math;

class CalculadoraPage extends StatefulWidget {
  const CalculadoraPage({Key? key}) : super(key: key);

  @override
  State<CalculadoraPage> createState() => _CalculadoraPageState();
}

class _CalculadoraPageState extends State<CalculadoraPage> {
  final _infoCalculadoraProvider = InfoCalculadoraProvider();
  final _caudalController = TextEditingController();
  final _presionController = TextEditingController();
  final _potenciaController = TextEditingController();
  final _diametroController = TextEditingController();
  late String _tipoVentilador;
  late String _modeloVentilador;
  late String _caudal;
  late String _presionEstatica;
  late String _potenciaAbsorbida;
  late String _diametroVentilador;
  late String _curvaNC;
  bool _isLoading = true;
  late List<Atenuacion> _atenuacion;
  late List<PotenciaSonora> _potenciaSonora;
  final List<String> _caudalUnidades = [
    'M3/S','M3/MIN','M3/H','L/S','L/MIN','L/H','CM3/S','CM3/MIN','CM3/H',
    'GALON/S','GALON/MIN','GALON/H','CFM'
  ];
  final List<String> _presionUnidades = [
    'MPA','KPA','PA','BAR','M CA','CM A','MM CA','IN HG','CM HG','MM HG',
    'TORR','INWG'
  ];
  final List<String> _potenciaUnidades = [
    'HP','J/S','KCAL/H','KW','WATT','PIE-LIBRA(S)','PIE-LIBRA(M)','BHP'
  ];
  final List<String> _diametroUnidades = [
    'MM','CM','DM','M','MI','YARDA','INCH','FT'
  ];
  final List<String> _curvas = [
    'NC15','NC20','NC25','NC30','NC35','NC40','NC45','NC50','NC55','NC60',
    'NC65','NC70'
  ];
  late List<String> _ventiladoresTipos;
  late List<Ventilador> _ventiladores;
  final Map<String, List<String>> _ventiladoresModelos = {
    'Seleccione un tipo de  ventilador...' : ['']
  };

  @override
  void initState() {
    super.initState();

    _infoCalculadoraProvider.fetchInfoCalculadora().then((infoCalculadora){
      _ventiladoresTipos = [];
      _ventiladoresTipos.add('Seleccione un tipo de  ventilador...');
      _ventiladores = infoCalculadora.result!.ventiladores!;

      if(infoCalculadora.result!.ventiladoresTipos!.isNotEmpty){
        int i = 0;
        do{
          _ventiladoresTipos.add(infoCalculadora.result!.ventiladoresTipos![i]);
          i++;
        }while(i < infoCalculadora.result!.ventiladoresTipos!.length);
      }else{
        _errorCarga('Hubo un error al cargar el Catálogo de ventiladores');
      }

      if(infoCalculadora.result!.ventiladoresModelos!.isNotEmpty){
        int i = 0;
        do{
          _ventiladoresModelos[infoCalculadora.result!.ventiladoresTipos![i]] = infoCalculadora.result!.ventiladoresModelos![i];
          i++;
        }while(i < infoCalculadora.result!.ventiladoresModelos!.length);
      }else{
        _errorCarga('Hubo un error al cargar los Modelos de ventiladores');
      }

      _atenuacion = infoCalculadora.result!.atenuacion!;
      _potenciaSonora = infoCalculadora.result!.potenciaSonora!;

      _initVariables();
    });
  }

  void _initVariables(){
    setState(() {
      _tipoVentilador = _ventiladoresTipos[0];
      _modeloVentilador = _ventiladoresModelos[_tipoVentilador]![0];
      _caudal = _caudalUnidades.last;
      _presionEstatica = _presionUnidades.last;
      _potenciaAbsorbida = _potenciaUnidades.last;
      _diametroVentilador = _diametroUnidades.last;
      _curvaNC = _curvas[0];

      _isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    final _screenSize = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(),
      body: _isLoading ? const Center(
        child: CircularProgressIndicator(),
      ) : SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Container(
                margin: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                width: _screenSize.width,
                child: Text(
                  'Tipo de Ventilador *',
                  textAlign: TextAlign.start,
                  style: GoogleFonts.roboto(
                      color: const Color(0xFF333333),
                      fontWeight: FontWeight.w700,
                      fontSize: 20.0
                  ),
                ),
              ),
              Container(
                decoration: BoxDecoration(
                    border: Border.all(
                        color: const Color(0xFFBBBBBB)
                    ),
                    borderRadius: BorderRadius.circular(8.0)
                ),
                padding: const EdgeInsets.symmetric(horizontal: 16),
                child: DropdownButton<String>(
                  value: _tipoVentilador,
                  elevation: 16,
                  underline: Container(
                    height: 0,
                    color: const Color(0x00000000),
                  ),
                  onChanged: (value){
                    setState(() {
                      _tipoVentilador = value!;
                      _modeloVentilador = _ventiladoresModelos[value]![0];
                    });
                  },
                  items: _ventiladoresTipos.map<DropdownMenuItem<String>>((value){
                    return DropdownMenuItem<String>(
                      value: value,
                      child: SizedBox(
                        width: _screenSize.width-122.0,
                        child: Text(
                          value,
                          textAlign: TextAlign.start,
                          style: GoogleFonts.roboto(
                              color: Colors.black
                          ),
                        ),
                      ),
                    );
                  }).toList(),
                ),
              ),
              Container(
                margin: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                width: _screenSize.width,
                child: Text(
                  'Modelo de Ventilador *',
                  style: GoogleFonts.roboto(
                      color: const Color(0xFF333333),
                      fontWeight: FontWeight.w700,
                      fontSize: 20.0
                  ),
                ),
              ),
              Container(
                decoration: BoxDecoration(
                    border: Border.all(
                        color: const Color(0xFFBBBBBB)
                    ),
                    borderRadius: BorderRadius.circular(8.0)
                ),
                padding: const EdgeInsets.symmetric(horizontal: 16),
                child: DropdownButton<String>(
                  value: _modeloVentilador,
                  underline: Container(
                    height: 0,
                    color: const Color(0x00000000),
                  ),
                  elevation: 16,
                  onChanged: (value){
                    setState(() {
                      _modeloVentilador = value!;
                    });
                  },
                  items: _ventiladoresModelos[_tipoVentilador]!.map<DropdownMenuItem<String>>((value){
                    return DropdownMenuItem<String>(
                      value: value,
                      child: SizedBox(
                        width: _screenSize.width-122.0,
                        child: Text(
                          value,
                          textAlign: TextAlign.start,
                          style: GoogleFonts.roboto(
                              color: Colors.black
                          ),
                        ),
                      ),
                    );
                  }).toList(),
                ),
              ),
              Container(
                margin: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                width: _screenSize.width,
                child: Text(
                  'Caudal (Q) *',
                  style: GoogleFonts.roboto(
                      color: const Color(0xFF333333),
                      fontWeight: FontWeight.w700,
                      fontSize: 20.0
                  ),
                ),
              ),
              Row(
                children: [
                  const SizedBox(width: 32.0),
                  Expanded(
                    child: Container(
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: const Color(0xFFBBBBBB)
                          ),
                          borderRadius: BorderRadius.circular(8.0)
                      ),
                      padding: const EdgeInsets.symmetric(horizontal: 16),
                      child: TextField(
                        controller: _caudalController,
                        keyboardType: TextInputType.number,
                        decoration: const InputDecoration(
                          border: InputBorder.none,
                        ),
                      ),
                    ),
                  ),
                  const SizedBox(width: 16.0),
                  Container(
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: const Color(0xFFBBBBBB)
                        ),
                        borderRadius: BorderRadius.circular(8.0)
                    ),
                    padding: const EdgeInsets.symmetric(horizontal: 16),
                    child: DropdownButton<String>(
                      value: _caudal,
                      elevation: 16,
                      style: GoogleFonts.roboto(
                          color: Colors.black
                      ),
                      underline: Container(
                        height: 0,
                        color: const Color(0x00000000),
                      ),
                      onChanged: (value){
                        setState(() {
                          _caudal = value!;
                        });
                      },
                      items: _caudalUnidades.map<DropdownMenuItem<String>>((value){
                        return DropdownMenuItem<String>(
                          value: value,
                          child: Text(
                              value
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                  const SizedBox(width: 32.0)
                ],
              ),
              Container(
                margin: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                width: _screenSize.width,
                child: Text(
                  'Presión Estática (P) *',
                  style: GoogleFonts.roboto(
                      color: const Color(0xFF333333),
                      fontWeight: FontWeight.w700,
                      fontSize: 20.0
                  ),
                ),
              ),
              Row(
                children: [
                  const SizedBox(width: 32.0),
                  Expanded(
                    child: Container(
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: const Color(0xFFBBBBBB)
                          ),
                          borderRadius: BorderRadius.circular(8.0)
                      ),
                      padding: const EdgeInsets.symmetric(horizontal: 16),
                      child: TextField(
                        controller: _presionController,
                        keyboardType: TextInputType.number,
                        decoration: InputDecoration(
                          border: InputBorder.none,
                        ),
                      ),
                    ),
                  ),
                  SizedBox(width: 16.0),
                  Container(
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: Color(0xFFBBBBBB)
                        ),
                        borderRadius: BorderRadius.circular(8.0)
                    ),
                    padding: EdgeInsets.symmetric(horizontal: 16),
                    child: DropdownButton<String>(
                      value: _presionEstatica,
                      elevation: 16,
                      style: GoogleFonts.roboto(
                          color: Colors.black
                      ),
                      underline: Container(
                        height: 0,
                        color: Color(0x00000000),
                      ),
                      onChanged: (value){
                        setState(() {
                          _presionEstatica = value!;
                        });
                      },
                      items: _presionUnidades.map<DropdownMenuItem<String>>((value){
                        return DropdownMenuItem<String>(
                          value: value,
                          child: Text(
                              value
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                  SizedBox(width: 32.0)
                ],
              ),
              Container(
                margin: EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                width: _screenSize.width,
                child: Text(
                  'Potencia Absorbida (Bhp) *',
                  style: GoogleFonts.roboto(
                      color: Color(0xFF333333),
                      fontWeight: FontWeight.w700,
                      fontSize: 20.0
                  ),
                ),
              ),
              Row(
                children: [
                  SizedBox(width: 32.0),
                  Expanded(
                    child: Container(
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: Color(0xFFBBBBBB)
                          ),
                          borderRadius: BorderRadius.circular(8.0)
                      ),
                      padding: EdgeInsets.symmetric(horizontal: 16),
                      child: TextField(
                        controller: _potenciaController,
                        keyboardType: TextInputType.number,
                        decoration: InputDecoration(
                          border: InputBorder.none,
                        ),
                      ),
                    ),
                  ),
                  SizedBox(width: 16.0),
                  Container(
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: Color(0xFFBBBBBB)
                        ),
                        borderRadius: BorderRadius.circular(8.0)
                    ),
                    padding: EdgeInsets.symmetric(horizontal: 16),
                    child: DropdownButton<String>(
                      value: _potenciaAbsorbida,
                      elevation: 16,
                      style: GoogleFonts.roboto(
                          color: Colors.black
                      ),
                      underline: Container(
                        height: 0,
                        color: Color(0x00000000),
                      ),
                      onChanged: (value){
                        setState(() {
                          _potenciaAbsorbida = value!;
                        });
                      },
                      items: _potenciaUnidades.map<DropdownMenuItem<String>>((value){
                        return DropdownMenuItem<String>(
                          value: value,
                          child: Text(
                              value
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                  SizedBox(width: 32.0)
                ],
              ),
              Container(
                margin: EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                width: _screenSize.width,
                child: Text(
                  'Diámetro del Ventilador *',
                  style: GoogleFonts.roboto(
                      color: Color(0xFF333333),
                      fontWeight: FontWeight.w700,
                      fontSize: 20.0
                  ),
                ),
              ),
              Row(
                children: [
                  SizedBox(width: 32.0),
                  Expanded(
                    child: Container(
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: Color(0xFFBBBBBB)
                          ),
                          borderRadius: BorderRadius.circular(8.0)
                      ),
                      padding: EdgeInsets.symmetric(horizontal: 16),
                      child: TextField(
                        controller: _diametroController,
                        keyboardType: TextInputType.number,
                        decoration: InputDecoration(
                          border: InputBorder.none,
                        ),
                      ),
                    ),
                  ),
                  SizedBox(width: 16.0),
                  Container(
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: Color(0xFFBBBBBB)
                        ),
                        borderRadius: BorderRadius.circular(8.0)
                    ),
                    padding: EdgeInsets.symmetric(horizontal: 16),
                    child: DropdownButton<String>(
                      value: _diametroVentilador,
                      elevation: 16,
                      style: GoogleFonts.roboto(
                          color: Colors.black
                      ),
                      underline: Container(
                        height: 0,
                        color: Color(0x00000000),
                      ),
                      onChanged: (value){
                        setState(() {
                          _diametroVentilador = value!;
                        });
                      },
                      items: _diametroUnidades.map<DropdownMenuItem<String>>((value){
                        return DropdownMenuItem<String>(
                          value: value,
                          child: Text(
                              value
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                  SizedBox(width: 32.0)
                ],
              ),
              Container(
                margin: EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                width: _screenSize.width,
                child: Text(
                  'Curva NC *',
                  textAlign: TextAlign.start,
                  style: GoogleFonts.roboto(
                      color: Color(0xFF333333),
                      fontWeight: FontWeight.w700,
                      fontSize: 20.0
                  ),
                ),
              ),
              Container(
                decoration: BoxDecoration(
                    border: Border.all(
                        color: Color(0xFFBBBBBB)
                    ),
                    borderRadius: BorderRadius.circular(8.0)
                ),
                padding: EdgeInsets.symmetric(horizontal: 16),
                child: DropdownButton<String>(
                  value: _curvaNC,
                  elevation: 16,
                  underline: Container(
                    height: 0,
                    color: Color(0x00000000),
                  ),
                  onChanged: (value){
                    setState(() {
                      _curvaNC = value!;
                    });
                  },
                  items: _curvas.map<DropdownMenuItem<String>>((value){
                    return DropdownMenuItem<String>(
                      value: value,
                      child: Container(
                        width: _screenSize.width-122.0,
                        child: Text(
                          value,
                          textAlign: TextAlign.start,
                          style: GoogleFonts.roboto(
                              color: Colors.black
                          ),
                        ),
                      ),
                    );
                  }).toList(),
                ),
              ),
              const SizedBox(height: 32.0),
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(50.0)
                    ),
                    primary: Color(0xFFEA2C13),
                    padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0),
                    elevation: 0.0
                ),
                child: Text(
                  'Calcular',
                  style: GoogleFonts.roboto(
                    color: Colors.white,
                    fontSize: 20.0,
                  ),
                ),
                onPressed: _validaCampos,
              ),
              SizedBox(height: 32.0),
            ],
          ),
        ),
      ),
    );
  }

  void _validaCampos(){
    bool valido;
    int presicionDecimales = 8;
    Map<String, String> arrDatosCalculos = Map<String, String>();
    String tipoVentilador = _tipoVentilador;
    String modeloVentilador = _modeloVentilador;

    if(_ventiladoresTipos.indexOf(_tipoVentilador) < 1){
      _buildAlert('Tipo Ventilador');
      valido = false;
      return null;
    }

    if(_caudalController.text.isEmpty){
      _buildAlert('Caudal (Q)');
      valido = false;
      return null;
    }

    if(_presionController.text.isEmpty){
      _buildAlert('Presión Estatíca (P)');
      valido = false;
      return null;
    }

    if(_potenciaController.text.isEmpty){
      _buildAlert('Potencia Absorbida (Bhp)');
      valido = false;
      return null;
    }

    if(_diametroController.text.isEmpty){
      _buildAlert('Diametro del Ventilador');
      valido = false;
      return null;
    }

    double vCaudal = double.parse(double.parse(_caudalController.text).toStringAsFixed(presicionDecimales));
    double vPresEs = double.parse(double.parse(_presionController.text).toStringAsFixed(presicionDecimales));
    double vPoteAb = double.parse(double.parse(_potenciaController.text).toStringAsFixed(presicionDecimales));
    double vDiaVen = double.parse(double.parse(_diametroController.text).toStringAsFixed(presicionDecimales));

    arrDatosCalculos['VCAUDAL'] = '$vCaudal || $_caudal || CAUDAL';
    arrDatosCalculos['VPREE'] = '$vPresEs || $_presionEstatica || PRE';
    arrDatosCalculos['VPOTE'] = '$vPoteAb || $_potenciaAbsorbida || POTE';
    arrDatosCalculos['DIAME'] = '$vDiaVen || $_diametroVentilador || DIAME';

    valido = true;

    if(valido){
      _realizarCalculos(tipoVentilador, modeloVentilador, arrDatosCalculos, _curvaNC);
    }
  }

  void _buildAlert(String campo){
    showDialog(
        context: context,
        barrierDismissible: true,
        builder: (context) => AlertDialog(
          title: Text(
            'Datos de Entrada Incompletos',
          ),
          content: Text(
              'El campo <<$campo>> es un dato Requerido.'
          ),
          actions: [
            TextButton(
              child: Text(
                  'Continuar'
              ),
              onPressed: () => Navigator.of(context).pop(),
            )
          ],
        )
    );
  }

  double _log10(double num){
    return math.log(num)/math.ln10;
  }

  void _realizarCalculos(String tipo, String modelo, Map<String, String> datos, String curva){
    if(_atenuacion.isEmpty){
      _errorCarga('Hubo un error al cargar el Catálogo de Atenuadores');
    }else if(_potenciaSonora.isEmpty){
      _errorCarga('Hubo un error al cargar las Potencias Sonoras');
    }

    double vCaudal = 0.0;
    double vPresionE = 0.0;
    double vPotenciaA = 0.0;
    double vDiametro = 0.0;
    int presicionDecimales = 8;

    Map<String, String> arrDatosDeEntrada = Map<String, String>();
    Map<String, String> arrConversiones = Map<String, String>();

    List<String> arrFrecuencias = ["63Hz","125Hz","250Hz","500Hz","1000Hz","2000Hz","4000Hz","8000Hz"];
    List<double> arrPonderanciaA = [-26.2,-16.1,-8.6,-3.2,0.0,1.2,1.0,-1.1];

    arrDatosDeEntrada['TipoVentilador'] = tipo;
    arrDatosDeEntrada['ModeloVentilador'] = modelo;

    _ventiladores.forEach((element) {
      if(element.idmodelo == modelo){
        arrDatosDeEntrada['ModeloVentilador'] = element.idmodelo!;
      }
    });

    datos.forEach((key, value) {
      var splitDatos = value.split('||');
      var valorCampo = double.parse(splitDatos[0].trim());
      var unidadDeMedida = splitDatos[1].trim();
      var campoDato = splitDatos[2].trim();

      if ( campoDato == "CAUDAL" ) {
        arrDatosDeEntrada['Caudal'] = "$valorCampo $unidadDeMedida";

        switch ( unidadDeMedida ) { // Conversiones para la Caudal
          case 'M3/S':
            vCaudal = valorCampo / 0.0004719;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 0.028314 M3/S ) X 1 CFM = $presicion CFM";
            break;
          case 'M3/MIN':
            vCaudal = valorCampo / 0.028314;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 0.028314 M3/MIN ) X 1 CFM = $presicion CFM";
            break;
          case 'M3/H':
            vCaudal = valorCampo / 1.699011;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 0.699011 M3/H ) X 1 CFM = $presicion CFM";
            break;
          case 'L/S':
            vCaudal = valorCampo * 2.119;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida  X 2.119 L/S ) X 1 CFM = $presicion CFM";
            break;
          case 'L/MIN':
            vCaudal = valorCampo / 28.32;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 28.32 L/MIN ) X 1 CFM = $presicion CFM";
            break;
          case 'L/H':
            vCaudal = valorCampo / 1699;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 1699 L/H ) X 1 CFM = $presicion CFM";
            break;
          case 'CM3/S':
            vCaudal = valorCampo / 471.9;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 471.9 CM3/S ) X 1 CFM = $presicion CFM";
            arrConversiones[unidadDeMedida] = "$valorCampo / 471.9 = $vCaudal";
            break;
          case 'CM3/MIN':
            vCaudal = valorCampo / 28314;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 278314 CM3/MIN ) X 1 CFM = $presicion CFM";
            break;
          case 'CM3/H':
            vCaudal = valorCampo / 1698840;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 1698840 CM3/H ) X 1 CFM = $presicion CFM";
            break;
          case 'GALON/S':
            vCaudal = valorCampo / 0.12467532;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 0.12467532 GALON/S) X 1 CFM = $presicion CFM";
            break;
          case 'GALON/MIN':
            vCaudal = valorCampo / 7.4805195566834;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 7.4805195566834 GALON/MIN ) X 1 CFM = $presicion CFM";
            break;
          case 'GALON/H':
            vCaudal = valorCampo / 448.8311734;
            var presicion = _precisarDecimales( presicionDecimales, vCaudal );
            arrConversiones['Caudal'] = "( $valorCampo $unidadDeMedida / 448.8311734 GALON/H ) X 1 CFM = $presicion CFM";
            break;
          case 'CFM':
            vCaudal = valorCampo;
            break;
        }

        vCaudal = double.parse(vCaudal.toStringAsFixed(presicionDecimales));

      }

      if ( campoDato == "PRE" ) {
        arrDatosDeEntrada['PresionEstatica'] = "$valorCampo $unidadDeMedida";

        switch ( unidadDeMedida ) { // Conversiones para la Presión Estatíca
          case 'MPA':
            vPresionE = valorCampo * 401.47;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 401.47 MPA ) X 1 INWG = $presicion INWG";
            break;
          case 'KPA':
            vPresionE = valorCampo * 4.0147;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 4.0147 KPA ) X 1 INWG = $presicion INWG";
            break;
          case 'PA':
            vPresionE = valorCampo * 0.0040147;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 0.0040147 PA ) X 1 INWG = $presicion INWG";
            break;
          case 'BAR':
            vPresionE = valorCampo * 401.865;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 401.865 BAR ) X 1 INWG = $presicion INWG";
            break;
          case 'M CA':
            vPresionE = valorCampo * 39.166667;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 39.166667 ) X 1 INWG = $presicion INWG";
            break;
          case 'CM CA':
            vPresionE = valorCampo * 0.39166667;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 0.39166667 CM CA ) X 1 INWG = $presicion INWG";
            break;
          case 'MM CA':
            vPresionE = valorCampo * 0.039166667;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 0.039166667 MM CA ) X 1 INWG = $presicion INWG";
            break;
          case 'IN HG':
            vPresionE = valorCampo / 0.0735541043;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 0.0735541043 ) X 1 INWG = $presicion INWG";
            break;
          case 'CM HG':
            vPresionE = valorCampo / 0.18682743044;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 0.18682743044 CM HG ) X 1 INWG = $presicion INWG";
            break;
          case 'MM HG':
            vPresionE = valorCampo / 0.018682743044;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 0.018682743044 MM HG ) X 1 INWG = $presicion INWG";
            break;
          case 'TORR':
            vPresionE = valorCampo * 0.5352533071;
            var presicion = _precisarDecimales( presicionDecimales, vPresionE );
            arrConversiones['Presion Estatica'] = "( $valorCampo $unidadDeMedida X 0.5352533071 TORR ) X 1 INWG = $presicion INWG";
            break;
          case 'INWG':
            vPresionE = valorCampo;
            break;
        }

        vPresionE = double.parse(vPresionE.toStringAsFixed(presicionDecimales));

      }

      if ( campoDato == "POTE" ) {
        arrDatosDeEntrada['PotenciaAbsorbida'] = "$valorCampo $unidadDeMedida";

        switch ( unidadDeMedida ) { // Conversiones para la Potencia Absorbida
          case 'HP':
            vPotenciaA = valorCampo / 13.1549;
            var presicion = _precisarDecimales( presicionDecimales, vPotenciaA );
            arrConversiones['Potencia Absorbida'] = "( $valorCampo $unidadDeMedida / 13.1549 HP ) X 1 BHP = $presicion BHP";
            break;
          case 'J/S':
            vPotenciaA = valorCampo / 9809.5;
            var presicion = _precisarDecimales( presicionDecimales, vPotenciaA );
            arrConversiones['Potencia Absorbida'] = "( $valorCampo $unidadDeMedida / 9809.5 J/S ) X 1 BHP = $presicion BHP";
            break;
          case 'KCAL/H':
            vPotenciaA = valorCampo / 8434.65;
            var presicion = _precisarDecimales( presicionDecimales, vPotenciaA );
            arrConversiones['Potencia Absorbida'] = "( $valorCampo $unidadDeMedida / 8434.65 KCAL ) X 1 BHP = $presicion BHP";
            break;
          case 'KW':
            vPotenciaA = valorCampo / 9.8095;
            var presicion = _precisarDecimales( presicionDecimales, vPotenciaA );
            arrConversiones['Potencia Absorbida'] = "( $valorCampo $unidadDeMedida / 8434.65 KW ) X 1 BHP = $presicion BHP";
            break;
          case 'WATT':
            vPotenciaA = valorCampo / 9809.5;
            var presicion = _precisarDecimales( presicionDecimales, vPotenciaA );
            arrConversiones['Potencia Absorbida'] = "( $valorCampo $unidadDeMedida / 8434.65 WATT ) X 1 BHP = $presicion BHP";
            break;
          case 'PIE-LIBRA(S)':
            vPotenciaA = valorCampo / 7235.12;
            var presicion = _precisarDecimales( presicionDecimales, vPotenciaA );
            arrConversiones['Potencia Absorbida'] = "( $valorCampo $unidadDeMedida / 8434.65 PIE-LIBRA(S) ) X 1 BHP = $presicion BHP";
            break;
          case 'PIE-LIBRA(M)':
            vPotenciaA = valorCampo / 434106.95;
            var presicion = _precisarDecimales( presicionDecimales, vPotenciaA );
            arrConversiones['Potencia Absorbida'] = "( $valorCampo $unidadDeMedida / 8434.65 PIE-LIBRA(M) ) X 1 BHP = $presicion BHP";
            break;
          case 'BHP':
            vPotenciaA = valorCampo;
            break;
        }

        vPotenciaA = double.parse(vPotenciaA.toStringAsFixed(presicionDecimales));

      }

      if ( campoDato == "DIAME" ) {
        arrDatosDeEntrada['Diametro'] = "$valorCampo $unidadDeMedida";

        switch ( unidadDeMedida ) { // Conversiones para el Diametro
          case 'MM':
            vDiametro = (valorCampo * 3.291) / 1000;
            var presicion = _precisarDecimales( presicionDecimales, vDiametro );
            arrConversiones['Diametro'] = "() ( $valorCampo $unidadDeMedida X 3.291 MM ) / 1000 ) X 1 FT = $presicion FT";
            break;
          case 'CM':
            vDiametro = (valorCampo * 3.291) / 100;
            var presicion = _precisarDecimales( presicionDecimales, vDiametro );
            arrConversiones['Diametro'] = "( ( $valorCampo $unidadDeMedida X 3.291 CM ) / 100 ) X 1 FT = $presicion FT";
            break;
          case 'DM':
            vDiametro = (valorCampo * 3.291) / 10;
            var presicion = _precisarDecimales( presicionDecimales, vDiametro );
            arrConversiones['Diametro'] = "( ( $valorCampo $unidadDeMedida X 13.1549 DM ) / 10 ) X 1 FT = $presicion FT";
            break;
          case 'M':
            vDiametro = valorCampo * 3.291;
            var presicion = _precisarDecimales( presicionDecimales, vDiametro );
            arrConversiones['Diametro'] = "( $valorCampo $unidadDeMedida X 13.1549 M ) X 1 FT = $presicion FT";
            arrConversiones[unidadDeMedida] = "$valorCampo X 13.1549 = $vDiametro ";
            break;
          case 'MI':
            vDiametro = valorCampo * 5280;
            var presicion = _precisarDecimales( presicionDecimales, vDiametro );
            arrConversiones['Diametro'] = "( $valorCampo $unidadDeMedida X 5280 MI ) X 1 FT = $presicion FT";
            break;
          case 'YARDA':
            vDiametro = valorCampo / 3;
            var presicion = _precisarDecimales( presicionDecimales, vDiametro );
            arrConversiones['Diametro'] = "( $valorCampo $unidadDeMedida / 3 YARDA ) X 1 FT = $presicion FT";
            break;
          case 'INCH':
            vDiametro = valorCampo * 0.083333;
            var presicion = _precisarDecimales( presicionDecimales, vDiametro );
            arrConversiones['Diametro'] = "( $valorCampo $unidadDeMedida X 0.083333 MM ) X 1 FT = $presicion FT";
            break;
          case 'FT':
            vDiametro = valorCampo;
            break;
        }

        vDiametro = double.parse(vDiametro.toStringAsFixed(presicionDecimales));

      }
    });

    Ventilador arrDatosVentilador = Ventilador();

    _ventiladores.forEach((ventilador) {
      if(ventilador.tipo == tipo){
        if(ventilador.desc == modelo || ventilador.modelo == modelo){
          arrDatosVentilador = ventilador;
        }
      }
    });

    List<int> arrCurvaNC = [];

    switch(curva){
      case 'NC15':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 47, 36, 29, 22, 17, 14, 12, 11 ]";
        arrCurvaNC = [ 47, 36, 29, 22, 17, 14, 12, 11 ];
        break;
      case 'NC20':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 51, 40, 33, 26, 22, 19, 17, 16 ]";
        arrCurvaNC = [ 51, 40, 33, 26, 22, 19, 17, 16 ];
        break;
      case 'NC25':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 54, 44, 37, 31, 27, 24, 22, 21 ]";
        arrCurvaNC = [ 54, 44, 37, 31, 27, 24, 22, 21 ];
        break;
      case 'NC30':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 57, 48, 41, 35, 31, 29, 28, 27 ]";
        arrCurvaNC = [ 57, 48, 41, 35, 31, 29, 28, 27 ];
        break;
      case 'NC35':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 60, 52, 45, 40, 36, 34, 33, 32 ]";
        arrCurvaNC = [ 60, 52, 45, 40, 36, 34, 33, 32 ];
        break;
      case 'NC40':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 64, 56, 50, 45, 41, 39, 38, 37 ]";
        arrCurvaNC = [ 64, 56, 50, 45, 41, 39, 38, 37 ];
        break;
      case 'NC45':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 67, 60, 54, 49, 46, 44, 43, 42 ]";
        arrCurvaNC = [ 67, 60, 54, 49, 46, 44, 43, 42 ];
        break;
      case 'NC50':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 71, 64, 58, 54, 51, 49, 48, 47 ]";
        arrCurvaNC = [ 71, 64, 58, 54, 51, 49, 48, 47 ];
        break;
      case 'NC55':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 74, 67, 62, 58, 56, 54, 53, 52 ]";
        arrCurvaNC = [ 74, 67, 62, 58, 56, 54, 53, 52 ];
        break;
      case 'NC60':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 77, 71, 67, 63, 61, 59, 58, 57 ]";
        arrCurvaNC = [ 77, 71, 67, 63, 61, 59, 58, 57 ];
        break;
      case 'NC65':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 80, 75, 71, 68, 66, 64, 63, 62 ]";
        arrCurvaNC = [ 80, 75, 71, 68, 66, 64, 63, 62 ];
        break;
      case 'NC70':
        arrDatosDeEntrada['CurvaNC'] = "$curva##[ 84, 79, 75, 72, 71, 70, 68, 68 ]";
        arrCurvaNC = [ 84, 79, 75, 72, 71, 70, 68, 68 ];
        break;
    }

    double pi = math.pi;
    double a = ((pi) * (math.pow(vDiametro, 2))) / 4;
    a = double.parse(a.toStringAsFixed(presicionDecimales));
    double v = vCaudal / a;
    v = double.parse(v.toStringAsFixed(presicionDecimales));

    Map<String, String> arrLw = Map<String, String>();
    Map<String, double> arrKw = Map<String, double>();

    if(arrFrecuencias.length != 0){
      arrFrecuencias.forEach((indice) {
        String frecuencia = indice;
        double kw = (10 * _log10(vCaudal)) + (20 * _log10(vPresionE));
        String cadenaOperacion = "(10 x ${_log10(vCaudal)}) + (20 x ${_log10(vPresionE)}) = / $kw /";

        kw = double.parse(kw.toStringAsFixed(presicionDecimales));
        arrLw[frecuencia] = frecuencia == arrFrecuencias[0] ? arrDatosVentilador.the63Hz!
            : frecuencia == arrFrecuencias[1] ? arrDatosVentilador.the125Hz!
            : frecuencia == arrFrecuencias[2] ? arrDatosVentilador.the250Hz!
            : frecuencia == arrFrecuencias[3] ? arrDatosVentilador.the500Hz!
            : frecuencia == arrFrecuencias[4] ? arrDatosVentilador.the1000Hz!
            : frecuencia == arrFrecuencias[5] ? arrDatosVentilador.the2000Hz!
            : frecuencia == arrFrecuencias[6] ? arrDatosVentilador.the4000Hz!
            : arrDatosVentilador.the8000Hz!;
        arrKw[frecuencia] = kw;
      });
    }

    Map<String, double> arrLwFinal = Map<String, double>();

    if(arrLw.length != 0){
      arrLw.forEach((key, value) {
        String valorLw = arrLw[key]!;
        double valorKw = arrKw[key]!;

        double lwFinal = valorKw + double.parse(valorLw);
        String cadenaOperacion = "$valorKw + $valorLw = / $lwFinal /";

        lwFinal = double.parse(lwFinal.toStringAsFixed(presicionDecimales));
        arrLwFinal[key] = lwFinal;
      });
    }

    Map<String, double> arrLwA = Map<String, double>();

    if(arrPonderanciaA.length != 0){
      arrPonderanciaA.forEach((element) {
        double valorLwFinal = arrLwFinal[arrFrecuencias[arrPonderanciaA.indexOf(element)]]!;
        double valorPonderancia = element;

        double lwA = valorLwFinal + valorPonderancia;
        String cadenaOperacion = "$valorLwFinal + $valorPonderancia = / $lwA /";

        lwA = double.parse(lwA.toStringAsFixed(presicionDecimales));
        arrLwA[arrFrecuencias[arrPonderanciaA.indexOf(element)]] = lwA;
      });
    }

    Map<String, double> arrLwAVentiladorSeleccionado = Map<String, double>();

    if(arrCurvaNC.length != 0){
      arrCurvaNC.forEach((element) {
        double valorLwFinal = arrLwFinal[arrFrecuencias[arrCurvaNC.indexOf(element)]]!;
        double valorCurvaNC = element.toDouble();

        double lwAVentilador = valorLwFinal - valorCurvaNC;
        String cadenaOperacion = "$valorLwFinal - $valorCurvaNC = / $lwAVentilador /";

        lwAVentilador = double.parse(lwAVentilador.toStringAsFixed(presicionDecimales));
        arrLwAVentiladorSeleccionado[arrFrecuencias[arrCurvaNC.indexOf(element)]] = lwAVentilador;
      });
    }

    double vAtenuador100Hz;

    if(arrLwAVentiladorSeleccionado.length != 0){
      vAtenuador100Hz = arrLwAVentiladorSeleccionado["1000Hz"]!;
    }else{
      Fluttertoast.showToast(
          msg: 'Error al cargar los valores de LwA del Ventilador',
          toastLength: Toast.LENGTH_LONG,
          timeInSecForIosWeb: 3,
          gravity: ToastGravity.CENTER
      );
      return;
    }

    double diametroTmp = vDiametro * 304.8;
    diametroTmp = double.parse(diametroTmp.toStringAsFixed(presicionDecimales));

    if ( diametroTmp <= 425 ) {
      diametroTmp = 400;
    } else if ( (diametroTmp > 425) && (diametroTmp <= 475) ) {
      diametroTmp = 450;
    } else if ( (diametroTmp > 475) && (diametroTmp <= 525) ) {
      diametroTmp = 500;
    } else if ( (diametroTmp > 525) && (diametroTmp <= 575) ) {
      diametroTmp = 560;
    } else if ( (diametroTmp > 580) && (diametroTmp <= 615) ) {
      diametroTmp = 600;
    } else if ( (diametroTmp > 615) && (diametroTmp <= 655) ) {
      diametroTmp = 630;
    } else if ( (diametroTmp > 655) && (diametroTmp <= 695) ) {
      diametroTmp = 675;
    } else if ( (diametroTmp > 695) && (diametroTmp <= 730) ) {
      diametroTmp = 710;
    } else if ( (diametroTmp > 730) && (diametroTmp <= 775) ) {
      diametroTmp = 750;
    } else if ( (diametroTmp > 775) && (diametroTmp <= 820) ) {
      diametroTmp = 800;
    } else if ( (diametroTmp > 820) && (diametroTmp <= 870) ) {
      diametroTmp = 840;
    } else if ( (diametroTmp > 870) && (diametroTmp <= 920) ) {
      diametroTmp = 900;
    } else if ( (diametroTmp > 920) && (diametroTmp <= 970) ) {
      diametroTmp = 945;
    } else if ( (diametroTmp > 970) && (diametroTmp <= 1030) ) {
      diametroTmp = 1000;
    } else if ( (diametroTmp > 1030) && (diametroTmp <= 1090) ) {
      diametroTmp = 1065;
    } else if ( (diametroTmp > 1090) && (diametroTmp <= 1160) ) {
      diametroTmp = 1120;
    } else if ( (diametroTmp > 1160) && (diametroTmp <= 1225) ) {
      diametroTmp = 1200;
    } else if ( (diametroTmp > 1225) && (diametroTmp <= 1255) ) {
      diametroTmp = 1250;
    } else if ( (diametroTmp > 1255) && (diametroTmp <= 1305) ) {
      diametroTmp = 1260;
    } else if ( (diametroTmp > 1305) && (diametroTmp <= 1375) ) {
      diametroTmp = 1350;
    } else if ( (diametroTmp > 1375) && (diametroTmp <= 1410) ) {
      diametroTmp = 1400;
    } else if ( (diametroTmp > 1410) && (diametroTmp <= 1460) ) {
      diametroTmp = 1420;
    } else if ( (diametroTmp > 1460) && (diametroTmp <= 1550) ) {
      diametroTmp = 1500;
    } else if ( (diametroTmp > 1550) && (diametroTmp <= 1640) ) {
      diametroTmp = 1600;
    } else if ( (diametroTmp > 1640) && (diametroTmp <= 1740) ) {
      diametroTmp = 1680;
    } else if ( (diametroTmp > 1740) && (diametroTmp <= 1840) ) {
      diametroTmp = 1800;
    } else if ( (diametroTmp > 1840) && (diametroTmp <= 1885) ) {
      diametroTmp = 1875;
    } else if ( (diametroTmp > 1885) && (diametroTmp <= 2050) ) {
      diametroTmp = 2000;
    } else if ( (diametroTmp > 2050) && (diametroTmp <= 2170) ) {
      diametroTmp = 2100;
    } else if ( (diametroTmp > 2170) && (diametroTmp <= 2370) ) {
      diametroTmp = 2240;
    } else if ( (diametroTmp > 2370) && (diametroTmp <= 2750) ) {
      diametroTmp = 2500;
    } else if ( (diametroTmp > 2501) && (diametroTmp <= 3000) ) {
      diametroTmp = 2800;
    }

    Map<String, String> arrAtenuador1000Hz = Map<String, String>();

    _atenuacion.forEach((element) {
      String idAtenuador = element.idatenuacion!;
      String vDiametroAte = element.diametro!;
      String vLongitudAte  = element.longitud!;
      String v1000Hz = element.the1000Hz!;

      if(vDiametroAte == diametroTmp.toInt().toString()){
        arrAtenuador1000Hz[idAtenuador] = v1000Hz;
      }
    });

    Map<String, double> arrDiferencia = Map<String, double>();
    Map<String, double> arrDiferenciaSort = Map<String, double>();
    String idAtenuadorSelect;

    if(arrAtenuador1000Hz.length > 0){
      arrAtenuador1000Hz.forEach((key, value) {
        double vAtenuadorSelect = double.parse(arrAtenuador1000Hz[key]!);
        double diferencia;

        if(vAtenuador100Hz > vAtenuadorSelect){
          diferencia = vAtenuador100Hz - vAtenuadorSelect;
        }else{
          diferencia = vAtenuadorSelect - vAtenuador100Hz;
        }

        diferencia = double.parse(diferencia.toStringAsFixed(presicionDecimales));
        arrDiferencia[key] = diferencia;
        arrDiferenciaSort[key] = diferencia;
      });

      arrDiferenciaSort = _sortMapItems(arrDiferenciaSort);
      double valMenorDif = arrDiferenciaSort[arrDiferenciaSort.keys.first]!;
      idAtenuadorSelect = _getKey(arrDiferencia, valMenorDif);
    }else{
      Fluttertoast.showToast(
          msg: 'Se Presento un Error a la hora de cargar los valores de los posibles atenuadores seleccionados.',
          toastLength: Toast.LENGTH_LONG,
          timeInSecForIosWeb: 3,
          gravity: ToastGravity.CENTER
      );
      return null;
    }

    Atenuacion arrAtenuador = Atenuacion();

    _atenuacion.forEach((element) {
      String idAtenuador = element.idatenuacion!;

      if(idAtenuador == idAtenuadorSelect){
        arrAtenuador = element;
      }
    });

    Map<String, double> arrLwAVentilador = Map<String, double>();

    arrFrecuencias.forEach((element) {
      String frecuencia = element;
      double vlwFinal = arrLwFinal[frecuencia]!;
      String vAtenuador = frecuencia == arrFrecuencias[0] ? arrAtenuador.the63Hz!
          : frecuencia == arrFrecuencias[1] ? arrAtenuador.the125Hz!
          : frecuencia == arrFrecuencias[2] ? arrAtenuador.the250Hz!
          : frecuencia == arrFrecuencias[3] ? arrAtenuador.the500Hz!
          : frecuencia == arrFrecuencias[4] ? arrAtenuador.the1000Hz!
          : frecuencia == arrFrecuencias[5] ? arrAtenuador.the2000Hz!
          : frecuencia == arrFrecuencias[6] ? arrAtenuador.the4000Hz!
          : arrAtenuador.the8000Hz!;

      double lwAVentilador = vlwFinal - double.parse(vAtenuador);
      String cadenaOperacion = "$vlwFinal - $vAtenuador = $lwAVentilador";
      lwAVentilador = double.parse(lwAVentilador.toStringAsFixed(presicionDecimales));
      arrLwAVentilador[frecuencia] = lwAVentilador;
    });

    String searchPotenciaSonora = '';

    if(!v.isNaN){
      double tmpPotenciaSonora = v;

      if ( tmpPotenciaSonora <= 1000 ) {
        searchPotenciaSonora = "<1000";
      } else if ( (tmpPotenciaSonora > 1000) && (tmpPotenciaSonora <= 1500) ) {
        searchPotenciaSonora = ">1000";
      } else if ( (tmpPotenciaSonora > 1500) && (tmpPotenciaSonora <= 2000) ) {
        searchPotenciaSonora = "<2000";
      } else if ( (tmpPotenciaSonora > 2000) && (tmpPotenciaSonora <= 2500) ) {
        searchPotenciaSonora = ">2000";
      } else if ( (tmpPotenciaSonora > 2500) && (tmpPotenciaSonora <= 3000) ) {
        searchPotenciaSonora = "<3000";
      } else if ( tmpPotenciaSonora > 3000 ) {
        searchPotenciaSonora = ">3000";
      }
    }

    PotenciaSonora arrPotenciaSonoraSelect = PotenciaSonora();

    _potenciaSonora.forEach((element) {
      PotenciaSonora arrTmpPotencia = element;
      String idPotenciaSonora = element.idpotson!;
      String vFtMin = element.ftmin!;

      if(vFtMin == searchPotenciaSonora){
        arrPotenciaSonoraSelect = arrTmpPotencia;
      }
    });

    Map<String, String> arrSonidoRegenerado = Map<String, String>();

    if(arrAtenuador1000Hz.length > 0){
      arrFrecuencias.forEach((element) {
        String frecuencia = element;
        arrSonidoRegenerado[frecuencia] = frecuencia == arrFrecuencias[0] ? arrPotenciaSonoraSelect.the63Hz!
            : frecuencia == arrFrecuencias[1] ? arrPotenciaSonoraSelect.the125Hz!
            : frecuencia == arrFrecuencias[2] ? arrPotenciaSonoraSelect.the250Hz!
            : frecuencia == arrFrecuencias[3] ? arrPotenciaSonoraSelect.the500Hz!
            : frecuencia == arrFrecuencias[4] ? arrPotenciaSonoraSelect.the1000Hz!
            : frecuencia == arrFrecuencias[5] ? arrPotenciaSonoraSelect.the2000Hz!
            : frecuencia == arrFrecuencias[6] ? arrPotenciaSonoraSelect.the4000Hz!
            : arrPotenciaSonoraSelect.the8000Hz!;
      });
    }else{
      Fluttertoast.showToast(
          msg: 'Los valores de las Frecuencias Hz del atenudor seleccionado, se no se cargaron correctamente.',
          toastLength: Toast.LENGTH_LONG,
          timeInSecForIosWeb: 3,
          gravity: ToastGravity.CENTER
      );
      return;
    }

    Map<String, double> arrCorreccionArea = Map<String, double>();

    for(int i = 0; i < arrFrecuencias.length; i++){
      String frecuencia = arrFrecuencias[i];
      double correccionArea = (10 * _log10(a)) - 4.8;
      String cadenaOperacion = "(10 x ${_log10(a)}) - 4.8";
      correccionArea = double.parse(correccionArea.toStringAsFixed(presicionDecimales));
      arrCorreccionArea[frecuencia] = correccionArea;
    }

    Map<String, double> arrSonidoMasCorreccion = Map<String, double>();

    for(int i = 0; i < arrFrecuencias.length; i++){
      String frecuencia = arrFrecuencias[i];
      double valPotenciaSonora = double.parse(frecuencia == arrFrecuencias[0] ? arrPotenciaSonoraSelect.the63Hz!
          : frecuencia == arrFrecuencias[1] ? arrPotenciaSonoraSelect.the125Hz!
          : frecuencia == arrFrecuencias[2] ? arrPotenciaSonoraSelect.the250Hz!
          : frecuencia == arrFrecuencias[3] ? arrPotenciaSonoraSelect.the500Hz!
          : frecuencia == arrFrecuencias[4] ? arrPotenciaSonoraSelect.the1000Hz!
          : frecuencia == arrFrecuencias[5] ? arrPotenciaSonoraSelect.the2000Hz!
          : frecuencia == arrFrecuencias[6] ? arrPotenciaSonoraSelect.the4000Hz!
          : arrPotenciaSonoraSelect.the8000Hz!
      );
      double valCorreccionArea = arrCorreccionArea[frecuencia]!;

      double sonidoMasCorreccion = valPotenciaSonora + valCorreccionArea;
      String cadenaOperacion = "$valPotenciaSonora + $valCorreccionArea = $sonidoMasCorreccion";
      sonidoMasCorreccion = double.parse(sonidoMasCorreccion.toStringAsFixed(presicionDecimales));
      arrSonidoMasCorreccion[frecuencia] = sonidoMasCorreccion;
    }

    Map<String, double> arrSumaLog = Map<String, double>();

    for(int i = 0; i < arrFrecuencias.length; i++){
      if(arrLwAVentilador.length > 0){
        String frecuencia = arrFrecuencias[i];
        double potSonora = double.parse(frecuencia == arrFrecuencias[0] ? arrPotenciaSonoraSelect.the63Hz!
            : frecuencia == arrFrecuencias[1] ? arrPotenciaSonoraSelect.the125Hz!
            : frecuencia == arrFrecuencias[2] ? arrPotenciaSonoraSelect.the250Hz!
            : frecuencia == arrFrecuencias[3] ? arrPotenciaSonoraSelect.the500Hz!
            : frecuencia == arrFrecuencias[4] ? arrPotenciaSonoraSelect.the1000Hz!
            : frecuencia == arrFrecuencias[5] ? arrPotenciaSonoraSelect.the2000Hz!
            : frecuencia == arrFrecuencias[6] ? arrPotenciaSonoraSelect.the4000Hz!
            : arrPotenciaSonoraSelect.the8000Hz!
        );

        double sumaLog = 10 * (_log10((math.pow(10, (arrLwAVentilador[frecuencia]!/10))) + (math.pow(10, (potSonora/10))).toDouble()));
        sumaLog = double.parse(sumaLog.toStringAsFixed(presicionDecimales));
        arrSumaLog[frecuencia] = sumaLog;
      }
    }

    Map<String, double> arrEspectroResultante = Map<String, double>();

    for(int i = 0; i < arrFrecuencias.length; i++){
      String frecuencia = arrFrecuencias[i];

      if(arrSumaLog.length > 0 && arrPonderanciaA.length > 0){
        double espectroResultante = arrSumaLog[frecuencia]! + arrPonderanciaA[i];
        espectroResultante = double.parse(espectroResultante.toStringAsFixed(presicionDecimales));
        arrEspectroResultante[frecuencia] = espectroResultante;
      }
    }

    double sumaLogaritmica;

    if(arrEspectroResultante.length > 0){
      sumaLogaritmica = 10 * (_log10(math.pow(10, (arrEspectroResultante["63Hz"]!/10)) + math.pow(10, (arrEspectroResultante["125Hz"]!/10)).toDouble()
          + math.pow(10, (arrEspectroResultante["250Hz"]!/10)) + math.pow(10, (arrEspectroResultante["500Hz"]!/10)).toDouble()
          + math.pow(10, (arrEspectroResultante["1000Hz"]!/10)) + math.pow(10, (arrEspectroResultante["2000Hz"]!/10)).toDouble()
          + math.pow(10, (arrEspectroResultante["4000Hz"]!/10)) + math.pow(10, (arrEspectroResultante["8000Hz"]!/10)).toDouble()
      ));
      sumaLogaritmica = double.parse(sumaLogaritmica.toStringAsFixed(presicionDecimales));
    }

    double sumaLogaritmicaLwFinal = 0.0;

    if(arrLwFinal.length > 0){
      sumaLogaritmicaLwFinal = 10 * (_log10(math.pow(10, (arrLwFinal["63Hz"]!/10)) + math.pow(10, (arrLwFinal["125Hz"]!/10)).toDouble()
          + math.pow(10, (arrLwFinal["250Hz"]!/10)) + math.pow(10, (arrLwFinal["500Hz"]!/10)).toDouble()
          + math.pow(10, (arrLwFinal["1000Hz"]!/10)) + math.pow(10, (arrLwFinal["2000Hz"]!/10)).toDouble()
          + math.pow(10, (arrLwFinal["4000Hz"]!/10)) + math.pow(10, (arrLwFinal["8000Hz"]!/10)).toDouble()
      ));
      sumaLogaritmicaLwFinal = double.parse(sumaLogaritmicaLwFinal.toStringAsFixed(presicionDecimales));
    }

    double sumaLogaritmicaLwA = 0.0;

    if(arrLwA.length > 0){
      sumaLogaritmicaLwA = 10 * (_log10(math.pow(10, (arrLwA["63Hz"]!/10)) + math.pow(10, (arrLwA["125Hz"]!/10)).toDouble()
          + math.pow(10, (arrLwA["250Hz"]!/10)) + math.pow(10, (arrLwA["500Hz"]!/10)).toDouble()
          + math.pow(10, (arrLwA["1000Hz"]!/10)) + math.pow(10, (arrLwA["2000Hz"]!/10)).toDouble()
          + math.pow(10, (arrLwA["4000Hz"]!/10)) + math.pow(10, (arrLwA["8000Hz"]!/10)).toDouble()
      ));
      sumaLogaritmicaLwA = double.parse(sumaLogaritmicaLwA.toStringAsFixed(presicionDecimales));
    }

    double resultadoPresionSonora = sumaLogaritmicaLwFinal - (10 * _log10((4*math.pi)*(math.pow(1.5, 2)/2)));
    resultadoPresionSonora = double.parse(resultadoPresionSonora.toStringAsFixed(presicionDecimales));

    double resultadoPresionSonoraA = sumaLogaritmicaLwA - (10 * _log10((4 * math.pi) * (math.pow(1.5, 2) / 2)));
    resultadoPresionSonoraA = double.parse(resultadoPresionSonoraA.toStringAsFixed(presicionDecimales));

    double sumaLogaritmicaLwAtenuado = 0.0;

    if(arrSumaLog.length > 0){
      sumaLogaritmicaLwAtenuado = 10 * (_log10(math.pow(10, (arrSumaLog["63Hz"]!/10)) + math.pow(10, (arrSumaLog["125Hz"]!/10)).toDouble()
          + math.pow(10, (arrSumaLog["250Hz"]!/10)) + math.pow(10, (arrSumaLog["500Hz"]!/10)).toDouble()
          + math.pow(10, (arrSumaLog["1000Hz"]!/10)) + math.pow(10, (arrSumaLog["2000Hz"]!/10)).toDouble()
          + math.pow(10, (arrSumaLog["4000Hz"]!/10)) + math.pow(10, (arrSumaLog["8000Hz"]!/10)).toDouble()
      ));
      sumaLogaritmicaLwAtenuado = double.parse(sumaLogaritmicaLwAtenuado.toStringAsFixed(presicionDecimales));
    }

    double sumaLogaritmicaEspectroResultante = 0.0;

    if(arrEspectroResultante.length > 0){
      sumaLogaritmicaEspectroResultante = 10 * (_log10(math.pow(10, (arrEspectroResultante["63Hz"]!/10)) + math.pow(10, (arrEspectroResultante["125Hz"]!/10)).toDouble()
          + math.pow(10, (arrEspectroResultante["250Hz"]!/10)) + math.pow(10, (arrEspectroResultante["500Hz"]!/10)).toDouble()
          + math.pow(10, (arrEspectroResultante["1000Hz"]!/10)) + math.pow(10, (arrEspectroResultante["2000Hz"]!/10)).toDouble()
          + math.pow(10, (arrEspectroResultante["4000Hz"]!/10)) + math.pow(10, (arrEspectroResultante["8000Hz"]!/10)).toDouble()
      ));
      sumaLogaritmicaEspectroResultante = double.parse(sumaLogaritmicaEspectroResultante.toStringAsFixed(presicionDecimales));
    }

    double resultadoPresionSonoraAA = sumaLogaritmicaLwAtenuado - (10 * _log10((4 * math.pi) * (math.pow(1.5, 2) / 2)));
    resultadoPresionSonoraAA = double.parse(resultadoPresionSonoraAA.toStringAsFixed(presicionDecimales));

    double resultadoPresionSonoraBB = sumaLogaritmicaEspectroResultante - (10 * _log10((4 * math.pi) * (math.pow(1.5, 2) / 2)));
    resultadoPresionSonoraBB = double.parse(resultadoPresionSonoraBB.toStringAsFixed(presicionDecimales));

    final Map<String, double> fArrLwFinal = {};
    arrLwFinal.forEach((key, value) {
      double val = value;

      if(value == double.negativeInfinity || value == double.infinity){
        val = 0.0;
      }

      fArrLwFinal[key] = val;
    });

    if(sumaLogaritmicaLwFinal == double.negativeInfinity || sumaLogaritmicaLwFinal == double.infinity){
      sumaLogaritmicaLwFinal = 0.0;
    }

    final Map<String, double> fArrLwA = {};
    arrLwA.forEach((key, value) {
      double val = value;

      if(value == double.negativeInfinity || value == double.infinity){
        val = 0.0;
      }

      fArrLwA[key] = val;
    });

    if(sumaLogaritmicaLwA == double.negativeInfinity || sumaLogaritmicaLwA == double.infinity){
      sumaLogaritmicaLwA = 0.0;
    }

    Navigator.push(context, MaterialPageRoute(
      builder: (context) => ResultadoPage(
        frecuencias: arrFrecuencias,
        arrLwFinal: fArrLwFinal,
        sumaLogaritmicaLwFinal: sumaLogaritmicaLwFinal,
        arrLwA: fArrLwA,
        sumaLogaritmicaLwA: sumaLogaritmicaLwA,
        presionSonora: resultadoPresionSonora,
        arrSumaLog: arrSumaLog,
        sumaLogaritmicaLwFinalVa: sumaLogaritmicaLwAtenuado,
        arrEspectroResultante: arrEspectroResultante,
        sumaLogaritmicaLwAVa: sumaLogaritmicaEspectroResultante,
        presionSonoraVa: resultadoPresionSonoraAA,
        arrAtenuador: arrAtenuador,
        arrDatosEntrada: arrDatosDeEntrada,
        arrConversiones: arrConversiones,
      ),
    ));
  }

  String _getKey(Map<String, double> map, double needle){
    List values = map.values.toList();
    List keys = map.keys.toList();

    int index = values.indexOf(needle);
    return keys[index];
  }

  Map<String, double> _sortMapItems(Map<String, double> toSort){
    Map<String, double> tmp = Map<String, double>();
    List values = toSort.values.toList();
    List keys = toSort.keys.toList();

    values.sort();
    values.reversed;

    values.forEach((value) {
      keys.forEach((key) {
        if(!tmp.containsKey(key) && toSort[key] == value){
          tmp[key] = value;
        }
      });
    });

    return tmp;
  }

  double _precisarDecimales(int presicion, double num){
    return double.parse(num.toStringAsFixed(presicion));
  }

  void _errorCarga(String error){
    showDialog(
        context: context,
        barrierDismissible: true,
        builder: (context) => AlertDialog(
          title: Text(
            '¡ERROR!',
          ),
          content: Text(
              'Se produjo el siguiente error: <<$error>>.'
          ),
          actions: [
            TextButton(
              child: Text(
                  'Regresar al inicio'
              ),
              onPressed: () => Navigator.pop(context),
            )
          ],
        )
    );
  }
}
