import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'dart:ui';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:http/http.dart' as http;

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

import '../models/ventiladores_model.dart';
import '../providers/pdf_provider.dart';
import '../providers/ventiladores_provider.dart';
import '../widgets/encabezado_pais.dart';
import '../widgets/formatters.dart';
import 'interfaz_cuadricula_page.dart';

class CalculadoraAtenuadoresAcusticosPage extends StatefulWidget {
  final String pais;
  final String code;
  final String idProyecto;
  final String idUsuario;
  final String token;
  final String datos;
  final String noProyecto;
  final String archpdf;

  const CalculadoraAtenuadoresAcusticosPage({
    Key? key,
    required this.pais,
    required this.code,
    required this.idProyecto,
    required this.idUsuario,
    required this.token,
    required this.datos,
    required this.noProyecto,
    required this.archpdf,
  }) : super(key: key);

  @override
  State<CalculadoraAtenuadoresAcusticosPage> createState() => _CalculadoraAtenuadoresAcusticosPageState();
}

class _CalculadoraAtenuadoresAcusticosPageState extends State<CalculadoraAtenuadoresAcusticosPage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  final VentiladoresProvider _ventiladoresProvider = VentiladoresProvider();
  final TextEditingController _caudalController = TextEditingController(text: "0.00000000");
  final TextEditingController _presionController = TextEditingController(text: "0.00000000");
  final TextEditingController _potenciaController = TextEditingController(text: "0.00000000");
  final TextEditingController _diametroController = TextEditingController(text: "0.00000000");
  final List<String> _ventiladoresTipos = [];
  final List<Atenuacion> _atenuacion = [];
  final List<PotenciaSonora> _potenciaSonora = [];
  final List<Ventilador> _ventiladores = [];
  final Map<String, List<String>> _ventiladoresModelos = {};
  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'
  ];
  final _pdfProvider = PDFProvider();

  bool _hasError = false;
  bool _isLoading = true;
  bool _enableResults = false;
  double _valCaudal = 0.0;
  double _valPresion = 0.0;
  double _valPotencia = 0.0;
  double _valDiametro = 0.0;
  String _errorStr = "";
  String _pais = "";
  String _code = "";
  String _tipoVentilador = "";
  String _modeloVentilador = "";
  String _unidadCaudal = "CFM";
  String _unidadPresion = "INWG";
  String _unidadPotencia = "BHP";
  String _unidadDiametro = "FT";
  String _curva = "NC15";

  final dynamic _calculos = {};

  late String _localPath;
  final ReceivePort _port = ReceivePort();
  List<TaskInfo>? _tasks;

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

    FlutterDownloader.registerCallback(downloadCallback);

    _pais = widget.pais;
    _code = widget.code;

    _init();
  }

  void _init() async{
    final ventiladores = await _ventiladoresProvider.fetchVentiladores(widget.token);
    if(ventiladores == null){
      _errorStr = "Hubo un error al consultar los ventiladores registrados";
      _hasError = true;
      setState(() => _isLoading = false);
      return;
    }

    for (var tipoVentilador in ventiladores.result!.ventiladoresTipos!) {
      _ventiladoresTipos.add(tipoVentilador);
    }

    for (var modeloVentilador in ventiladores.result!.ventiladores!) {
      final tipoVentilador = modeloVentilador.tipo;
      final modelos = _ventiladoresModelos[tipoVentilador];

      if(modelos == null){
        _ventiladoresModelos[tipoVentilador!] = [];
      }

      _ventiladoresModelos[tipoVentilador!]!.add(modeloVentilador.desc!);
    }

    for (var atenuacion in ventiladores.result!.atenuacion!) {
      _atenuacion.add(atenuacion);
    }

    if(_atenuacion.isEmpty){
      _errorStr = "Hubo un error al cargar el catálogo de atenuadores";
      _hasError = true;
      setState(() => _isLoading = false);
      return;
    }

    for (var potenciaSonora in ventiladores.result!.potenciaSonora!) {
      _potenciaSonora.add(potenciaSonora);
    }

    if(_atenuacion.isEmpty){
      _errorStr = "Hubo un error al cargar las potencias sonoras";
      _hasError = true;
      setState(() => _isLoading = false);
      return;
    }

    for (var ventilador in ventiladores.result!.ventiladores!) {
      _ventiladores.add(ventilador);
    }

    if(_ventiladores.isEmpty){
      _errorStr = "Hubo un error al cargar los ventiladores registrados";
      _hasError = true;
      setState(() => _isLoading = false);
      return;
    }

    if(widget.datos.isEmpty){
      setState(() => _isLoading = false);
    }else{
      final datosDec = utf8.decode(base64.decode(widget.datos));
      final datosArr = jsonDecode(datosDec);

      final datosEntrada = datosArr['arrDatosDeEntrada'];
      if(datosEntrada['TipoVentilador'].isEmpty){
        setState(() => _isLoading = false);
      }else{
        _tipoVentilador = datosEntrada['TipoVentilador'];
        _modeloVentilador = datosEntrada['ModeloVentilador'];

        final caudalStr = datosEntrada['Caudal'];
        final caudalArr = caudalStr.split(" ");

        _valCaudal = caudalArr[0].runtimeType == double ? caudalArr[0] : double.parse("${caudalArr[0]}");
        _caudalController.text = _valCaudal.toStringAsFixed(8);
        _unidadCaudal = caudalArr[1];

        final presionStr = datosEntrada['PresionEstatica'];
        final presionArr = presionStr.split(" ");

        _valPresion = presionArr[0].runtimeType == double ? presionArr[0] : double.parse("${presionArr[0]}");
        _presionController.text = _valPresion.toStringAsFixed(8);
        _unidadPresion = presionArr[1];

        final potenciaStr = datosEntrada['PotenciaAbsorbida'];
        final potenciaArr = potenciaStr.split(" ");

        _valPotencia = potenciaArr[0].runtimeType == double ? potenciaArr[0] : double.parse("${potenciaArr[0]}");
        _potenciaController.text = _valPotencia.toStringAsFixed(8);
        _unidadPotencia = potenciaArr[1];

        final diametroStr = datosEntrada['Diametro'];
        final diametroArr = diametroStr.split(" ");

        _valDiametro = diametroArr[0].runtimeType == double ? diametroArr[0] : double.parse("${diametroArr[0]}");
        _diametroController.text = _valDiametro.toStringAsFixed(8);
        _unidadDiametro = diametroArr[1];

        _calcAtenuador();
        setState(() => _isLoading = false);
      }
    }
  }

  Future<bool> _cambiarDatos(String datos, String archPDF, String status) async{
    final url = Uri.https("smart.solerpalau.mx", "PR/api/v1/quiosco/matrizMemoriasCalculo/actualizarProyecto");
    final res = await http.post(url,
      headers: {
        "Authorization": "Bearer ${widget.token}"
      },
      body: {
        "IDUSUARIO": widget.idUsuario,
        "IDPROYECTO": widget.idProyecto,
        "FMODIF": DateTime.now().toIso8601String().substring(0, 19),
        "ESTATUS": status,
        "DATOS": base64Encode(utf8.encode(datos)),
        "ARCHPDF" : archPDF
      },
    );

    final decoded = jsonDecode(res.body);
    return decoded['response'];
  }

  void _requestDownload(TaskInfo task) async{
    task.taskId = await FlutterDownloader.enqueue(
      url: task.link!,
      savedDir: _localPath,
      showNotification: true,
      openFileFromNotification: true,
      saveInPublicStorage: true,
    );
  }

  Future<void> _prepareSaveDir() async{
    _localPath = (await _findLocalPath())!;
    final savedDir = Directory(_localPath);
    bool hasExisted = await savedDir.exists();
    if (!hasExisted) {
      savedDir.create();
    }
  }

  Future<String?> _findLocalPath() async{
    String externalStorageDirPath;
    if(Platform.isAndroid){
      final directory = await getExternalStorageDirectory();
      externalStorageDirPath = directory!.path;
    }else{
      final directory = await getApplicationDocumentsDirectory();
      externalStorageDirPath = directory.path;
    }

    return externalStorageDirPath;
  }

  void _bindBackgroundIsolate(){
    bool isSuccess = IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');

    if(!isSuccess){
      _unbindBackgroundIsolate();
      _bindBackgroundIsolate();
      return;
    }

    _port.listen((data) {
      print('UI Isolate Callback: $data');
      String? id = data[0];
      DownloadTaskStatus? status = data [1];
      int? progress = data[2];

      if(_tasks != null && _tasks!.isNotEmpty){
        final task = _tasks!.firstWhere((task) => task.taskId == id);
        setState(() {
          task.status = status;
          task.progress = progress;
        });
      }
    });
  }

  void _unbindBackgroundIsolate() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
  }

  static void downloadCallback(String id, DownloadTaskStatus status, int progress){
    print("Task $id: status: $status, progress: $progress");
    final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port')!;
    send.send([id, status, progress]);
  }

  @override
  Widget build(BuildContext context) {
    final _screenSize = MediaQuery.of(context).size;
    return Scaffold(
      key: _scaffoldKey,
      body: _isLoading ? const Center(
        child: CircularProgressIndicator(),
      ) : SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: [
              const SizedBox(height: 8.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Row(
                  children: [
                    TextButton(
                      child: Text(
                        "Memoria de cálculo de ...",
                        style: GoogleFonts.roboto(
                          fontSize: 16.0,
                          fontWeight: FontWeight.bold,
                          fontStyle: FontStyle.italic,
                        ),
                      ),
                      onPressed: () async{
                        final accion = await showDialog(
                          context: context,
                          barrierDismissible: false,
                          builder: (context) => AlertDialog(
                            title: Text(
                              "Salir sin guardar",
                              textAlign: TextAlign.center,
                              style: GoogleFonts.roboto(
                                fontWeight: FontWeight.bold,
                                fontSize: 20.0,
                                color: Colors.black87,
                              ),
                            ),
                            content: Text(
                              "¿Está seguro de salir sin guardar los cambios?",
                              textAlign: TextAlign.center,
                              style: GoogleFonts.roboto(
                                fontSize: 16.0,
                              ),
                            ),
                            actions: [
                              TextButton(
                                child: const Text("Salir sin guardar"),
                                onPressed: () => Navigator.pop(context, "salir"),
                              ),
                              TextButton(
                                child: const Text("Guardar y salir"),
                                onPressed: () => Navigator.pop(context, "guardar"),
                              ),
                              TextButton(
                                child: const Text("Cancelar"),
                                onPressed: () => Navigator.pop(context, "cancelar"),
                              )
                            ],
                          ),
                        );

                        if(accion == "salir"){
                          Navigator.pop(context);
                        }else if(accion == "guardar"){
                          Map<String, String> arrDatosDeEntrada = {};

                          arrDatosDeEntrada['TipoVentilador'] = _tipoVentilador;
                          arrDatosDeEntrada['ModeloVentilador'] = _modeloVentilador;
                          arrDatosDeEntrada['Caudal'] = "${_valCaudal.toStringAsFixed(8)} $_unidadCaudal";
                          arrDatosDeEntrada['PresionEstatica'] = "${_valPresion.toStringAsFixed(8)} $_unidadPresion";
                          arrDatosDeEntrada['PotenciaAbsorbida'] = "${_valPotencia.toStringAsFixed(8)} $_unidadPotencia";
                          arrDatosDeEntrada['Diametro'] = "${_valDiametro.toStringAsFixed(8)} $_unidadDiametro";

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

                          final jsonInfoArr = {
                            "arrDatosDeEntrada" : arrDatosDeEntrada,
                            "frecuencias": _calculos['frecuencias'],
                            "arrLwFinal": _calculos['LW'],
                            "sumaLogaritmicaLwFinal": _calculos['LWdB'],
                            "arrLwA": _calculos['LWA'],
                            "sumaLogaritmicaLwA": _calculos['LWAdB'],
                            "presionSonora": _calculos['presionSonora'],
                            "arrSumaLog": _calculos['ALW'],
                            "sumaLogaritmicaLwFinalVa": _calculos['ALWdB'],
                            "arrEspectroResultante": _calculos['ALWA'],
                            "sumaLogaritmicaLwAVa": _calculos['ALWAdB'],
                            "presionSonoraVa": _calculos['presionSonoraA'],
                            "modelo": _calculos['modeloAtenuador'],
                            "longitud": _calculos['longitudAtenuador'],
                          };
                          final infoStr = jsonEncode(jsonInfoArr);

                          final guardado = await _cambiarDatos(infoStr, "", _enableResults ? "F" : "C");
                          if(guardado){
                            Navigator.pop(context);
                          }else{
                            Fluttertoast.showToast(
                              msg: "Hubo un error al intentar guardar el proyecto, intentelo de nuevo más tarde.",
                              toastLength: Toast.LENGTH_SHORT,
                              timeInSecForIosWeb: 4,
                              gravity: ToastGravity.CENTER,
                              webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                            );
                          }
                        }
                      },
                      style: TextButton.styleFrom(
                        padding: const EdgeInsets.fromLTRB(0, 0, 8.0, 0),
                        minimumSize: const Size(0, 0),
                        tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      ),
                    ),
                    const SizedBox(width: 8.0),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.fromLTRB(0, 0, 8.0, 0),
                        child: RichText(
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          text: TextSpan(
                            style: GoogleFonts.roboto(
                              fontSize: 16.0,
                              color: Colors.black54,
                              fontWeight: FontWeight.bold,
                              fontStyle: FontStyle.italic,
                            ),
                            children: [
                              TextSpan(
                                text: ">  ",
                                style: GoogleFonts.roboto(
                                  fontSize: 16.0,
                                  color: const Color(0xFFB40404),
                                  fontWeight: FontWeight.bold,
                                  fontStyle: FontStyle.italic,
                                ),
                              ),
                              const TextSpan(text: "Calculadora de atenuadores acústicos"),
                            ],
                          ),
                        ),
                      ),
                    )
                  ],
                ),
              ),
              const SizedBox(height: 8.0),
              EncabezadoPais(paisCode: _code, paisName: _pais),
              const SizedBox(height: 32.0),
              Image.asset(
                "assets/5.png",
                width: 88.0,
              ),
              const SizedBox(height: 16.0),
              Container(
                width: double.infinity,
                padding: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Text(
                  "Calculadora de atenuadores acústicos".toUpperCase(),
                  textAlign: TextAlign.center,
                  style: const TextStyle(
                    fontFamily: "Helvetica Neue Black Cond",
                    fontSize: 28.0,
                  ),
                ),
              ),
              const SizedBox(height: 8.0),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 32.0),
                width: double.infinity,
                child: const Text(
                  "Por favor ingresa los datos requeridos para el cálculo del atenuador.",
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontFamily: "Helvetica Neue Light",
                    fontSize: 22.0,
                    fontWeight: FontWeight.w600,
                    color: Color.fromRGBO(104, 104, 104, 1),
                  ),
                ),
              ),
              const SizedBox(height: 32.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Tipo de ventilador:',
                      textAlign: TextAlign.start,
                      style: GoogleFonts.roboto(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    DropdownButton<String>(
                      value: _tipoVentilador.isNotEmpty ? _tipoVentilador : null,
                      hint: Text(
                        "Selecciona un tipo de ventilador",
                        style: GoogleFonts.roboto(
                          color: Colors.grey,
                          fontStyle: FontStyle.italic,
                        ),
                      ),
                      items: _ventiladoresTipos.map((e) => DropdownMenuItem(
                        value: e,
                        child: Text(
                          e,
                          style: GoogleFonts.roboto(),
                        ),
                      )).toList(),
                      onChanged: (newVal) => setState((){
                        _tipoVentilador = newVal!;
                        _modeloVentilador = _ventiladoresModelos[newVal]!.first;

                        _calcAtenuador();
                      }),
                      isExpanded: true,
                      focusColor: Colors.transparent,
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Modelo de ventilador:',
                      style: GoogleFonts.roboto(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    DropdownButton<String>(
                      value: _modeloVentilador,
                      disabledHint: Text(
                        "Primero selecciona un tipo de ventilador",
                        style: GoogleFonts.roboto(
                          color: Colors.grey,
                          fontStyle: FontStyle.italic,
                        ),
                      ),
                      items: _tipoVentilador.isEmpty ? [] : _ventiladoresModelos[_tipoVentilador]!.map((e) => DropdownMenuItem(
                        value: e,
                        child: Text(
                          e,
                          style: GoogleFonts.roboto(),
                        ),
                      )).toList(),
                      onChanged: _tipoVentilador.isEmpty ? null : (newVal) => setState(() {
                        _modeloVentilador = newVal!;
                        _calcAtenuador();
                      }),
                      isExpanded: true,
                      focusColor: Colors.transparent,
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Caudal (Q):',
                      style: GoogleFonts.roboto(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    Row(
                      children: [
                        Expanded(
                          child: SizedBox(
                            height: 64.0,
                            width: double.infinity,
                            child: Stack(
                              alignment: Alignment.center,
                              children: [
                                TextField(
                                  textAlign: TextAlign.center,
                                  controller: _caudalController,
                                  decoration: const InputDecoration(
                                    counterText: "",
                                    counterStyle: TextStyle(
                                      height: double.minPositive,
                                    ),
                                  ),
                                  inputFormatters: [
                                    DecimalTextInputFormatter()
                                  ],
                                  onChanged: (val) => setState(() {
                                    if(val.isEmpty){
                                      _valCaudal = 0;
                                    }else{
                                      _valCaudal = double.parse(val);
                                    }

                                    _calcAtenuador();
                                  }),
                                ),
                                Positioned(
                                  left: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.remove,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valCaudal = _valCaudal - 0.00000001;
                                      if(_valCaudal < 0){
                                        _valCaudal = 0;
                                      }

                                      _caudalController.text = _valCaudal.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }) ,
                                  ),
                                ),
                                Positioned(
                                  right: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.add,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valCaudal = _valCaudal + 0.00000001;
                                      if(_valCaudal > 9999){
                                        _valCaudal = 9999;
                                      }

                                      _caudalController.text = _valCaudal.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }),
                                  ),
                                )
                              ],
                            ),
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        DropdownButton<String>(
                          focusColor: Colors.transparent,
                          value: _unidadCaudal,
                          onChanged: (val) => setState(() {
                            _unidadCaudal = val!;
                            _calcAtenuador();
                          }),
                          items: _caudalUnidades.map((e) => DropdownMenuItem<String>(
                            child: Text(
                              e,
                              style: GoogleFonts.roboto(
                                fontSize: 18.0,
                              ),
                            ),
                            value: e,
                          )).toList(),
                        )
                      ],
                    )
                  ],
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Presión estática (P):',
                      style: GoogleFonts.roboto(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    Row(
                      children: [
                        Expanded(
                          child: SizedBox(
                            height: 64.0,
                            width: double.infinity,
                            child: Stack(
                              alignment: Alignment.center,
                              children: [
                                TextField(
                                  textAlign: TextAlign.center,
                                  controller: _presionController,
                                  decoration: const InputDecoration(
                                    counterText: "",
                                    counterStyle: TextStyle(
                                      height: double.minPositive,
                                    ),
                                  ),
                                  inputFormatters: [
                                    DecimalTextInputFormatter()
                                  ],
                                  onChanged: (val) => setState(() {
                                    if(val.isEmpty){
                                      _valPresion = 0;
                                    }else{
                                      _valPresion = double.parse(val);
                                    }

                                    _calcAtenuador();
                                  }),
                                ),
                                Positioned(
                                  left: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.remove,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valPresion = _valPresion - 0.00000001;
                                      if(_valPresion < 0){
                                        _valPresion = 0;
                                      }

                                      _presionController.text = _valPresion.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }) ,
                                  ),
                                ),
                                Positioned(
                                  right: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.add,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valPresion = _valPresion + 0.00000001;
                                      if(_valPresion > 9999){
                                        _valPresion = 9999;
                                      }

                                      _presionController.text = _valPresion.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }),
                                  ),
                                )
                              ],
                            ),
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        DropdownButton<String>(
                          focusColor: Colors.transparent,
                          value: _unidadPresion,
                          onChanged: (val) => setState(() {
                            _unidadPresion = val!;
                            _calcAtenuador();
                          }),
                          items: _presionUnidades.map((e) => DropdownMenuItem<String>(
                            child: Text(
                              e,
                              style: GoogleFonts.roboto(
                                fontSize: 18.0,
                              ),
                            ),
                            value: e,
                          )).toList(),
                        )
                      ],
                    )
                  ],
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Potencia absorbida (Bhp):',
                      style: GoogleFonts.roboto(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    Row(
                      children: [
                        Expanded(
                          child: SizedBox(
                            height: 64.0,
                            width: double.infinity,
                            child: Stack(
                              alignment: Alignment.center,
                              children: [
                                TextField(
                                  textAlign: TextAlign.center,
                                  controller: _potenciaController,
                                  decoration: const InputDecoration(
                                    counterText: "",
                                    counterStyle: TextStyle(
                                      height: double.minPositive,
                                    ),
                                  ),
                                  inputFormatters: [
                                    DecimalTextInputFormatter()
                                  ],
                                  onChanged: (val) => setState(() {
                                    if(val.isEmpty){
                                      _valPotencia = 0;
                                    }else{
                                      _valPotencia = double.parse(val);
                                    }

                                    _calcAtenuador();
                                  }),
                                ),
                                Positioned(
                                  left: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.remove,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valPotencia = _valPotencia - 0.00000001;
                                      if(_valPotencia < 0){
                                        _valPotencia = 0;
                                      }

                                      _potenciaController.text = _valPotencia.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }) ,
                                  ),
                                ),
                                Positioned(
                                  right: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.add,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valPotencia = _valPotencia + 0.00000001;
                                      if(_valPotencia > 9999){
                                        _valPotencia = 9999;
                                      }

                                      _potenciaController.text = _valPotencia.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }),
                                  ),
                                )
                              ],
                            ),
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        DropdownButton<String>(
                          focusColor: Colors.transparent,
                          value: _unidadPotencia,
                          onChanged: (val) => setState(() {
                            _unidadPotencia = val!;
                            _calcAtenuador();
                          }),
                          items: _potenciaUnidades.map((e) => DropdownMenuItem<String>(
                            child: Text(
                              e,
                              style: GoogleFonts.roboto(
                                fontSize: 18.0,
                              ),
                            ),
                            value: e,
                          )).toList(),
                        )
                      ],
                    )
                  ],
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Diámetro del ventilador:',
                      style: GoogleFonts.roboto(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    Row(
                      children: [
                        Expanded(
                          child: SizedBox(
                            height: 64.0,
                            width: double.infinity,
                            child: Stack(
                              alignment: Alignment.center,
                              children: [
                                TextField(
                                  textAlign: TextAlign.center,
                                  controller: _diametroController,
                                  decoration: const InputDecoration(
                                    counterText: "",
                                    counterStyle: TextStyle(
                                      height: double.minPositive,
                                    ),
                                  ),
                                  inputFormatters: [
                                    DecimalTextInputFormatter()
                                  ],
                                  onChanged: (val) => setState(() {
                                    if(val.isEmpty){
                                      _valDiametro = 0;
                                    }else{
                                      _valDiametro = double.parse(val);
                                    }

                                    _calcAtenuador();
                                  }),
                                ),
                                Positioned(
                                  left: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.remove,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valDiametro = _valDiametro - 0.00000001;
                                      if(_valDiametro < 0){
                                        _valDiametro = 0;
                                      }

                                      _diametroController.text = _valDiametro.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }) ,
                                  ),
                                ),
                                Positioned(
                                  right: 0.0,
                                  child: IconButton(
                                    icon: const Icon(
                                      Icons.add,
                                      color: Colors.black45,
                                    ),
                                    onPressed: () => setState(() {
                                      _valDiametro = _valDiametro + 0.00000001;
                                      if(_valDiametro > 9999){
                                        _valDiametro = 9999;
                                      }

                                      _diametroController.text = _valDiametro.toStringAsFixed(8);
                                      _calcAtenuador();
                                    }),
                                  ),
                                )
                              ],
                            ),
                          ),
                        ),
                        const SizedBox(width: 8.0),
                        DropdownButton<String>(
                          focusColor: Colors.transparent,
                          value: _unidadDiametro,
                          onChanged: (val) => setState(() {
                            _unidadDiametro = val!;
                            _calcAtenuador();
                          }),
                          items: _diametroUnidades.map((e) => DropdownMenuItem<String>(
                            child: Text(
                              e,
                              style: GoogleFonts.roboto(
                                fontSize: 18.0,
                              ),
                            ),
                            value: e,
                          )).toList(),
                        )
                      ],
                    )
                  ],
                ),
              ),
              const SizedBox(height: 16.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Row(
                  children: [
                    Text(
                      'Curva NC:',
                      style: GoogleFonts.roboto(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                    const SizedBox(width: 8.0),
                    Expanded(
                      child: DropdownButton<String>(
                        focusColor: Colors.transparent,
                        value: _curva,
                        onChanged: (val) => setState(() {
                          _curva = val!;
                          _calcAtenuador();
                        }),
                        items: _curvas.map((e) => DropdownMenuItem<String>(
                          child: Text(
                            e,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                            ),
                          ),
                          value: e,
                        )).toList(),
                        isExpanded: true,
                      ),
                    ),
                  ],
                ),
              ),
              AnimatedCrossFade(
                firstChild: Container(),
                secondChild: _enableResults ? _calcTable() : Container(),
                duration: const Duration(milliseconds: 250),
                crossFadeState: !_enableResults ? CrossFadeState.showFirst : CrossFadeState.showSecond,
              ),
              const SizedBox(height: 32.0),
              Container(
                margin: const EdgeInsets.symmetric(
                  horizontal: 32.0,
                ),
                child: Column(
                  children: [
                    MaterialButton(
                      elevation: 4,
                      padding: const EdgeInsets.symmetric(vertical: 8.0),
                      minWidth: _screenSize.width - 32,
                      color: const Color(0xFFFF0000),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Image.asset(
                            "assets/guardar.png",
                            width: 32.0,
                          ),
                          const SizedBox(width: 8.0),
                          const Text(
                            "Guardar y regresar",
                            style: TextStyle(
                              fontFamily: "Helvetica Neue Black Cond",
                              color: Colors.white,
                              fontSize: 28.0,
                            ),
                          )
                        ],
                      ),
                      onPressed: () async{
                        Map<String, String> arrDatosDeEntrada = {};

                        arrDatosDeEntrada['TipoVentilador'] = _tipoVentilador;
                        arrDatosDeEntrada['ModeloVentilador'] = _modeloVentilador;
                        arrDatosDeEntrada['Caudal'] = "${_valCaudal.toStringAsFixed(8)} $_unidadCaudal";
                        arrDatosDeEntrada['PresionEstatica'] = "${_valPresion.toStringAsFixed(8)} $_unidadPresion";
                        arrDatosDeEntrada['PotenciaAbsorbida'] = "${_valPotencia.toStringAsFixed(8)} $_unidadPotencia";
                        arrDatosDeEntrada['Diametro'] = "${_valDiametro.toStringAsFixed(8)} $_unidadDiametro";

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

                        final jsonInfoArr = {
                          "arrDatosDeEntrada" : arrDatosDeEntrada,
                          "frecuencias": _calculos['frecuencias'],
                          "arrLwFinal": _calculos['LW'],
                          "sumaLogaritmicaLwFinal": _calculos['LWdB'],
                          "arrLwA": _calculos['LWA'],
                          "sumaLogaritmicaLwA": _calculos['LWAdB'],
                          "presionSonora": _calculos['presionSonora'],
                          "arrSumaLog": _calculos['ALW'],
                          "sumaLogaritmicaLwFinalVa": _calculos['ALWdB'],
                          "arrEspectroResultante": _calculos['ALWA'],
                          "sumaLogaritmicaLwAVa": _calculos['ALWAdB'],
                          "presionSonoraVa": _calculos['presionSonoraA'],
                          "modelo": _calculos['modeloAtenuador'],
                          "longitud": _calculos['longitudAtenuador'],
                        };
                        final infoStr = jsonEncode(jsonInfoArr);

                        final guardado = await _cambiarDatos(infoStr, "", _enableResults ? "F" : "C");
                        if(guardado){
                          Navigator.pop(context);
                        }else{
                          Fluttertoast.showToast(
                            msg: "Hubo un error al intentar guardar el proyecto, intentelo de nuevo más tarde.",
                            toastLength: Toast.LENGTH_SHORT,
                            timeInSecForIosWeb: 4,
                            gravity: ToastGravity.CENTER,
                            webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                          );
                        }
                      },
                    ),
                    const SizedBox(height: 16.0),
                    MaterialButton(
                      elevation: 4,
                      padding: const EdgeInsets.symmetric(vertical: 8.0),
                      minWidth: _screenSize.width - 32,
                      color: const Color(0xFFFF0000),
                      disabledColor: Colors.grey,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: const [
                          Icon(
                            Icons.print,
                            color: Colors.white,
                            size: 32.0,
                          ),
                          SizedBox(width: 8.0),
                          Text(
                            "Imprimir resultados",
                            style: TextStyle(
                              fontFamily: "Helvetica Neue Black Cond",
                              color: Colors.white,
                              fontSize: 28.0,
                            ),
                          ),
                        ],
                      ),
                      onPressed: _enableResults ? () async{
                        final jsonInfoArr = {
                          "arrDatosDeEntrada" : _calculos['arrDatosDeEntrada'],
                          "frecuencias": _calculos['frecuencias'],
                          "arrLwFinal": _calculos['LW'],
                          "sumaLogaritmicaLwFinal": _calculos['LWdB'],
                          "arrLwA": _calculos['LWA'],
                          "sumaLogaritmicaLwA": _calculos['LWAdB'],
                          "presionSonora": _calculos['presionSonora'],
                          "arrSumaLog": _calculos['ALW'],
                          "sumaLogaritmicaLwFinalVa": _calculos['ALWdB'],
                          "arrEspectroResultante": _calculos['ALWA'],
                          "sumaLogaritmicaLwAVa": _calculos['ALWAdB'],
                          "presionSonoraVa": _calculos['presionSonoraA'],
                          "modelo": _calculos['modeloAtenuador'],
                          "longitud": _calculos['longitudAtenuador'],
                        };

                        final infoStr = jsonEncode(jsonInfoArr);

                        final ruta = {
                          "idUsuario": widget.idUsuario,
                          "idProyecto": widget.idProyecto,
                          "noProyecto": widget.noProyecto
                        };

                        final rutab64 = base64Encode(utf8.encode(jsonEncode(ruta)));

                        final infoPDF = base64Encode(utf8.encode(jsonEncode({
                          "ruta": rutab64,
                          "infoCalculo": base64Encode(utf8.encode(infoStr))
                        })));

                        final urlArch = await _pdfProvider.fetchAtenuador(infoPDF, 'atenuador');
                        final task = TaskInfo(name: widget.idProyecto, link: urlArch);
                        _requestDownload(task);

                        final guardado = await _cambiarDatos(infoStr, urlArch, _enableResults ? "F" : "C");
                        if(!guardado){
                          Fluttertoast.showToast(
                            msg: "Hubo un error al intentar guardar el proyecto, intentelo de nuevo más tarde.",
                            toastLength: Toast.LENGTH_SHORT,
                            timeInSecForIosWeb: 4,
                            gravity: ToastGravity.CENTER,
                            webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                          );
                        }
                      } : null,
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 32.0),
            ],
          ),
        ),
      ),
    );
  }

  void _calcAtenuador() async => setState(() {
    if(_tipoVentilador.isEmpty){
      _enableResults = false;
    }else{
      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];
      Map<String, String> arrDatosDeEntrada = {};

      arrDatosDeEntrada['TipoVentilador'] = _tipoVentilador;
      arrDatosDeEntrada['ModeloVentilador'] = _modeloVentilador;
      arrDatosDeEntrada['Caudal'] = "${_valCaudal.toStringAsFixed(8)} $_unidadCaudal";
      arrDatosDeEntrada['PresionEstatica'] = "${_valPresion.toStringAsFixed(8)} $_unidadPresion";
      arrDatosDeEntrada['PotenciaAbsorbida'] = "${_valPotencia.toStringAsFixed(8)} $_unidadPotencia";
      arrDatosDeEntrada['Diametro'] = "${_valDiametro.toStringAsFixed(8)} $_unidadDiametro";

      Ventilador arrDatosVentilador = Ventilador();
      for (var vent in _ventiladores) {
        if(vent.tipo == _tipoVentilador){
          if(vent.desc == _modeloVentilador){
            arrDatosVentilador = vent;
          }
        }
      }

      double vCaudal = 0;
      switch(_unidadCaudal){
        case 'M3/S': vCaudal = _valCaudal / 0.0004719; break;
        case 'M3/MIN': vCaudal = _valCaudal / 0.028314; break;
        case 'M3/H': vCaudal = _valCaudal / 1.699011; break;
        case 'L/S': vCaudal = _valCaudal * 2.119; break;
        case 'L/MIN': vCaudal = _valCaudal / 28.32; break;
        case 'L/H': vCaudal = _valCaudal / 1699; break;
        case 'CM3/S': vCaudal = _valCaudal / 471.9; break;
        case 'CM3/MIN': vCaudal = _valCaudal / 28314; break;
        case 'CM3/H': vCaudal = _valCaudal / 1698840; break;
        case 'GALON/S': vCaudal = _valCaudal / 0.12467532; break;
        case 'GALON/MIN': vCaudal = _valCaudal / 7.4805195566834; break;
        case 'GALON/H': vCaudal = _valCaudal / 448.8311734; break;
        case 'CFM': vCaudal = _valCaudal; break;
      }

      double vPresionE = 0;
      switch(_unidadPresion){
        case 'MPA': vPresionE = _valPresion * 401.47; break;
        case 'KPA': vPresionE = _valPresion * 4.0147; break;
        case 'PA': vPresionE = _valPresion * 0.0040147; break;
        case 'BAR': vPresionE = _valPresion * 401.865; break;
        case 'M CA': vPresionE = _valPresion * 39.166667; break;
        case 'CM CA': vPresionE = _valPresion * 0.39166667; break;
        case 'MM CA': vPresionE = _valPresion * 0.039166667; break;
        case 'IN HG': vPresionE = _valPresion / 0.0735541043; break;
        case 'CM HG': vPresionE = _valPresion / 0.18682743044; break;
        case 'MM HG': vPresionE = _valPresion / 0.018682743044; break;
        case 'TORR': vPresionE = _valPresion * 0.5352533071; break;
        case 'INWG': vPresionE = _valPresion; break;
      }

      double vPotenciaA = 0;
      switch(_unidadPotencia){
        case 'HP': vPotenciaA = _valPotencia / 13.1549; break;
        case 'J/S': vPotenciaA = _valPotencia / 9809.5; break;
        case 'KCAL/H': vPotenciaA = _valPotencia / 8434.65; break;
        case 'KW': vPotenciaA = _valPotencia / 9.8095; break;
        case 'WATT': vPotenciaA = _valPotencia / 9809.5; break;
        case 'PIE-LIBRA(S)': vPotenciaA = _valPotencia / 7235.12; break;
        case 'PIE-LIBRA(M)': vPotenciaA = _valPotencia / 434106.95; break;
        case 'BHP': vPotenciaA = _valPotencia; break;
      }

      double vDiametro = 0;
      switch(_unidadDiametro){
        case 'MM': vDiametro = (_valDiametro * 3.291) / 1000; break;
        case 'CM': vDiametro = (_valDiametro * 3.291) / 100; break;
        case 'DM': vDiametro = (_valDiametro * 3.291) / 10; break;
        case 'M': vDiametro = _valDiametro * 3.291; break;
        case 'MI': vDiametro = _valDiametro * 5280; break;
        case 'YARDA': vDiametro = _valDiametro / 3; break;
        case 'INCH': vDiametro = _valDiametro * 0.083333; break;
        case 'FT': vDiametro = _valDiametro; break;
      }

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

      double a = ((pi) * (pow(vDiametro, 2))) / 4;
      double v = vCaudal / a;

      if(v.isNaN || v.isInfinite){
        _enableResults = false;
        return;
      }

      Map<String, String> arrLw = {};
      Map<String, double> arrKw = {};

      for (var indice in arrFrecuencias) {
        String frecuencia = indice;
        double kw = (10 * _log10(vCaudal)) + (20 * _log10(vPresionE));
        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 = {};
      arrLw.forEach((key, value) {
        String valorLw = arrLw[key]!;
        double valorKw = arrKw[key]!;

        double lwFinal = valorKw + double.parse(valorLw);
        arrLwFinal[key] = lwFinal;
      });

      Map<String, double> arrLwA = {};
      for (var element in arrPonderanciaA) {
        double valorLwFinal = arrLwFinal[arrFrecuencias[arrPonderanciaA.indexOf(element)]]!;
        double valorPonderancia = element;

        double lwA = valorLwFinal + valorPonderancia;
        arrLwA[arrFrecuencias[arrPonderanciaA.indexOf(element)]] = lwA;
      }

      Map<String, double> arrLwAVentiladorSeleccionado = {};
      for (var element in arrCurvaNC) {
        double valorLwFinal = arrLwFinal[arrFrecuencias[arrCurvaNC.indexOf(element)]]!;
        double valorCurvaNC = element.toDouble();

        double lwAVentilador = valorLwFinal - valorCurvaNC;
        arrLwAVentiladorSeleccionado[arrFrecuencias[arrCurvaNC.indexOf(element)]] = lwAVentilador;
      }

      double vAtenuador100Hz;

      if(arrLwAVentiladorSeleccionado.isNotEmpty){
        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,
        );
        _enableResults = false;
        return;
      }

      double diametroTmp = vDiametro * 304.8;

      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 = {};

      for (var element in _atenuacion) {
        String idAtenuador = element.idatenuacion!;
        String vDiametroAte = element.diametro!;
        String v1000Hz = element.the1000Hz!;

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

      Map<String, double> arrDiferencia = {};
      Map<String, double> arrDiferenciaSort = {};
      String idAtenuadorSelect;

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

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

          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,
        );
        _enableResults = false;
        return;
      }

      Atenuacion arrAtenuador = Atenuacion();

      for (var element in _atenuacion) {
        String idAtenuador = element.idatenuacion!;

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

      Map<String, double> arrLwAVentilador = {};

      for (var element in arrFrecuencias) {
        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);
        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";
        }
      }else{
        _enableResults = false;
        return;
      }

      PotenciaSonora arrPotenciaSonoraSelect = PotenciaSonora();

      for (var element in _potenciaSonora) {
        PotenciaSonora arrTmpPotencia = element;
        String vFtMin = element.ftmin!;

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

      Map<String, String> arrSonidoRegenerado = {};

      if(arrAtenuador1000Hz.isNotEmpty){
        for (var element in arrFrecuencias) {
          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,
        );
        _enableResults = false;
        return;
      }

      Map<String, double> arrCorreccionArea = {};

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

      Map<String, double> arrSonidoMasCorreccion = {};

      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;
        arrSonidoMasCorreccion[frecuencia] = sonidoMasCorreccion;
      }

      Map<String, double> arrSumaLog = {};

      for(int i = 0; i < arrFrecuencias.length; i++){
        if(arrLwAVentilador.isNotEmpty){
          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((pow(10, (arrLwAVentilador[frecuencia]!/10))) + (pow(10, (potSonora/10))).toDouble()));
          arrSumaLog[frecuencia] = sumaLog;
        }
      }

      Map<String, double> arrEspectroResultante = {};

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

        if(arrSumaLog.isNotEmpty && arrPonderanciaA.isNotEmpty){
          double espectroResultante = arrSumaLog[frecuencia]! + arrPonderanciaA[i];
          arrEspectroResultante[frecuencia] = espectroResultante;
        }
      }

      double sumaLogaritmica = 0;

      if(arrEspectroResultante.isNotEmpty){
        sumaLogaritmica = 10 * (_log10(pow(10, (arrEspectroResultante["63Hz"]!/10)) + pow(10, (arrEspectroResultante["125Hz"]!/10)).toDouble()
            + pow(10, (arrEspectroResultante["250Hz"]!/10)) + pow(10, (arrEspectroResultante["500Hz"]!/10)).toDouble()
            + pow(10, (arrEspectroResultante["1000Hz"]!/10)) + pow(10, (arrEspectroResultante["2000Hz"]!/10)).toDouble()
            + pow(10, (arrEspectroResultante["4000Hz"]!/10)) + pow(10, (arrEspectroResultante["8000Hz"]!/10)).toDouble()
        ));
      }

      double sumaLogaritmicaLwFinal = 0.0;

      if(arrLwFinal.isNotEmpty){
        sumaLogaritmicaLwFinal = 10 * (_log10(pow(10, (arrLwFinal["63Hz"]!/10)) + pow(10, (arrLwFinal["125Hz"]!/10)).toDouble()
            + pow(10, (arrLwFinal["250Hz"]!/10)) + pow(10, (arrLwFinal["500Hz"]!/10)).toDouble()
            + pow(10, (arrLwFinal["1000Hz"]!/10)) + pow(10, (arrLwFinal["2000Hz"]!/10)).toDouble()
            + pow(10, (arrLwFinal["4000Hz"]!/10)) + pow(10, (arrLwFinal["8000Hz"]!/10)).toDouble()
        ));
      }

      double sumaLogaritmicaLwA = 0.0;

      if(arrLwA.isNotEmpty){
        sumaLogaritmicaLwA = 10 * (_log10(pow(10, (arrLwA["63Hz"]!/10)) + pow(10, (arrLwA["125Hz"]!/10)).toDouble()
            + pow(10, (arrLwA["250Hz"]!/10)) + pow(10, (arrLwA["500Hz"]!/10)).toDouble()
            + pow(10, (arrLwA["1000Hz"]!/10)) + pow(10, (arrLwA["2000Hz"]!/10)).toDouble()
            + pow(10, (arrLwA["4000Hz"]!/10)) + pow(10, (arrLwA["8000Hz"]!/10)).toDouble()
        ));
      }

      double resultadoPresionSonora = sumaLogaritmicaLwFinal - (10 * _log10((4*pi)*(pow(1.5, 2)/2)));
      double resultadoPresionSonoraA = sumaLogaritmicaLwA - (10 * _log10((4 * pi) * (pow(1.5, 2) / 2)));
      double sumaLogaritmicaLwAtenuado = 0.0;

      if(arrSumaLog.isNotEmpty){
        sumaLogaritmicaLwAtenuado = 10 * (_log10(pow(10, (arrSumaLog["63Hz"]!/10)) + pow(10, (arrSumaLog["125Hz"]!/10)).toDouble()
            + pow(10, (arrSumaLog["250Hz"]!/10)) + pow(10, (arrSumaLog["500Hz"]!/10)).toDouble()
            + pow(10, (arrSumaLog["1000Hz"]!/10)) + pow(10, (arrSumaLog["2000Hz"]!/10)).toDouble()
            + pow(10, (arrSumaLog["4000Hz"]!/10)) + pow(10, (arrSumaLog["8000Hz"]!/10)).toDouble()
        ));
      }

      double sumaLogaritmicaEspectroResultante = 0.0;

      if(arrEspectroResultante.isNotEmpty){
        sumaLogaritmicaEspectroResultante = 10 * (_log10(pow(10, (arrEspectroResultante["63Hz"]!/10)) + pow(10, (arrEspectroResultante["125Hz"]!/10)).toDouble()
            + pow(10, (arrEspectroResultante["250Hz"]!/10)) + pow(10, (arrEspectroResultante["500Hz"]!/10)).toDouble()
            + pow(10, (arrEspectroResultante["1000Hz"]!/10)) + pow(10, (arrEspectroResultante["2000Hz"]!/10)).toDouble()
            + pow(10, (arrEspectroResultante["4000Hz"]!/10)) + pow(10, (arrEspectroResultante["8000Hz"]!/10)).toDouble()
        ));
      }

      double resultadoPresionSonoraAA = sumaLogaritmicaLwAtenuado - (10 * _log10((4 * pi) * (pow(1.5, 2) / 2)));
      double resultadoPresionSonoraBB = sumaLogaritmicaEspectroResultante - (10 * _log10((4 * pi) * (pow(1.5, 2) / 2)));

      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;
      }

      _calculos['frecuencias'] = arrFrecuencias;
      _calculos['LW'] = fArrLwFinal.values.toList();
      _calculos['LWdB'] = sumaLogaritmicaLwFinal;
      _calculos['LWA'] = fArrLwA.values.toList();
      _calculos['LWAdB'] = sumaLogaritmicaLwA;
      _calculos['presionSonora'] = resultadoPresionSonora;
      _calculos['ALW'] = arrSumaLog.values.toList();
      _calculos['ALWdB'] = sumaLogaritmicaLwAtenuado;
      _calculos['ALWA'] = arrEspectroResultante.values.toList();
      _calculos['ALWAdB'] = sumaLogaritmicaEspectroResultante;
      _calculos['presionSonoraA'] = resultadoPresionSonoraAA;
      _calculos['modeloAtenuador'] = arrAtenuador.modelo;
      _calculos['longitudAtenuador'] = arrAtenuador.longitud;
      _calculos['arrDatosDeEntrada'] = arrDatosDeEntrada;

      _enableResults = true;
    }
  });

  Widget _calcTable(){
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.symmetric(horizontal: 32.0),
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.black12,
              width: 1.0,
            ),
          ),
          margin: const EdgeInsets.only(top: 16.0),
          width: 1024,
          child: Column(
            children: [
              Container(
                padding: const EdgeInsets.all(16.0),
                child: Text(
                  "Espectro de Potencia Sonora Ventilador Lw",
                  textAlign: TextAlign.center,
                  style: GoogleFonts.roboto(
                    fontSize: 18.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['frecuencias']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['frecuencias'][i]}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "Lw (dB)",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['LW']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['LW'][i].toStringAsFixed(2)}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "${_calculos['LWdB'].toStringAsFixed(2)}",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                padding: const EdgeInsets.all(16.0),
                child: Text(
                  "Espectro de Potencia Sonora Ventilador Ponderación A Lw(A)",
                  textAlign: TextAlign.center,
                  style: GoogleFonts.roboto(
                    fontSize: 18.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['frecuencias']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['frecuencias'][i]}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "Lw (dB)",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['LWA']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['LWA'][i].toStringAsFixed(2)}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "${_calculos['LWAdB'].toStringAsFixed(2)}",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        child: Text(
                          "Presión Sonora",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      flex: 3,
                    ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "${_calculos['presionSonora'].toStringAsFixed(2)}",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      flex: 6,
                    ),
                  ],
                ),
              ),
              Container(
                padding: const EdgeInsets.all(16.0),
                child: Text(
                  "Espectro de Potencia Sonora Ventilador con Atenuador Lw",
                  textAlign: TextAlign.center,
                  style: GoogleFonts.roboto(
                    fontSize: 18.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['frecuencias']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['frecuencias'][i]}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "Lw (dB)",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['ALW']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['ALW'][i].toStringAsFixed(2)}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "${_calculos['ALWdB'].toStringAsFixed(2)}",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                padding: const EdgeInsets.all(16.0),
                child: Text(
                  "Espectro de Potencia Sonora Ventilador con Atenuador Lw(A)",
                  textAlign: TextAlign.center,
                  style: GoogleFonts.roboto(
                    fontSize: 18.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['frecuencias']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['frecuencias'][i]}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "Lw (dB)",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    for(int i = 0; i < _calculos['ALWA']!.length; i++)
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.all(16.0),
                          decoration: BoxDecoration(
                            border: Border(
                              left: i > 0 ? const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ) : const BorderSide(color: Colors.transparent, width: 0.0),
                              right: const BorderSide(
                                color: Colors.black12,
                                width: 1.0,
                              ),
                            ),
                          ),
                          child: Text(
                            "${_calculos['ALWA'][i].toStringAsFixed(2)}",
                            textAlign: TextAlign.center,
                            style: GoogleFonts.roboto(
                              fontSize: 18.0,
                            ),
                          ),
                        ),
                      ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "${_calculos['ALWAdB'].toStringAsFixed(2)}",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                    bottom: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        child: Text(
                          "Presión Sonora",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      flex: 3,
                    ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "${_calculos['presionSonoraA'].toStringAsFixed(2)}",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      flex: 6,
                    ),
                  ],
                ),
              ),
              Container(
                padding: const EdgeInsets.all(16.0),
                child: Text(
                  "Datos del Atenuador Seleccionado",
                  textAlign: TextAlign.center,
                  style: GoogleFonts.roboto(
                    fontSize: 18.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              Container(
                decoration: const BoxDecoration(
                  border: Border(
                    top: BorderSide(
                      color: Colors.black12,
                      width: 1.0,
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        child: Text(
                          "Modelo",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                      flex: 3,
                    ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          _calculos['modeloAtenuador'],
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                      flex: 2,
                    ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          "Longitud del Atenuador",
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                      flex: 3,
                    ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.all(16.0),
                        decoration: const BoxDecoration(
                          border: Border(
                            left: BorderSide(
                              color: Colors.black12,
                              width: 1.0,
                            ),
                          ),
                        ),
                        child: Text(
                          _calculos['longitudAtenuador'],
                          textAlign: TextAlign.center,
                          style: GoogleFonts.roboto(
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                      flex: 1,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  double _log10(double num) => log(num) / ln10;

  Map<String, double> _sortMapItems(Map<String, double> toSort){
    Map<String, double> tmp = {};
    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;
  }

  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];
  }
}
