# Imports do próprio módulo
from inewave.config import SUBMERCADOS
from inewave._utils.registros import RegistroAn, RegistroFn, RegistroIn
from inewave._utils.bloco import Bloco
from inewave._utils.leiturablocos import LeituraBlocos

# Imports de módulos externos
from typing import IO, List
import numpy as np  # type: ignore


class BlocoNomeCaso(Bloco):
    """
    Bloco com o nome do caso, existente
    no arquivo `dger.dat` do NEWAVE.
    """

    def __init__(self):

        super().__init__("", "", True)

        self._dados = ""

    # Override
    def le(self, arq: IO):
        reg = RegistroAn(80)
        self._dados = reg.le_registro(self._linha_inicio, 0)

    # Override
    def escreve(self, arq: IO):
        arq.write(self._dados + "\n")


class BlocoTipoExecucao(Bloco):
    """
    Bloco com o tipo de execução do caso,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "TIPO DE EXECUCAO"
    str_fim = "   (1:EXECUCAO COMPLETA; 0:SIMULACAO FINAL)"

    def __init__(self):

        super().__init__(
            BlocoTipoExecucao.str_inicio, BlocoTipoExecucao.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoTipoExecucao.str_inicio.ljust(21)}"
            + f"{dado}{BlocoTipoExecucao.str_fim}\n"
        )
        arq.write(linha)


class BlocoDuracaoPeriodo(Bloco):
    """
    Bloco com a duração do período de execução,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DURACAO DO PERIODO"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoDuracaoPeriodo.str_inicio, BlocoDuracaoPeriodo.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoDuracaoPeriodo.str_inicio.ljust(21)}"
            + f"{dado}{BlocoDuracaoPeriodo.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumAnosEstudo(Bloco):
    """
    Bloco com o número de anos no período de estudo,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No. DE ANOS DO EST"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoNumAnosEstudo.str_inicio, BlocoNumAnosEstudo.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumAnosEstudo.str_inicio.ljust(21)}"
            + f"{dado}{BlocoNumAnosEstudo.str_fim}\n"
        )
        arq.write(linha)


class BlocoMesInicioPreEstudo(Bloco):
    """
    Bloco com o mês de início do pré-estudo,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "MES INICIO PRE-EST"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoMesInicioPreEstudo.str_inicio,
            BlocoMesInicioPreEstudo.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoMesInicioPreEstudo.str_inicio.ljust(21)}"
            + f"{dado}{BlocoMesInicioPreEstudo.str_fim}\n"
        )
        arq.write(linha)


class BlocoMesInicioEstudo(Bloco):
    """
    Bloco com o mês de início do período de estudo,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "MES INICIO DO ESTUDO"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoMesInicioEstudo.str_inicio, BlocoMesInicioEstudo.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoMesInicioEstudo.str_inicio.ljust(21)}"
            + f"{dado}{BlocoMesInicioEstudo.str_fim}\n"
        )
        arq.write(linha)


class BlocoAnoInicioEstudo(Bloco):
    """
    Bloco com o ano do início do período de estudo
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "ANO INICIO DO ESTUDO"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoAnoInicioEstudo.str_inicio, BlocoAnoInicioEstudo.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoAnoInicioEstudo.str_inicio.ljust(21)}"
            + f"{dado}{BlocoAnoInicioEstudo.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumAnosPreEstudo(Bloco):
    """
    Bloco com o número de anos do período pré-estudo,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No. DE ANOS PRE"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoNumAnosPreEstudo.str_inicio,
            BlocoNumAnosPreEstudo.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumAnosPreEstudo.str_inicio.ljust(21)}"
            + f"{dado}{BlocoNumAnosPreEstudo.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumAnosPosEstudo(Bloco):
    """
    Bloco com o número de anos do período pós-estudo,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No. DE ANOS POS"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoNumAnosPosEstudo.str_inicio,
            BlocoNumAnosPosEstudo.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumAnosPosEstudo.str_inicio.ljust(21)}"
            + f"{dado}{BlocoNumAnosPosEstudo.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumAnosPosEstudoSimFinal(Bloco):
    """
    Bloco com o número de anos do período pós-estudo na simulação final,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No. DE ANOS POS FINAL"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoNumAnosPosEstudoSimFinal.str_inicio,
            BlocoNumAnosPosEstudoSimFinal.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumAnosPosEstudoSimFinal.str_inicio.ljust(21)}"
            + f"{dado}{BlocoNumAnosPosEstudoSimFinal.str_fim}\n"
        )
        arq.write(linha)


class BlocoImprimeDados(Bloco):
    """
    Bloco com a opção de imprimir dados das usinas,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRIME DADOS"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoImprimeDados.str_inicio, BlocoImprimeDados.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoImprimeDados.str_inicio.ljust(21)}"
            + f"{dado}{BlocoImprimeDados.str_fim}\n"
        )
        arq.write(linha)


class BlocoImprimeMercados(Bloco):
    """
    Bloco com a opção de imprimir dados de mercados,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRIME MERCADOS"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoImprimeMercados.str_inicio, BlocoImprimeMercados.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoImprimeMercados.str_inicio.ljust(21)}"
            + f"{dado}{BlocoImprimeMercados.str_fim}\n"
        )
        arq.write(linha)


class BlocoImprimeEnergias(Bloco):
    """
    Bloco com a opção de imprimir dados das energias,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRIME ENERGIAS"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoImprimeEnergias.str_inicio, BlocoImprimeEnergias.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoImprimeEnergias.str_inicio.ljust(21)}"
            + f"{dado}{BlocoImprimeEnergias.str_fim}\n"
        )
        arq.write(linha)


class BlocoImprimeModeloEstocastico(Bloco):
    """
    Bloco com a opção de imprimir dados do modelo estocástico,
    de geração de cenários existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRIME M. ESTOCAS"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoImprimeModeloEstocastico.str_inicio,
            BlocoImprimeModeloEstocastico.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoImprimeModeloEstocastico.str_inicio.ljust(21)}"
            + f"{dado}{BlocoImprimeModeloEstocastico.str_fim}\n"
        )
        arq.write(linha)


class BlocoImprimeSubsistema(Bloco):
    """
    Bloco com a opção de imprimir dados dos subsistemas,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRIME SUBSISTEMA"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoImprimeSubsistema.str_inicio,
            BlocoImprimeSubsistema.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoImprimeSubsistema.str_inicio.ljust(21)}"
            + f"{dado}{BlocoImprimeSubsistema.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumMaxIteracoes(Bloco):
    """
    Bloco com o número máximo de iterações,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No MAX. DE ITER."
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoNumMaxIteracoes.str_inicio, BlocoNumMaxIteracoes.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumMaxIteracoes.str_inicio.ljust(21)}"
            + f"{dado}{BlocoNumMaxIteracoes.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumForwards(Bloco):
    """
    Bloco com o número de simulações forward,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No DE SIM. FORWARD"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoNumForwards.str_inicio, BlocoNumForwards.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumForwards.str_inicio.ljust(21)}"
            + f"{dado}{BlocoNumForwards.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumAberturas(Bloco):
    """
    Bloco com o número aberturas e se são consideradas
    aberturas variáveis, existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No DE ABERTURAS"
    str_fim = "(CONSIDERA ABERTURA VARIAVEL =0 NAO CONSIDERA, =1 CONSIDERA )"

    def __init__(self):

        super().__init__(
            BlocoNumAberturas.str_inicio, BlocoNumAberturas.str_fim, True
        )

        self._dados = 0

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoNumAberturas):
            return False
        bloco: BlocoNumAberturas = o
        return self._dados == bloco._dados

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        num_ab = str(self._dados).rjust(4)
        linha = f"{BlocoNumAberturas.str_inicio.ljust(21)}" + f"{num_ab}\n"
        arq.write(linha)


class BlocoNumSeriesSinteticas(Bloco):
    """
    Bloco com o número de séries sintéticas utilizadas,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No DE SERIES SINT."
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoNumSeriesSinteticas.str_inicio,
            BlocoNumSeriesSinteticas.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumSeriesSinteticas.str_inicio.ljust(21)}"
            + f"{dado}{BlocoNumSeriesSinteticas.str_fim}\n"
        )
        arq.write(linha)


class BlocoOrdemMaximaPARp(Bloco):
    """
    Bloco com a ordem máxima do modelo PAR(p),
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "ORDEM MAX. PAR(P)"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoOrdemMaximaPARp.str_inicio, BlocoOrdemMaximaPARp.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoOrdemMaximaPARp.str_inicio.ljust(21)}"
            + f"{dado}{BlocoOrdemMaximaPARp.str_fim}\n"
        )
        arq.write(linha)


class BlocoAnoInicialHistorico(Bloco):
    """
    Bloco com o ano inicial do histórico,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "ANO INICIAL HIST."
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoAnoInicialHistorico.str_inicio,
            BlocoAnoInicialHistorico.str_fim,
            True,
        )

        self._dados = [0, 0]

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoAnoInicialHistorico):
            return False
        bloco: BlocoAnoInicialHistorico = o
        return all([d1 == d2 for d1, d2 in zip(self._dados, bloco._dados)])

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados[0] = reg.le_registro(self._linha_inicio, 21)
        reg_flag = RegistroIn(1)
        self._dados[1] = reg_flag.le_registro(self._linha_inicio, 28)

    # Override
    def escreve(self, arq: IO):
        ano = str(self._dados[0]).rjust(4)
        flag = str(self._dados[1]).rjust(4)
        linha = (
            f"{BlocoAnoInicialHistorico.str_inicio.ljust(21)}"
            + f"{ano}{flag}{BlocoAnoInicialHistorico.str_fim}\n"
        )
        arq.write(linha)


class BlocoCalculaVolInicial(Bloco):
    """
    Bloco com o ano inicial do histórico,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CALCULA VOL.INICIAL"
    str_fim = "0=USA REG 20 ; 1= CALCULA EARM. INICIAL"

    def __init__(self):

        super().__init__(
            BlocoCalculaVolInicial.str_inicio,
            BlocoCalculaVolInicial.str_fim,
            True,
        )

        self._dados = 0

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoCalculaVolInicial):
            return False
        bloco: BlocoCalculaVolInicial = o
        return self._dados == bloco._dados

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(1)
        self._dados = reg.le_registro(self._linha_inicio, 24)

    # Override
    def escreve(self, arq: IO):
        calcula = str(self._dados).rjust(4)
        linha = (
            f"{BlocoCalculaVolInicial.str_inicio.ljust(21)}"
            + f"{calcula}   {BlocoCalculaVolInicial.str_fim}\n"
        )
        arq.write(linha)


class BlocoVolInicialSubsistema(Bloco):
    """
    Bloco com o ano inicial do histórico,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = " POR SUBSISTEMA"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoVolInicialSubsistema.str_inicio,
            BlocoVolInicialSubsistema.str_fim,
            True,
        )

        self._dados = np.zeros((len(SUBMERCADOS) + 1,), dtype=np.float64)

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoVolInicialSubsistema):
            return False
        bloco: BlocoVolInicialSubsistema = o
        return all([d1 == d2 for d1, d2 in zip(self._dados, bloco._dados)])

    # Override
    def le(self, arq: IO):
        reg = RegistroFn(5)
        self._dados = reg.le_linha_tabela(
            self._linha_inicio, 21, 2, len(SUBMERCADOS) + 1
        )

    # Override
    def escreve(self, arq: IO):
        dado = ""
        for i in range(len(self._dados)):
            d = f"{self._dados[i]:3.1f}  "
            dado += d.rjust(7)
        linha = (
            f"{BlocoVolInicialSubsistema.str_inicio.ljust(21)}"
            + f"{dado}{BlocoVolInicialSubsistema.str_fim}\n"
        )
        arq.write(linha)


class BlocoTolerancia(Bloco):
    """
    Bloco com a tolerância de convergência,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "TOLERANCIA      -%"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoTolerancia.str_inicio, BlocoTolerancia.str_fim, True
        )

        self._dados = 0.0

    # Override
    def le(self, arq: IO):
        reg = RegistroFn(5)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(f"{self._dados:2.1f}").rjust(5)
        linha = (
            f"{BlocoTolerancia.str_inicio.ljust(21)}"
            + f"{dado}{BlocoTolerancia.str_fim}\n"
        )
        arq.write(linha)


class BlocoTaxaDesconto(Bloco):
    """
    Bloco com a taxa de desconto,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "TAXA DE DESCONTO-%"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoTaxaDesconto.str_inicio, BlocoTaxaDesconto.str_fim, True
        )

        self._dados = 0.0

    # Override
    def le(self, arq: IO):
        reg = RegistroFn(5)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(f"{self._dados:2.1f}").rjust(5)
        linha = (
            f"{BlocoTaxaDesconto.str_inicio.ljust(21)}"
            + f"{dado}{BlocoTaxaDesconto.str_fim}\n"
        )
        arq.write(linha)


class BlocoTipoSimFinal(Bloco):
    """
    Bloco com a opção do tipo de simulação final,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "TIPO SIMUL. FINAL"
    str_fim = "(=0 NAO SIMULA; =1 S.SINT.; =2 S.HIST.; =3 CONSIST)"

    def __init__(self):

        super().__init__(
            BlocoTipoSimFinal.str_inicio, BlocoTipoSimFinal.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoTipoSimFinal.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoTipoSimFinal.str_fim}\n"
        )
        arq.write(linha)


class BlocoImpressaoOperacao(Bloco):
    """
    Bloco com a opção para impressão da operação detalhada,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRESSAO DA OPER"
    str_fim = "(=0 SINOPSE; =1 OP. DETALHADA)"

    def __init__(self):

        super().__init__(
            BlocoImpressaoOperacao.str_inicio,
            BlocoImpressaoOperacao.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoImpressaoOperacao.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoImpressaoOperacao.str_fim}\n"
        )
        arq.write(linha)


class BlocoImpressaoConvergencia(Bloco):
    """
    Bloco com a opção para impressão da convergência,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRESSAO DA CONVERG."
    str_fim = "(=0 CONVERGENCIA FINAL APENAS, =1 TOTAL)"

    def __init__(self):

        super().__init__(
            BlocoImpressaoConvergencia.str_inicio,
            BlocoImpressaoConvergencia.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoImpressaoConvergencia.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoImpressaoConvergencia.str_fim}\n"
        )
        arq.write(linha)


class BlocoIntervaloGravar(Bloco):
    """
    Bloco com a opção para impressão do intervalo para gravar,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "INTERVALO P/ GRAVAR"
    str_fim = "SERIES SIMULADAS ( 40  SERIES GRAVADAS )"

    def __init__(self):

        super().__init__(
            BlocoIntervaloGravar.str_inicio, BlocoIntervaloGravar.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoIntervaloGravar.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoIntervaloGravar.str_fim}\n"
        )
        arq.write(linha)


class BlocoMinIteracoes(Bloco):
    """
    Bloco com o número mínimo de iterações,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No. MIN. ITER."
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoMinIteracoes.str_inicio, BlocoMinIteracoes.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoMinIteracoes.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoMinIteracoes.str_fim}\n"
        )
        arq.write(linha)


class BlocoRacionamentoPreventivo(Bloco):
    """
    Bloco com o uso de racionamento preventivo,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "RACIONAMENTO PREVENT."
    str_fim = "(=0 NAO CONSIDERA NA SIMULACAO FINAL; 1=CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoRacionamentoPreventivo.str_inicio,
            BlocoRacionamentoPreventivo.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoRacionamentoPreventivo.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoRacionamentoPreventivo.str_fim}\n"
        )
        arq.write(linha)


class BlocoNumAnosManutUTE(Bloco):
    """
    Bloco com o número de anos considerados de manutenção de UTEs,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "No. ANOS MANUT.UTE'S"
    str_fim = "(=0 NAO CONSIDERA, =1 ANO, =2 ANOS)"

    def __init__(self):

        super().__init__(
            BlocoNumAnosManutUTE.str_inicio, BlocoNumAnosManutUTE.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoNumAnosManutUTE.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoNumAnosManutUTE.str_fim}\n"
        )
        arq.write(linha)


class BlocoTendenciaHidrologica(Bloco):
    """
    Bloco com o uso e a forma de uso da tendência hidrológica,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "TENDENCIA HIDROLOGICA"
    str_fim = "(1 FCF / 2 SF =0 NAO CONDIC., =1 P/ SUBSISTEMA, =2 P/ POSTO)"

    def __init__(self):

        super().__init__(
            BlocoTendenciaHidrologica.str_inicio,
            BlocoTendenciaHidrologica.str_fim,
            True,
        )

        self._dados = [0, 0]

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoTendenciaHidrologica):
            return False
        bloco: BlocoTendenciaHidrologica = o
        return all([d1 == d2 for d1, d2 in zip(self._dados, bloco._dados)])

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados[0] = reg.le_registro(self._linha_inicio, 21)
        self._dados[1] = reg.le_registro(self._linha_inicio, 26)

    # Override
    def escreve(self, arq: IO):
        uso = str(self._dados[0]).rjust(4)
        condic = str(self._dados[1]).rjust(4)
        linha = (
            f"{BlocoTendenciaHidrologica.str_inicio.ljust(21)}"
            + f"{uso} {condic}   {BlocoTendenciaHidrologica.str_fim}\n"
        )
        arq.write(linha)


class BlocoRestricaoItaipu(Bloco):
    """
    Bloco com a consideração das restrições de Itaipu,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "RESTRICA0 DE ITAIPU"
    str_fim = "(=0 NAO CONSIDERA, =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoRestricaoItaipu.str_inicio, BlocoRestricaoItaipu.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoRestricaoItaipu.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoRestricaoItaipu.str_fim}\n"
        )
        arq.write(linha)


class BlocoBid(Bloco):
    """
    Bloco com a consideração das restrições de Itaipu,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "BID"
    str_fim = "(=0 NAO CONSIDERA, =1 CONSIDERA)"

    def __init__(self):

        super().__init__(BlocoBid.str_inicio, BlocoBid.str_fim, True)

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoBid.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoBid.str_fim}\n"
        )
        arq.write(linha)


class BlocoPerdasTransmissao(Bloco):
    """
    Bloco com a consideração das perdas na transmissão,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "PERDAS P/ TRANSMISSAO"
    str_fim = "(=0 NAO CONSIDERA, =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoPerdasTransmissao.str_inicio,
            BlocoPerdasTransmissao.str_fim,
            True,
        )
        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoPerdasTransmissao.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoPerdasTransmissao.str_fim}\n"
        )
        arq.write(linha)


class BlocoElNino(Bloco):
    """
    Bloco com a consideração do El Nino,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "EL NINO"
    str_fim = "(=0 NAO CONSIDERA, =1 CONSIDERA)"

    def __init__(self):

        super().__init__(BlocoElNino.str_inicio, BlocoElNino.str_fim, True)

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoElNino.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoElNino.str_fim}\n"
        )
        arq.write(linha)


class BlocoEnso(Bloco):
    """
    Bloco com a consideração de ENSO,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "ENSO INDEX"
    str_fim = "(FUNCAO NAO IMPLEMENTADA)"

    def __init__(self):

        super().__init__(BlocoEnso.str_inicio, BlocoEnso.str_fim, True)

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoEnso.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoEnso.str_fim}\n"
        )
        arq.write(linha)


class BlocoDuracaoPorPatamar(Bloco):
    """
    Bloco com a consideração da duração por patamar,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DURACAO POR PATAMAR"
    str_fim = "(=0 SAZONAL, =1 VARIAVEL POR ANO)"

    def __init__(self):

        super().__init__(
            BlocoDuracaoPorPatamar.str_inicio,
            BlocoDuracaoPorPatamar.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoDuracaoPorPatamar.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoDuracaoPorPatamar.str_fim}\n"
        )
        arq.write(linha)


class BlocoOutrosUsosAgua(Bloco):
    """
    Bloco com a consideração dos outros usos da água,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "OUTROS USOS DA AGUA"
    str_fim = "(=0 NAO CONSIDERA, =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoOutrosUsosAgua.str_inicio, BlocoOutrosUsosAgua.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoOutrosUsosAgua.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoOutrosUsosAgua.str_fim}\n"
        )
        arq.write(linha)


class BlocoCorrecaoDesvio(Bloco):
    """
    Bloco com a consideração da correção do desvio,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CORRECAO DESVIO"
    str_fim = "(=0 CONSTANTE; =1 VARIAVEL COM O ARMAZENAMENTO)"

    def __init__(self):

        super().__init__(
            BlocoCorrecaoDesvio.str_inicio, BlocoCorrecaoDesvio.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoCorrecaoDesvio.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoCorrecaoDesvio.str_fim}\n"
        )
        arq.write(linha)


class BlocoCurvaAversao(Bloco):
    """
    Bloco com a consideração da curva de penalização por VminP,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "C.AVERSAO/PENAL.VMINP"
    str_fim = "(=0 SEM CAR E VMINP; =1  CAR E/OU VMINP)"

    def __init__(self):

        super().__init__(
            BlocoCurvaAversao.str_inicio, BlocoCurvaAversao.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoCurvaAversao.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoCurvaAversao.str_fim}\n"
        )
        arq.write(linha)


class BlocoTipoGeracaoENA(Bloco):
    """
    Bloco com a consideração do tipo de geração de ENA,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "TIPO DE GERACAO ENAS"
    str_fim = "(=0 RUIDOS FW SORTEADOS DA BW E COMPENSACAO CORREL.ESPACIAL; =1 COMPENS.BW; =2 COMPENS.BW E FW)"  # noqa

    def __init__(self):

        super().__init__(
            BlocoTipoGeracaoENA.str_inicio, BlocoTipoGeracaoENA.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoTipoGeracaoENA.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoTipoGeracaoENA.str_fim}\n"
        )
        arq.write(linha)


class BlocoRiscoDeficit(Bloco):
    """
    Bloco com o uso e a forma de consideração do risco de déficit,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "RISCO DE DEFICIT"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoRiscoDeficit.str_inicio, BlocoRiscoDeficit.str_fim, True
        )

        self._dados = [0, 0]

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoRiscoDeficit):
            return False
        bloco: BlocoRiscoDeficit = o
        return all([d1 == d2 for d1, d2 in zip(self._dados, bloco._dados)])

    # Override
    def le(self, arq: IO):
        reg = RegistroFn(4)
        self._dados[0] = reg.le_registro(self._linha_inicio, 21)
        self._dados[1] = reg.le_registro(self._linha_inicio, 27)

    # Override
    def escreve(self, arq: IO):
        prof1 = str(f"{self._dados[0]:2.1f}").rjust(4)
        prof2 = str(f"{self._dados[1]:2.1f}").rjust(4)
        linha = (
            f"{BlocoRiscoDeficit.str_inicio.ljust(21)}"
            + f"{prof1}  {prof2} {BlocoRiscoDeficit.str_fim}\n"
        )
        arq.write(linha)


class BlocoIteracaoParaSimFinal(Bloco):
    """
    Bloco com a consideração da iteração para simulação final,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "ITERACAO P/SIM.FINAL"
    str_fim = "(=0 CONSIDERA TODAS AS ITERACOES)"

    def __init__(self):

        super().__init__(
            BlocoIteracaoParaSimFinal.str_inicio,
            BlocoIteracaoParaSimFinal.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoIteracaoParaSimFinal.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoIteracaoParaSimFinal.str_fim}\n"
        )
        arq.write(linha)


class BlocoAgrupamentoLivre(Bloco):
    """
    Bloco com a consideração do agrupamento de intercâmbios,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "AGRUPAMENTO LIVRE"
    str_fim = "(=0 NAO CONSIDERA, =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoAgrupamentoLivre.str_inicio,
            BlocoAgrupamentoLivre.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoAgrupamentoLivre.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoAgrupamentoLivre.str_fim}\n"
        )
        arq.write(linha)


class BlocoEqualizacaoPenalInt(Bloco):
    """
    Bloco com a consideração da equalização da penalização de intercâmbios,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "EQUALIZACAO PEN.INT."
    str_fim = "(FLAG DESABILITADO)"

    def __init__(self):

        super().__init__(
            BlocoEqualizacaoPenalInt.str_inicio,
            BlocoEqualizacaoPenalInt.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoEqualizacaoPenalInt.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoEqualizacaoPenalInt.str_fim}\n"
        )
        arq.write(linha)


class BlocoRepresentacaoSubmot(Bloco):
    """
    Bloco com a consideração da representação de submotorização,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "REPRESENT.SUBMOT."
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA SUBSISTEMA, =2 CONSIDERA USINA)"  # noqa

    def __init__(self):

        super().__init__(
            BlocoRepresentacaoSubmot.str_inicio,
            BlocoRepresentacaoSubmot.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoRepresentacaoSubmot.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoRepresentacaoSubmot.str_fim}\n"
        )
        arq.write(linha)


class BlocoOrdenacaoAutomatica(Bloco):
    """
    Bloco com a consideração da ordenação automática,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "ORDENACAO AUTOMATICA"
    str_fim = "(=0 NAO CONSIDERA; =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoOrdenacaoAutomatica.str_inicio,
            BlocoOrdenacaoAutomatica.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoOrdenacaoAutomatica.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoOrdenacaoAutomatica.str_fim}\n"
        )
        arq.write(linha)


class BlocoConsideraCargaAdicional(Bloco):
    """
    Bloco com a consideração de cargas adicionais,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CONS. CARGA ADICIONAL"
    str_fim = "(=0 NAO CONSIDERA; =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoConsideraCargaAdicional.str_inicio,
            BlocoConsideraCargaAdicional.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoConsideraCargaAdicional.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoConsideraCargaAdicional.str_fim}\n"
        )
        arq.write(linha)


class BlocoDeltaZSUP(Bloco):
    """
    Bloco com a tolerância de variação do Zsup,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DELTA ZSUP"
    str_fim = "(VALOR EM PERCENTUAL)"

    def __init__(self):

        super().__init__(
            BlocoDeltaZSUP.str_inicio, BlocoDeltaZSUP.str_fim, True
        )

        self._dados = 0.0

    # Override
    def le(self, arq: IO):
        reg = RegistroFn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(f"{self._dados:2.1f}").rjust(4)
        linha = (
            f"{BlocoDeltaZSUP.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoDeltaZSUP.str_fim}\n"
        )
        arq.write(linha)


class BlocoDeltaZINF(Bloco):
    """
    Bloco com a tolerância de variação do Zinf,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DELTA ZINF"
    str_fim = "(VALOR EM PERCENTUAL)"

    def __init__(self):

        super().__init__(
            BlocoDeltaZINF.str_inicio, BlocoDeltaZINF.str_fim, True
        )

        self._dados = 0.0

    # Override
    def le(self, arq: IO):
        reg = RegistroFn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(f"{self._dados:2.1f}").rjust(4)
        linha = (
            f"{BlocoDeltaZINF.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoDeltaZINF.str_fim}\n"
        )
        arq.write(linha)


class BlocoDeltasConsecutivos(Bloco):
    """
    Bloco com o número de deltas consecutivos para covnergência,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DELTAS CONSECUT."
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoDeltasConsecutivos.str_inicio,
            BlocoDeltasConsecutivos.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoDeltasConsecutivos.str_inicio.ljust(21)}"
            + f"{dado}{BlocoDeltasConsecutivos.str_fim}\n"
        )
        arq.write(linha)


class BlocoDespachoAntecipadoGNL(Bloco):
    """
    Bloco com a consideração de despacho antecipado,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DESP. ANTEC.  GNL"
    str_fim = "(=0 NAO CONSIDERA; =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoDespachoAntecipadoGNL.str_inicio,
            BlocoDespachoAntecipadoGNL.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoDespachoAntecipadoGNL.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoDespachoAntecipadoGNL.str_fim}\n"
        )
        arq.write(linha)


class BlocoModifAutomaticaAdTerm(Bloco):
    """
    Bloco com a consideração sobre modificação automática de adiantamento
    de térmicas, existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "MODIF.AUTOM.ADTERM"
    str_fim = "(=0 NAO CONSIDERA; =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoModifAutomaticaAdTerm.str_inicio,
            BlocoModifAutomaticaAdTerm.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoModifAutomaticaAdTerm.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoModifAutomaticaAdTerm.str_fim}\n"
        )
        arq.write(linha)


class BlocoGeracaoHidraulicaMin(Bloco):
    """
    Bloco com a consideração de geração hidraulica mínima,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CONSIDERA GHMIN"
    str_fim = "(=0 NAO CONSIDERA; =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoGeracaoHidraulicaMin.str_inicio,
            BlocoGeracaoHidraulicaMin.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoGeracaoHidraulicaMin.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoGeracaoHidraulicaMin.str_fim}\n"
        )
        arq.write(linha)


class BlocoSimFinalComData(Bloco):
    """
    Bloco com a consideração da data na simulação final,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "S.F. COM DATA"
    str_fim = ""

    def __init__(self):

        super().__init__(
            BlocoSimFinalComData.str_inicio, BlocoSimFinalComData.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoSimFinalComData.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoSimFinalComData.str_fim}\n"
        )
        arq.write(linha)


class BlocoGerenciamentoPLs(Bloco):
    """
    Bloco com as configurações do gerenciamento de PLs
    aberturas variáveis, existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "GER.PLs E NV1 E NV2"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoGerenciamentoPLs.str_inicio,
            BlocoGerenciamentoPLs.str_fim,
            True,
        )

        self._dados = [0, 0, 0, 0, 0]

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoGerenciamentoPLs):
            return False
        bloco: BlocoGerenciamentoPLs = o
        return all([d1 == d2 for d1, d2 in zip(self._dados, bloco._dados)])

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_linha_tabela(self._linha_inicio, 21, 1, 5)

    # Override
    def escreve(self, arq: IO):
        dado = ""
        for d in self._dados:
            dado += f"{str(d).rjust(4)} "
        linha = (
            f"{BlocoGerenciamentoPLs.str_inicio.ljust(21)}"
            + f"{dado} {BlocoGerenciamentoPLs.str_fim}\n"
        )
        arq.write(linha)


class BlocoSAR(Bloco):
    """
    Bloco com a configuração para uso da SAR,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "SAR"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(BlocoSAR.str_inicio, BlocoSAR.str_fim, True)

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoSAR.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoSAR.str_fim}\n"
        )
        arq.write(linha)


class BlocoCVAR(Bloco):
    """
    Bloco com a configuração para uso do CVAR,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CVAR"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA CTE TEMPO, =2 CONSIDERA VARIAVEL NO TEMP)"  # noqa

    def __init__(self):

        super().__init__(BlocoCVAR.str_inicio, BlocoCVAR.str_fim, True)

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoCVAR.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoCVAR.str_fim}\n"
        )
        arq.write(linha)


class BlocoZSUPMinConvergencia(Bloco):
    """
    Bloco com a consideração do Zsup mínimo durante a convergência,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CONS. ZSUP MIN. CONV."
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoZSUPMinConvergencia.str_inicio,
            BlocoZSUPMinConvergencia.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoZSUPMinConvergencia.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoZSUPMinConvergencia.str_fim}\n"
        )
        arq.write(linha)


class BlocoDesconsideraVazaoMinima(Bloco):
    """
    Bloco com a configuração para desconsiderar vazao mínima,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DESCONSIDERA VAZMIN"
    str_fim = "(=0 NAO , =1 SIM)"

    def __init__(self):

        super().__init__(
            BlocoDesconsideraVazaoMinima.str_inicio,
            BlocoDesconsideraVazaoMinima.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoDesconsideraVazaoMinima.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoDesconsideraVazaoMinima.str_fim}\n"
        )
        arq.write(linha)


class BlocoRestricoesEletricas(Bloco):
    """
    Bloco com a consideração de restrições elétricas,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "RESTRICOES ELETRICAS"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoRestricoesEletricas.str_inicio,
            BlocoRestricoesEletricas.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoRestricoesEletricas.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoRestricoesEletricas.str_fim}\n"
        )
        arq.write(linha)


class BlocoSelecaoCortes(Bloco):
    """
    Bloco com a consideração da seleção de cortes,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "SELECAO DE CORTES"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoSelecaoCortes.str_inicio, BlocoSelecaoCortes.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoSelecaoCortes.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoSelecaoCortes.str_fim}\n"
        )
        arq.write(linha)


class BlocoJanelaCortes(Bloco):
    """
    Bloco com a consideração da janela de cortes,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "JANELA DE CORTES"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoJanelaCortes.str_inicio, BlocoJanelaCortes.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoJanelaCortes.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoJanelaCortes.str_fim}\n"
        )
        arq.write(linha)


class BlocoReamostragemCenarios(Bloco):
    """
    Bloco com as configurações de reamostragem de cenários,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "REAMOST. CENARIOS"
    str_fim = "(UTILIZA REAMOSTRAGEM: =0 NAO; =1 SIM     TIPO: =0 RECOMB; =1 PLENA     PASSO: 0 - 45 )"  # noqa

    def __init__(self):

        super().__init__(
            BlocoReamostragemCenarios.str_inicio,
            BlocoReamostragemCenarios.str_fim,
            True,
        )

        self._dados = [0, 0, 0]

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoReamostragemCenarios):
            return False
        bloco: BlocoReamostragemCenarios = o
        return all([d1 == d2 for d1, d2 in zip(self._dados, bloco._dados)])

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_linha_tabela(self._linha_inicio, 21, 1, 3)

    # Override
    def escreve(self, arq: IO):
        dado = ""
        for d in self._dados:
            dado += f"{str(d).zfill(4)} "
        linha = (
            f"{BlocoReamostragemCenarios.str_inicio.ljust(21)}"
            + f"{dado} {BlocoReamostragemCenarios.str_fim}\n"
        )
        arq.write(linha)


class BlocoConvergeNoZero(Bloco):
    """
    Bloco com a consideração da convergência no 0,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CONVERGE NO ZERO"
    str_fim = "(=0 CONVERGENCIA TRADICIONAL, =1 CONVERGENCIA CALCULADA NO ZERO)"  # noqa

    def __init__(self):

        super().__init__(
            BlocoConvergeNoZero.str_inicio, BlocoConvergeNoZero.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoConvergeNoZero.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoConvergeNoZero.str_fim}\n"
        )
        arq.write(linha)


class BlocoConsultaFCF(Bloco):
    """
    Bloco com a consideração da consulta à FCF,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "CONSULTA FCF"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoConsultaFCF.str_inicio, BlocoConsultaFCF.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoConsultaFCF.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoConsultaFCF.str_fim}\n"
        )
        arq.write(linha)


class BlocoImpressaoENA(Bloco):
    """
    Bloco com a consideração da impressão da ENA,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMPRESSAO ENA"
    str_fim = "(=0 NAO IMPRIME , =1 IMPRIME)"

    def __init__(self):

        super().__init__(
            BlocoImpressaoENA.str_inicio, BlocoImpressaoENA.str_fim, True
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).zfill(4)
        linha = (
            f"{BlocoImpressaoENA.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoImpressaoENA.str_fim}\n"
        )
        arq.write(linha)


class BlocoImpressaoCortesAtivosSimFinal(Bloco):
    """
    Bloco com a consideração da impressão dos cortes ativos
    na simulação final, existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "IMP. CATIVO S.FINAL"
    str_fim = "(=0 NAO IMPRIME , =1 IMPRIME)"

    def __init__(self):

        super().__init__(
            BlocoImpressaoCortesAtivosSimFinal.str_inicio,
            BlocoImpressaoCortesAtivosSimFinal.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).zfill(4)
        linha = (
            f"{BlocoImpressaoCortesAtivosSimFinal.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoImpressaoCortesAtivosSimFinal.str_fim}\n"
        )
        arq.write(linha)


class BlocoRepresentacaoAgregacao(Bloco):
    """
    Bloco com a representação da agregação,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "REP. AGREGACAO"
    str_fim = "(=0 MAIS PROXIMO, =1 CENTROIDE)"

    def __init__(self):

        super().__init__(
            BlocoRepresentacaoAgregacao.str_inicio,
            BlocoRepresentacaoAgregacao.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).zfill(4)
        linha = (
            f"{BlocoRepresentacaoAgregacao.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoRepresentacaoAgregacao.str_fim}\n"
        )
        arq.write(linha)


class BlocoMatrizCorrelacaoEspacial(Bloco):
    """
    Bloco com a representação da correlação espacial,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "MATRIZ CORR.ESPACIAL"
    str_fim = "(=0 ANUAL, =1 MENSAL)"

    def __init__(self):

        super().__init__(
            BlocoMatrizCorrelacaoEspacial.str_inicio,
            BlocoMatrizCorrelacaoEspacial.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).zfill(4)
        linha = (
            f"{BlocoMatrizCorrelacaoEspacial.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoMatrizCorrelacaoEspacial.str_fim}\n"
        )
        arq.write(linha)


class BlocoDesconsideraConvEstatistica(Bloco):
    """
    Bloco com a desconsideração do critério estatístico para convergência,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "DESCONS. CONV. ESTAT"
    str_fim = "(=0 NAO, =1 SIM)"

    def __init__(self):

        super().__init__(
            BlocoDesconsideraConvEstatistica.str_inicio,
            BlocoDesconsideraConvEstatistica.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).zfill(4)
        linha = (
            f"{BlocoDesconsideraConvEstatistica.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoDesconsideraConvEstatistica.str_fim}\n"
        )
        arq.write(linha)


class BlocoMomentoReamostragem(Bloco):
    """
    Bloco com a escolha do momento de reamostragem,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "MOMENTO REAMOSTRAGEM"
    str_fim = "(=0 BACKWARD, =1 FORWARD)"

    def __init__(self):

        super().__init__(
            BlocoMomentoReamostragem.str_inicio,
            BlocoMomentoReamostragem.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).zfill(4)
        linha = (
            f"{BlocoMomentoReamostragem.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoMomentoReamostragem.str_fim}\n"
        )
        arq.write(linha)


class BlocoMantemArquivosEnergias(Bloco):
    """
    Bloco com a escolha de manter ou não os arquivos de energias,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "ARQUIVOS ENA"
    str_fim = "(=0 APAGA APOS EXECUCAO, =1 MANTEM)"

    def __init__(self):

        super().__init__(
            BlocoMantemArquivosEnergias.str_inicio,
            BlocoMantemArquivosEnergias.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).zfill(4)
        linha = (
            f"{BlocoMantemArquivosEnergias.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoMantemArquivosEnergias.str_fim}\n"
        )
        arq.write(linha)


class BlocoInicioTesteConvergencia(Bloco):
    """
    Bloco com a iteração de início para o teste de convergência,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "INICIO TESTE CONVERG."
    str_fim = "(=0 PRIMEIRA ITERACAO, =1 ITERACAO MINIMA)"

    def __init__(self):

        super().__init__(
            BlocoInicioTesteConvergencia.str_inicio,
            BlocoInicioTesteConvergencia.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoInicioTesteConvergencia.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoInicioTesteConvergencia.str_fim}\n"
        )
        arq.write(linha)


class BlocoSazonalizarVminT(Bloco):
    """
    Bloco com a escolha de sazonalizar o VminT nos períodos estáticos,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "SAZ. VMINT PER. EST."
    str_fim = "(=0 PRE E POS NAO SAZONAIS, =1 PRE E POS SAZONAIS)"

    def __init__(self):

        super().__init__(
            BlocoSazonalizarVminT.str_inicio,
            BlocoSazonalizarVminT.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoSazonalizarVminT.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoSazonalizarVminT.str_fim}\n"
        )
        arq.write(linha)


class BlocoSazonalizarVmaxT(Bloco):
    """
    Bloco com a escolha de sazonalizar o VmaxT nos períodos estáticos,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "SAZ. VMAXT PER. EST."
    str_fim = "(=0 PRE E POS NAO SAZONAIS, =1 PRE E POS SAZONAIS)"

    def __init__(self):

        super().__init__(
            BlocoSazonalizarVmaxT.str_inicio,
            BlocoSazonalizarVmaxT.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoSazonalizarVmaxT.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoSazonalizarVmaxT.str_fim}\n"
        )
        arq.write(linha)


class BlocoSazonalizarVminP(Bloco):
    """
    Bloco com a escolha de sazonalizar o VminP nos períodos estáticos,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "SAZ. VMINP PER. EST."
    str_fim = "(=0 PRE E POS NAO SAZONAIS, =1 PRE E POS SAZONAIS)"

    def __init__(self):

        super().__init__(
            BlocoSazonalizarVminP.str_inicio,
            BlocoSazonalizarVminP.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoSazonalizarVminP.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoSazonalizarVminP.str_fim}\n"
        )
        arq.write(linha)


class BlocoSazonalizarCfugaCmont(Bloco):
    """
    Bloco com a escolha de sazonalizar Cfuga e Cmont nos períodos
    estáticos, existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "SAZ. CFUGA E CMONT"
    str_fim = "(=0 PRE E POS NAO SAZONAIS, =1 PRE E POS SAZONAIS)"

    def __init__(self):

        super().__init__(
            BlocoSazonalizarCfugaCmont.str_inicio,
            BlocoSazonalizarCfugaCmont.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoSazonalizarCfugaCmont.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoSazonalizarCfugaCmont.str_fim}\n"
        )
        arq.write(linha)


class BlocoRestricoesEmissaoGEE(Bloco):
    """
    Bloco com a escolha de habilitar ou não as retrições de GEE,
    existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "REST. EMISSAO GEE"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoRestricoesEmissaoGEE.str_inicio,
            BlocoRestricoesEmissaoGEE.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoRestricoesEmissaoGEE.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoRestricoesEmissaoGEE.str_fim}\n"
        )
        arq.write(linha)


class BlocoAfluenciaAnualPARp(Bloco):
    """
    Bloco com a consideração da componente de afluência anual
    para o PAR(p), existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "AFLUENCIA ANUAL PARP"
    str_fim = (
        "(=0 NAO CONSIDERA , =1 CONSIDERA. PDDE SEM ABRIR"
        + " X NA DERIVACAO DOS CORTES, =2 CONSIDERA. PDDE ABRINDO"
        + " X NA DERIVACAO DOS CORTES COM APROX. DE 1/6 X(t-1)"
        + " PARA ENA(t-12), =3 CONSIDERA. PDDE EXATA COM 12 EIXOS"
        + " PARA AS AFLUENCIAS PASSADAS; REDUCAO DA ORDEM: "
        + "=0 CONSIDERA,  =1 NAO CONSIDERA, =2 CONSIDERA COM "
        + "IMPRESSAO RELATORIO)"
    )

    def __init__(self):

        super().__init__(
            BlocoAfluenciaAnualPARp.str_inicio,
            BlocoAfluenciaAnualPARp.str_fim,
            True,
        )

        self._dados = [0, 0]

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, BlocoAfluenciaAnualPARp):
            return False
        bloco: BlocoAfluenciaAnualPARp = o
        return all([d1 == d2 for d1, d2 in zip(self._dados, bloco._dados)])

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_linha_tabela(self._linha_inicio, 21, 1, 2)

    # Override
    def escreve(self, arq: IO):
        dado = ""
        for d in self._dados:
            dado += f"{str(d).rjust(4)} "
        linha = (
            f"{BlocoAfluenciaAnualPARp.str_inicio.ljust(21)}"
            + f"{dado}  {BlocoAfluenciaAnualPARp.str_fim}\n"
        )
        arq.write(linha)


class BlocoRestricoesFornecGas(Bloco):
    """
    Bloco com a escolha de habilitar ou não as retrições de fornecimento
    de gás, existente no arquivo `dger.dat` do NEWAVE.
    """

    str_inicio = "REST. FORNEC. GAS"
    str_fim = "(=0 NAO CONSIDERA , =1 CONSIDERA)"

    def __init__(self):

        super().__init__(
            BlocoRestricoesFornecGas.str_inicio,
            BlocoRestricoesFornecGas.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoRestricoesFornecGas.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoRestricoesFornecGas.str_fim}\n"
        )
        arq.write(linha)


class BlocoMemCalculoCortes(Bloco):
    """
    Bloco com a escolha de habilitar ou não a impressão da memória de
    cálculo dos cortes de Benders.
    """

    str_inicio = "MEM. CALCULO CORTES"
    str_fim = (
        "(=0 NAO IMPRIME, =1 IMPRIME PARA ESCOLHA ESPECIFICADA"
        + " NO ARQUIVO dbgcortes.dat)"
    )

    def __init__(self):

        super().__init__(
            BlocoMemCalculoCortes.str_inicio,
            BlocoMemCalculoCortes.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoMemCalculoCortes.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoMemCalculoCortes.str_fim}\n"
        )
        arq.write(linha)


class BlocoGeracaoEolica(Bloco):
    """
    Bloco com a escolha de habilitar ou não as incertezas na geração
    eólica na geração de cenários, cálculo da política e simulação final,
    e também a penalidade para corte de eólica.
    """

    str_inicio = "GERACAO EOLICA"
    str_fim = (
        "(=0 NAO CONSIDERA, =1 CONSIDERA; PENALIDADE DO CORTE "
        + "DE GERACAO EOLICA)"
    )

    def __init__(self):

        super().__init__(
            BlocoGeracaoEolica.str_inicio, BlocoGeracaoEolica.str_fim, True
        )

        self._dados = [0, 0.0]

    # Override
    def le(self, arq: IO):
        reg_habilita = RegistroIn(4)
        reg_penal = RegistroFn(8)
        self._dados = [
            reg_habilita.le_registro(self._linha_inicio, 21),
            reg_penal.le_registro(self._linha_inicio, 26),
        ]

    # Override
    def escreve(self, arq: IO):
        habilita = str(self._dados[0]).rjust(4)
        penal = f"{self._dados[1]:.4f}".ljust(8)
        linha = (
            f"{BlocoGeracaoEolica.str_inicio.ljust(21)}"
            + f"{habilita} {penal}     {BlocoGeracaoEolica.str_fim}\n"
        )
        arq.write(linha)


class BlocoCompensacaoCorrelacaoCruzada(Bloco):
    """
    Bloco com a escolha da forma de compensação da correlação
    cruzada nos cenários do NEWAVE.
    """

    str_inicio = "COMP. COR. CRUZ."
    str_fim = "(=0 CORR. SOMENTE AFL.; =1 CORR.AFL. E VENTOS; =2 NAO CORRIGE)"

    def __init__(self):

        super().__init__(
            BlocoCompensacaoCorrelacaoCruzada.str_inicio,
            BlocoCompensacaoCorrelacaoCruzada.str_fim,
            True,
        )

        self._dados = 0

    # Override
    def le(self, arq: IO):
        reg = RegistroIn(4)
        self._dados = reg.le_registro(self._linha_inicio, 21)

    # Override
    def escreve(self, arq: IO):
        dado = str(self._dados).rjust(4)
        linha = (
            f"{BlocoCompensacaoCorrelacaoCruzada.str_inicio.ljust(21)}"
            + f"{dado}   {BlocoCompensacaoCorrelacaoCruzada.str_fim}\n"
        )
        arq.write(linha)


class LeituraDGer(LeituraBlocos):
    """
    Realiza a leitura do arquivo dger.dat
    existente em um diretório de entradas do NEWAVE.

    Esta classe contém o conjunto de utilidades para ler
    e interpretar os campos de um arquivo dger.dat, construindo
    um objeto `DGer` cujas informações são as mesmas do dger.dat.

    Este objeto existe para retirar do modelo de dados a complexidade
    de iterar pelas linhas do arquivo, recortar colunas, converter
    tipos de dados, dentre outras tarefas necessárias para a leitura.

    """

    def __init__(self, diretorio: str) -> None:
        super().__init__(diretorio)

    # Override
    def _cria_blocos_leitura(self) -> List[Bloco]:
        return [
            BlocoNomeCaso(),
            BlocoTipoExecucao(),
            BlocoDuracaoPeriodo(),
            BlocoNumAnosEstudo(),
            BlocoMesInicioPreEstudo(),
            BlocoMesInicioEstudo(),
            BlocoAnoInicioEstudo(),
            BlocoNumAnosPreEstudo(),
            BlocoNumAnosPosEstudo(),
            BlocoNumAnosPosEstudoSimFinal(),
            BlocoImprimeDados(),
            BlocoImprimeMercados(),
            BlocoImprimeEnergias(),
            BlocoImprimeModeloEstocastico(),
            BlocoImprimeSubsistema(),
            BlocoNumMaxIteracoes(),
            BlocoNumForwards(),
            BlocoNumAberturas(),
            BlocoNumSeriesSinteticas(),
            BlocoOrdemMaximaPARp(),
            BlocoAnoInicialHistorico(),
            BlocoCalculaVolInicial(),
            BlocoVolInicialSubsistema(),
            BlocoTolerancia(),
            BlocoTaxaDesconto(),
            BlocoTipoSimFinal(),
            BlocoImpressaoOperacao(),
            BlocoImpressaoConvergencia(),
            BlocoIntervaloGravar(),
            BlocoMinIteracoes(),
            BlocoRacionamentoPreventivo(),
            BlocoNumAnosManutUTE(),
            BlocoTendenciaHidrologica(),
            BlocoRestricaoItaipu(),
            BlocoBid(),
            BlocoPerdasTransmissao(),
            BlocoElNino(),
            BlocoEnso(),
            BlocoDuracaoPorPatamar(),
            BlocoOutrosUsosAgua(),
            BlocoCorrecaoDesvio(),
            BlocoCurvaAversao(),
            BlocoTipoGeracaoENA(),
            BlocoRiscoDeficit(),
            BlocoIteracaoParaSimFinal(),
            BlocoAgrupamentoLivre(),
            BlocoEqualizacaoPenalInt(),
            BlocoRepresentacaoSubmot(),
            BlocoOrdenacaoAutomatica(),
            BlocoConsideraCargaAdicional(),
            BlocoDeltaZSUP(),
            BlocoDeltaZINF(),
            BlocoDeltasConsecutivos(),
            BlocoDespachoAntecipadoGNL(),
            BlocoModifAutomaticaAdTerm(),
            BlocoGeracaoHidraulicaMin(),
            BlocoSimFinalComData(),
            BlocoGerenciamentoPLs(),
            BlocoSAR(),
            BlocoCVAR(),
            BlocoZSUPMinConvergencia(),
            BlocoDesconsideraVazaoMinima(),
            BlocoRestricoesEletricas(),
            BlocoSelecaoCortes(),
            BlocoJanelaCortes(),
            BlocoReamostragemCenarios(),
            BlocoConvergeNoZero(),
            BlocoConsultaFCF(),
            BlocoImpressaoENA(),
            BlocoImpressaoCortesAtivosSimFinal(),
            BlocoRepresentacaoAgregacao(),
            BlocoMatrizCorrelacaoEspacial(),
            BlocoDesconsideraConvEstatistica(),
            BlocoMomentoReamostragem(),
            BlocoMantemArquivosEnergias(),
            BlocoInicioTesteConvergencia(),
            BlocoSazonalizarVminT(),
            BlocoSazonalizarVmaxT(),
            BlocoSazonalizarVminP(),
            BlocoSazonalizarCfugaCmont(),
            BlocoRestricoesEmissaoGEE(),
            BlocoAfluenciaAnualPARp(),
            BlocoRestricoesFornecGas(),
            BlocoMemCalculoCortes(),
            BlocoGeracaoEolica(),
            BlocoCompensacaoCorrelacaoCruzada(),
        ]
