{--------------------------------------------------------}
{
{     Discavox - utilitário de comunicações
{
{     Autores: Antonio Borges e Valter Ponte
{
{     Cooperação tecnológica NCE/UFRJ e RENDE/USP
{
{     Em abril/1995
{
{--------------------------------------------------------}

{$M 16535,8000}
program discavox;

uses winProcs, strings,
    windos, dvcrt, dvwin, dvhora,
    disvars, dismsg, disutil, disprot,
    disfala, disdos, disrende,
    disansi, xmodem, videovox, discomm;

const versao = '2.2';

{--------------------------------------------------------}
{           manda um arquivo para o computador
{--------------------------------------------------------}

procedure mandaArqComput (transmLineFeed: boolean);
var nomearq: string;
    resp: char;
    result: integer;
    arq: text;
    c: char;
    contaCarac: integer;
    s: string;
    espera, erro: word;

label cancela;

begin
    gotoxy (1, 24);
    writeln; writeln;
    gotoxy (1, 23);
    textBackground (RED);
    mensagem ('DINOMENV', 0); {Qual o nome do arquivo a enviar ? }
    textBackground (BLACK);
    sintReadln (nomearq);
    if nomearq = '' then
        begin
            mensagem ('DIENVCAN', 1); {Envio cancelado.}
            exit;
        end;

    if not existeArq (nomearq) then
        begin
            mensagem ('DIARQNAO', 1); {Arquivo não existe.  Operação cancelada.}
            exit;
        end;

    textBackground (RED);
    mensagem ('DIENVGAR', 0); {Quer envio com garantia (s/n) ? }
    textBackground (BLACK);
    resp := letecla (1);

    utilizaCrc (upcase (resp) = 'C');

    if upcase(resp) <> 'N' then
        begin
            mensagem ('DIESPREC', 1); {Aguardando parceiro iniciar recepcao...}
            result := xmodemSend (nomearq);
            if result <> 0 then
                mostraErroXmodem (result)
            else
                mensagem ('DITERTRA', 1); {Terminei transmissao.}
        end
    else
        begin
            writeln;  gotoxy (wherex, wherey-1);
            mensagem ('DIDELAY', 0); {Espera entre linhas em milissegundos (sugiro 500): }
            sintReadln (s);
            val (s, espera, erro);
            if erro < 0 then espera := 500;

            mensagem ('DITRANSM', 1); {Transmitindo...}

            assign (arq, nomearq);
            reset (arq);
            contaCarac := 0;
            while not eof (arq) do
                begin
                    read (arq, c);
                    if (c <> #$0a) or transmLineFeed then
                         esclink (c);

                    if c = #$0d then
                        if espera <> 0 then
                            delay (espera);

                    if chegouLink then
                         begin
                             lelink (c);
                             if c = ^S then
                                 repeat
                                     if chegouLink then
                                          lelink (c);
                                     if keypressed then c := ^Q;
                                 until c = ^Q;
                         end;

                    contaCarac := contaCarac + 1;
                    if contaCarac >= 1024 then
                        begin
                            contaCarac := 0;
                            begin sound (100); delay (50); nosound; end;
                        end;

                    if keypressed then
                        begin
                            if sintFalando then;
                            c := readkey;
                            if c = #$1b then goto cancela;
                        end;
                end;
cancela:
            close (arq);

            repeat
                while chegoulink do lelink (c);
                delay (1000);
            until not chegoulink;

            mensagem ('DITERTRA', 1); {Terminei transmissao.}
        end;
end;

{--------------------------------------------------------}
{           recebe um arquivo do computador
{-------------------------------------------------------}

procedure recebeArqComput;
var
    nomearq: string;
    result: integer;
    resp, c, tec: char;
    arq: text;
    erro: boolean;
    contaCarac: integer;

begin
    gotoxy (1, 24);
    writeln; writeln;
    gotoxy (1, 23);
    textBackground (RED);
    textColor (LIGHTGRAY);
    mensagem ('DINOMREC', 0); {Qual o nome do arquivo a receber ?}
    textBackground (BLACK);
    clreol;
    sintReadln (nomearq);

    if nomearq = '' then
        begin
            mensagem ('DIRECCAN', 1); {Recepção cancelada.}
            exit;
        end;

    textBackground (RED);
    mensagem ('DITGARAN', 0); {O parceiro vai transmitir com garantia (s/n) ? }
    textBackground (BLACK);
    resp := letecla (1);

    utilizaCrc (upcase (resp) = 'C');

    if upcase(resp) <> 'N' then
        begin
            mensagem ('DIESPENV', 1); {Aguardando parceiro enviar...}
            result := xmodemReceive (nomearq);
            if result <> 0 then
                mostraErroXmodem (result)
            else
                mensagem ('DIGRAV', 1); {Arquivo gravado}
        end
    else
        begin
            assign (arq, nomearq);
            {$I-} append (arq); {$I+}
            if ioresult <> 0 then
                {$I-} rewrite (arq); {$I+}
            if ioresult <> 0 then
                begin
                    mensagem ('DIERRARQ', 1); {Erro ao criar arquivo. Recepcao cancelada}
                    exit;
                end;

            mensagem ('DITCESCR', 1); {Tecle ESC para finalizar a recepção do arquivo}

            contaCarac := 0;
            erro := false;
            tec := 'x';
            repeat
                if chegouLink then
                    begin
                        lelink (c);
                        {$I-} write (arq, c); {$I+}
                        if ioresult <> 0 then erro := true;

                        contaCarac := contaCarac + 1;
                        if contaCarac >= 80 then
                            begin
                                contaCarac := 0;
                                begin sound (100); delay (100); nosound; end;
                            end;
                    end;

                if keypressed then
                    begin
                        if sintFalando then;
                        tec := readkey;
                        if tec <> ESC then esclink (tec);
                    end;
            until tec = ESC;

            {$i-}  close (arq);  {$I+}
            if ioresult <> 0 then erro := true;

            if erro then
                mensagem ('DITRUNC', 1) {Houve um erro na gravação.  Arquivo foi truncado.}
            else
                mensagem ('DIGRAV', 1); {Arquivo gravado}
        end;
end;

{--------------------------------------------------------}
{               seleciona velocidade de fala
{--------------------------------------------------------}

procedure selVelocFala;
var erro: integer;
    s: string;
    c: char;
    quantoCorta, minSobra, interPal: integer;

label 1, 2, 3, fim;

begin
    sintSom ('DIVELFAL');  { Qual a velocidade de fala de 1 a 4 ? }
    c := sintReadkey;

(*    leitRapida := false; *)
(*    leitCondens:= false; *)

    sintVeloc (ord (c) and 3);

    sintsom ('DISOLET');           { Soletra digitacao (s/n) ? }
    c := sintReadkey;
    soletrando := upcase (c) = 'S';

fim:
    sintSom ('DIOK');
end;


{--------------------------------------------------------}
{               emula um terminal de computador
{--------------------------------------------------------}

procedure termComputador;
var
    c: char;
    emulando: boolean;
    nomeComputador: string;
    salvaSolet: boolean;
    nomeArqLynx: string;

{--------------------------------------------------------}

    procedure ajudaTerm;
    begin
        if modoLynx then exit;

        writeln;
        textBackground(BLUE);
        mensagem ('DIAJUDT2', 1); {F2 - transmite um arquivo}
        mensagem ('DIAJUDT3', 1); {F3 - recebe um arquivo}
        mensagem ('DIAJUDT4', 1); {F4 - seleciona modo de fala}
        mensagem ('DIAJUDT5', 1); {F5 - seleciona modo WWW}
        mensagem ('DIAJUDT6', 1); {F6 - limpa tela}
        mensagem ('DIAJUDT7', 1); {F7 - disca de novo}
        mensagem ('DIAJUDT8', 1); {F8 - fala hora}
        mensagem ('DIAJUDT9', 1); {F9 - ativa leitor de tela}
        mensagem ('DITECF10', 1); {Tecle F10 para desligar}
        textBackground(BLACK);
        clreol;
        writeln;
    end;

{--------------------------------------------------------}

    procedure controlaAutoArquiva;
    var x, y: integer;
    label errodisco;
    begin
       autoArquiva := not autoArquiva;

       if autoArquiva then
           begin
               sintSom ('DIAGRAV');   { autogravacao ativada }

               assign (arqAuto, 'discavox.log');

               {$I-}  reset (arqAuto);  {$I+}
               if ioresult = 0 then
                   begin
                       {$I-} append (arqAuto); {$I+}
                       if ioresult <> 0 then goto erroDisco;
                    end
               else
                   begin
                       {$I-} close (arqAuto); {$I+}
                       if ioresult <> 0 then;
                       {$I-} rewrite (arqAuto); {$I+}
                       if ioresult <> 0 then goto erroDisco;
                   end
           end
       else
           begin
               {$I-}   close (arqAuto);   {$I+}
               if ioresult <> 0 then
                   goto erroDisco
               else
                   begin
                       sintsom ('DIARGRAV');   { Arquivo gravado' }
                   end;
           end;

       exit;

erroDisco:
        sintSom ('DIERGRAV');  { Erro de gravacao }
    end;

{--------------------------------------------------------}

    function qualLinhaInversa: integer;
    var x, y: integer;
    begin
        for y := 1 to 25 do
            for x := 0 to 79 do
                if (getScreenAttrib (y, x+1) and $e0) <> 0 then
                     begin
                         qualLinhaInversa := y;
                         exit;
                     end;

        qualLinhaInversa := wherey;
    end;

{--------------------------------------------------------}

    procedure leLinhaVideo (n: integer);
    var s: string;
        i: integer;
        tudoBranco: boolean;
        c: char;

    begin
        if n < 1  then n := 1;
        if n > 25 then n := 25;

        tudoBranco := false;
        s := '';
        for i := 0 to 79 do
            begin
                c := getScreenChar (i+1, n);
                s := s + c;
                if c <> ' ' then tudoBranco := false;
            end;

        if tudoBranco then
            delay (1000)
        else
            begin
                (* falaRapida (leitRapida); *)
                (* falaCondensada (leitCondens);  *)
                sintetiza (s);
                (* falaRapida (false); *)
                (* falaCondensada (false); *)
            end;

        sintClek;
    end;

{--------------------------------------------------------}

    procedure ligaDeslFalaTerm;
    begin
        if falando = 0 then
             falando := 1
        else
             falando := 0;

        if falando <> 0 then
            sintSom ('DIFALLIG')
        else
            sintSom ('DIFALDLG');
    end;

{--------------------------------------------------------}

    procedure selecModoLynx;
    begin
        falando := 1;

        modoLynx := not modoLynx;
        if modoLynx then
            begin
                salvaSolet := soletrando;
                soletrando := true;
                sintSom ('DILNXLIG');
            end
        else
            begin
                soletrando := salvaSolet;
                sintSom ('DILNXDLG');
            end;
    end;

{--------------------------------------------------------}

    procedure recebeTelaLynx;
    var arq: text;
        espera: integer;
        c: char;
        s: string;
    label fim;


        function trataTeclado: boolean;
        begin
            trataTeclado := true;

            if sintFalando then;
            if keypressed then
                case c of
                    #$1b: begin
                              trataTeclado := false;
                              exit;
                          end;

                     #$0:
                          begin
                              c := readkey;
                              if c = TEND then leLinhaVideo (22)
                              else
                              if c = HOME then leLinhaVideo (1);
                          end;

                else
                         begin
                             esclink (readkey);
                             if soletrando then sintCarac (c);
                         end;
                end;
        end;


    begin
        gotoxy (1, 24);
        writeln; writeln;
        gotoxy (1, 23);
        textBackground (RED);
        textColor (LIGHTGRAY);
        mensagem ('DINOMREC', 0); {Qual o nome do arquivo a receber ? }
        textBackground (BLACK);
        clreol;
        sintReadln (s);

        if s <> '' then nomeArqLynx := s;

        assign (arq, nomeArqLynx);
        {$I-} reset (arq);  {$I+}
        if ioresult = 0 then
            begin
                close (arq);
                {$I-} append (arq); {$I+}
                if ioresult <> 0 then
                    begin
                        mensagem ('DIERRARQ', 1); {Erro ao criar arquivo. Recepcao cancelada}
                        exit;
                    end;
            end
        else
            begin
                {$I-} rewrite (arq);  {$I+}
                if ioresult <> 0 then
                    begin
                        mensagem ('DIERRARQ', 1); {Erro ao criar arquivo. Recepcao cancelada}
                        exit;
                    end;
            end;

        sintSom ('DIRECTEL');      { arquivando pagina www }

        esclink ('P');
        delay (2000);
        while chegouLink do
            lelink (c);
        esclink (#$1b);  esclink ('[');  esclink ('B');
        delay (1000);
        while chegouLink do
            lelink (c);
        esclink (#$1b);  esclink ('[');  esclink ('B');
        delay (1000);
        while chegouLink do
            lelink (c);

        esclink (#$0d);

        repeat
            if not trataTeclado then goto fim;

            if chegouLink then
                begin
                    lelink (c);
                    ansiwrite (c);
                    if c = ']' then esclink ('y');
                end;
        until c = ':';

        writeln (arq, '------------- Inicio de texto do Lynx ------------');
        esclink (#$0d);

        espera := 0;
        while espera < 30 do
             begin
                 if not trataTeclado then goto fim;

                 while chegouLink do
                     begin
                         espera := 0;
                         leLink (c);
                         ansiwrite (c);
                         write (arq, c);
                         if c = #$0d then sintclek;
                     end;

                 espera := espera + 1;
                 delay (200);
             end;
fim:
        writeln (arq);
        writeln (arq, '------------- Fim de texto do Lynx ------------');
        close (arq);

        sintSom ('DIGRAV');
        esclink (#$0d);
    end;

{--------------------------------------------------------}

    procedure trataControles;
    var c: char;
        salvax, salvay: integer;
        s: string;
        i: integer;
    begin
        c := readkey;
        case c of
             CTLF1: if modoLynx then
                        leLinhaVideo(qualLinhaInversa)
                    else
                        lelinhaVideo (wherey);

             ALTF1: if modoLynx then
                        begin
                            for i := 2 to 21 do
                               if not keypressed then lelinhaVideo (i);
                            while keypressed do c := readkey;
                        end
                    else
                        begin
                            for i := 1 to 24 do
                               if not keypressed then lelinhaVideo (i);
                            while keypressed do c := readkey;
                        end;

             F1   : ajudaTerm;
             F2   : begin
                        utilizaCrc (false);
                        mandaArqComput (false);
                    end;
             F3   : if modoLynx then
                        recebeTelaLynx
                    else
                        recebeArqComput;
             CTLF3: controlaAutoArquiva;
             F4   : ligaDeslFalaTerm;
             CTLF4: selVelocFala;
             F5   : selecModoLynx;
             F6   : begin
              	 	salvax := wherex;
                        salvay := wherey;
                        textColor (LightGray);
                        textBackGround (Black);
                        clrscr;
                        gotoxy (salvax, salvay);
                    end;
             F7   : if discaTelefone (nomeComputador) then;
             F8   : falaHora;
             CTLF8: falaDia;

             F9   : if modoLynx then
                        begin
                            salvax := wherex;
                            salvay := wherex;
                            gotoxy (1, qualLinhaInversa);
                            leitorDeTela;
                            gotoxy (salvax, salvay);
                        end
                    else
                        leitorDeTela;

             F10  : begin
                       salvax := wherex;
                       salvay := wherey;
                       window (1, 1, 80, 25);

                       gotoxy (54, 25);
                       textBackGround (BLACK);
                       textColor (LIGHTGRAY);
                       clreol;
                       textBackGround (BLUE);
                       mensagem ('DICNFFIM', 0); {Confirma fim (s/n)}
                       textBackGround (BLACK);
                       clreol;

                       c := readkey;
                       if upcase(c) = 'S' then
                           emulando := FALSE
                       else
                           begin
                               gotoxy (54, 25);
                               textBackGround (BLUE);
                               mensagem ('DITECF10', 0); {Tecle F10 para desligar}
                               textBackGround (BLACK);
                               clreol;
                           end;

                       window (1, 1, 80, 24);
                       gotoxy (salvax, salvay);
                    end;

             INS : lelinhaVideo (wherey);

             DEL : esclink (#$7f);

             HOME: if modoLynx then
                       lelinhaVideo (1)
                   else
                       begin
                           esclink (#$1b);  esclink ('[');  esclink ('H');
                       end;

             TEND: if modoLynx then
                       lelinhaVideo (22)
                   else
                       begin
                           esclink (#$1b);  esclink ('[');  esclink ('K');
                       end;

             PGUP: begin
                      esclink (#$1b);  esclink ('[');
                      esclink ('5');   esclink ('~');
                   end;

             PGDN: begin
                      esclink (#$1b);  esclink ('[');
                      esclink ('6');   esclink ('~');
                   end;

             CIMA: begin
                       esclink (#$1b);  esclink ('[');  esclink ('A');
                   end;
             BAIX: begin
                       esclink (#$1b);  esclink ('[');  esclink ('B');
                   end;
             ESQ : begin
                       esclink (#$1b);  esclink ('[');  esclink ('D');
                   end;
             DIR : begin
                       esclink (#$1b);  esclink ('[');  esclink ('C');
                   end;

            #16..#50:   { ALTS }
                     begin
                         c := tabAlt [ord(c)];
                         s := pegaParam ('MENS'+c);
                         for i := 1 to length(s) do
                             esclink (s[i]);
                     end;
         end;
    end;

{--------------------------------------------------------}

var
    i, erro: integer;
    conexaoLocal: boolean;

label inicio;

begin
inicio:
    mensagem ('DITELCOM', 0); {Informe o telefone do computador parceiro: }
    sintReadln (nomeComputador);
    if nomeComputador = '' then exit;

    conexaoLocal := (nomeComputador = 'local') or
                    (nomeComputador = 'LOCAL');

    if not conexaoLocal then
        begin
            for i := 1 to length (nomeComputador) do
                nomeComputador[i] := upcase (nomeComputador[i]);
            if nomeComputador[1] in ['A'..'Z'] then
                 begin
                     nomeComputador := pegaParam (nomeComputador);
                     if nomeComputador = '' then
                         goto inicio;
                 end;
        end;

    clrscr;
    textBackground (BLUE);
    gotoxy (54, 25);
    mensagem ('DITECF10', 0); {Tecle F10 para desligar}
    textBackGround (BLACK);

    checkBreak := false;

    gotoxy (1,1);
    window (1, 1, 80, 24);

    InicLink (porta, velocTerm, nbitsTerm, stopsTerm, paridTerm);
    if not conexaoLocal then
        if discaTelefone (nomeComputador) then;

    modoLynx := false;
    inicAnsi;
    soletrando:= false;
    falando := 1;
    nomeArqLynx := 'lynx.$$$';

    c := #0;
    emulando := true;

    leitRapida  := false;
    leitCondens := true;
    autoArquiva := false;

    forceCursor;
    while emulando do
        begin
            if keypressed then
                begin
                    unforceCursor;
                    if sintFalando then;
                    c := readkey;
                    if modoLynx and (c = ^H) then
                        if (wherex <> 1) then
                            begin
                                sintSom ('DIDEL');
                                (*sintCarac (leTela (wherey, wherex-1));*)
                            end
                        else
                            sintbip;

                    if c = #$0 then
                        trataControles
                    else
                        begin
                            esclink (c);
                            if soletrando then
                                sintCarac (c);
                        end;
                    forceCursor;
                end;

            if chegouLink then
                begin
                    unforceCursor;
                    (*falaRapida (leitRapida);*)
                    (*falaCondensada (leitCondens);*)

                    repeat
                        lelink (c);
                        if autoArquiva then
                            write (arqAuto, c);
                        if c = #$0c then
                            clrscr
                        else
                            ansiwrite (c);
                    until (not chegouLink) or
                          (not modoLynx);    { para evitar perda de cleks }

                    (*falaRapida (false);*)
                    (*falaCondensada (false);*)
                    forceCursor;
                end;
        end;

    unforceCursor;
    falando := 1;
    if autoArquiva then controlaAutoArquiva;

    if not conexaoLocal then
        desligaTelefone (true);
    finalLink;

    window (1, 1, 80, 25);
    gotoxy (1, 25);

    textColor(LIGHTGRAY);
    textBackground (BLACK);
    clreol;

    checkBreak := true;
end;

{--------------------------------------------------------}
{                   configuração
{--------------------------------------------------------}

procedure configura;
var c: char;
    numeroRende, s: string;
    salvaPorta, erro: integer;

    function intstr (v: longint): string;
    var s: string;
    begin
        str(v, s);
        intstr := s;
    end;

begin
    writeln;
    mensagem ('DICONFIG', 1); {Configurando comunicações}
    writeln;

    salvaPorta := porta;
    if salvaPorta = 0 then salvaPorta := 4;
    mensagem ('DIPORTA', 0); {Porta (atualmente }
    sintWriteInt (porta);
    write ('): ');
    sintReadInt (porta);
    if porta = 0 then porta := salvaPorta;

    mensagem ('DIVEL', 0); {Velocidade (sugiro 2400): }
    sintReadln (s);
    val (s, veloc, erro);    { longint }
    if veloc = 0 then veloc := 19200;
    velocTerm := veloc;

    mensagem ('DIBITCAR', 0); {Numero de bits por caractere (sugiro 8): }
    sintReadint (nbits);
    if nbits = 0 then nbits := 8;
    nbitsTerm := nbits;

    mensagem ('DISTOPBI', 0); {Numero de stop bits (sugiro 1): }
    sintReadint (stops);
    if stops = 0 then stops := 1;
    stopsTerm := stops;

    mensagem ('DIPARID', 0); {Paridade: 0 sem, 1 impar, 2 par (sugiro 0): }
    sintReadint (parid);
    paridTerm := parid;

    mensagem ('DIOKCONF', 1); {Ok, configurado}
    mensagem ('DISVDSK', 0); {Quer salvar em disco (s/n) ? }
    s := 'N';
    sintReadln (s);
    if upcase(s[1]) = 'S' then
        begin
            trocaParam ('PORTA', intstr (porta));
            trocaParam ('VELOC', intstr (veloc));
            trocaParam ('VELOCTERM', intstr (velocTerm));
            trocaParam ('NBITS', intstr (nbits));
            trocaParam ('NBITSTERM', intstr (nbitsTerm));
            trocaParam ('STOPS', intstr (stops));
            trocaParam ('STOPSTERM', intstr (stopsTerm));
            trocaParam ('PARID', intstr (parid));
            trocaParam ('PARIDTERM', intstr (paridTerm));

            mensagem ('DINUMPRO', 0); {Qual o telefone do provedor (Enter deixa igual): }
            sintReadln (numeroRende);
            if numeroRende <> '' then
                begin
                    trocaParam ('RENDE', numeroRende);
                    trocaParam ('RENDE1', numeroRende);
                end;
        end;
end;

{--------------------------------------------------------}
{          trata tela de conversacao entre usuarios
{--------------------------------------------------------}

procedure inicTelaUsuario;
var i: integer;
begin
    window (1,1,80,25);
    clrScr;
    gotoxy (1, 13);
    for i := 1 to 8 do
        write ('----------');

    gotoxy (1, 25);
    textBackground (BLUE);
    mensagem ('DIF10TRM', 0); {Tecle F10 para desligar, F1 para ajuda}
    clreol;
    textBackground (BLACK);
    xcurDele := 1;  ycurDele := 1;
    xcurMeu  := 1;  ycurMeu := 1;
end;

{--------------------------------------------------------}

procedure saiMeuCarac (c: char);
begin
    window (1, 14, 80, 24);
    gotoxy (xcurMeu, ycurMeu);
    write (c);

    if falando = 1 then
        begin
            if c = ENTER then
                sintClek
            else
                sintcarac (c)
        end;

    if c = ENTER then
        writeln;
    xcurMeu := whereX;
    ycurMeu := whereY;
end;

{--------------------------------------------------------}

procedure saiCaracParceiro (c: char);
begin
    window (1, 1, 80, 12);
    gotoxy (xcurDele, ycurDele);
    write (c);
    acumulaPalavra (c);
    if c = ENTER then
        writeln;
    xcurDele := whereX;
    ycurDele := whereY;
end;

{--------------------------------------------------------}
{          ajuda na conversa com outro usuario
{--------------------------------------------------------}

procedure ajudaUsuario;
begin
    writeln;
    mensagem ('DIAJUDU2', 1); {F2 - transmite um arquivo}
    mensagem ('DIAJUDU3', 1); {F3 - recebe um arquivo}
    mensagem ('DIAJUDU4', 1); {F4 - seleciona modo de fala}
    mensagem ('DIAJUDU9', 1); {F9 - ativa leitor de tela}
    mensagem ('DIAJUDU0', 1); {F10 - fim de comunicação}
end;

{--------------------------------------------------------}
{                    fala com gente
{--------------------------------------------------------}

procedure falaComGente;
var
    c, opcao: char;
    nomeParceiro: string;
    conversando: boolean;
    salvax, salvay, i: integer;

{--------------------------------------------------------}

    procedure ligaDeslFala;
    begin
        if falando = 0 then
             falando := 1
        else
             falando := 0;

        if falando <> 0 then
            sintSom ('DIFALLIG')
        else
            sintSom ('DIFALDLG');
    end;

{--------------------------------------------------------}

    procedure trataControles;

    var c: char;
        s: string;
        i: integer;

    begin
        saiMeuCarac (ENTER);
        c := readkey;
        case c of
            F1   : ajudaUsuario;
            F2   : begin
                       utilizaCrc (true);
                       mandaArqComput (true);
                   end;
            F3   : recebeArqComput;
            F4   : ligaDeslFala;
            CTLF4: selVelocFala;
            F5   : ;
            F6   : ;
            F7   : ;
            F8   : falaHora;
            CTLF8: falaDia;
            F9   : leitorDeTela;
            F10  : begin
                       window (1, 1, 80, 25);
                       salvax := wherex;
                       salvay := wherey;

                       gotoxy (54, 25);
                       textBackGround (BLACK);
                       clreol;
                       textBackGround (BLUE);
                       mensagem ('DICNFFIM', 0); {Confirma fim (s/n): }
                       textBackGround (BLACK);
                       clreol;

                       if sintFalando then;
                       c := readkey;
                       if upcase(c) = 'S' then
                           conversando := FALSE
                       else
                           begin
                               gotoxy (54, 25);
                               textBackground (BLUE);
                               clreol;
                               textBackGround (BLACK);
                           end;

                        gotoxy (salvax, salvay);
                    end;

            #16..#50:   { ALTS }
                     begin
                         c := tabAlt [ord(c)];
                         s := pegaParam ('MENS'+c);
                         for i := 1 to length(s) do
                             begin
                                 saiMeuCarac (s[i]);
                                 esclink (s[i]);
                             end;
                         saiMeuCarac (ENTER);
                         esclink (ENTER);
                     end;

            PGDN : inicTelaUsuario;
        end;

        xcurMeu := wherex;
        ycurMeu := wherey;
    end;

{--------------------------------------------------------}

begin
    textBackground (RED);
    mensagem ('DISCHAM', 0); {Tecle D para micro discar, E para esperar chamada, R para reconectar: }
    textBackground (BLACK);
    opcao := upcase (letecla(1));
    if opcao = ESC then exit;

    InicLink (porta, veloc, nbits, stops, parid);

    if opcao = 'D' then
        begin
            mensagem ('DISTELUS', 0); {Informe o telefone do usuário parceiro: }
            sintReadln (nomeParceiro);
            if nomeParceiro = '' then exit;
            if discaTelefone (nomeParceiro) then;
        end
    else
    if upcase(opcao) = 'R' then
        begin
            saiLink ('ATX1'+ENTER, 1000);
            mensagem ('DICHRESP', 1); {Seu micro vai ser quem chama (C) ou responde (R) ? }
            opcao := upcase (letecla(1));
                if opcao = 'C' then
                    saiLink ('ATDP'+ENTER, 1000)
                else
                    saiLink ('ATA'+ENTER, 1000);
        end
    else
        saiLink ('ATS0=1'+ENTER, 1000);

    inicTelaUsuario;

    checkBreak := false;

    c := #0;
    conversando := true;
    while conversando do
        begin
            if sintFalando then;
            if keypressed then
                begin
                    c := readkey;

                    if c = #$0 then
                        trataControles
                    else
                        begin
                            esclink (c);
                            saiMeuCarac (c);
                        end;
                end;

            if chegouLink then
                begin
                    lelink (c);
                    if c <> #$0a then
                        saiCaracParceiro (c);
                end;
        end;

    window (1, 1, 80, 25);
    gotoxy (1, 25);
    clreol;

    desligaTelefone (false);

    checkBreak := true;
    finalLink;
    writeln;
end;

{--------------------------------------------------------}
{                    inicialização
{--------------------------------------------------------}

procedure inicializa;
var
    i, erro: integer;
    s: string;
    status: integer;
    result: array [0..144] of char;
begin
    sintInic (0, sintambiente ('DISCAVOX', 'DIRDISCAVOX'));

    GetWindowsDirectory(result, 144);
    s := strPas (result) + '\DOSVOX.INI'+ #$0;
    GetPrivateProfileString('DISCAVOX', 'AMBDISCAVOX', 'C:\WINVOX\DISCAVOX.INI',
                            result, 80, @s[1]);

    ambDiscavox := strPas (result);

    pulse := true;        { valores default }
    porta := 0;
    irq   := 0;
    veloc := 2400;
    nbits := 8;
    stops := 1;
    parid := 0;
    falando := 1;
    modoLynx := false;
    autoArquiva := false;

    if existeArq (ambDiscaVox) then
        begin
            if pegaParam ('DISCA') = 'TONE' then
                 pulse := false;

            s := pegaParam ('PORTA');
            val (s, porta, erro);
            if (porta < 1) or (porta > 4) then
               porta := 4;

            s := pegaParam ('VELOC');
            val (s, veloc, erro);

            s := pegaParam ('NBITS');
            val (s, nbits, erro);

            s := pegaParam ('STOPS');
            val (s, stops, erro);
            if (stops < 0) or (stops > 2) then stops := 1;

            s := pegaParam ('PARID');
            val (s, parid, erro);
            if (parid < 0) or (parid > 2) then parid := 0;

            s := pegaParam ('VELOCTERM');
            val (s, velocterm, erro);

            s := pegaParam ('NBITSTERM');
            if s = '' then
                nbitsterm := 8
            else
                val (s, nbitsterm, erro);

            s := pegaParam ('STOPSTERM');
            if s = '' then
                stopsterm := 1
            else
                val (s, stopsterm, erro);

            s := pegaParam ('PARID');
            if s = '' then
                paridterm := 0
            else
                val (s, paridterm, erro);

            s := 'S';
            s := pegaParam ('FALANDO');
            if s <> 'SIM' then
                begin
                    falando := 0;
                    (*sintCalado (true);*)
                end;
        end;

    if porta = 0 then
        porta := 4;

    if (irq < 3) or (irq > 15) then
        if porta = 4 then  irq := 3
                     else  irq := 4;

    clrscr;
    mensagem ('DIINIC', 0); {Sistema DISCAVOX - NCE/UFRJ, RENDE/USP e RNP - Versão }
    writeln (versao);
    sintSoletra (versao);
    writeln;

    mensagem ('DIINIMOD', 1); {Inicializando modem}

    repeat
        status := InicLink (porta, veloc, nbits, stops, parid);
        if status <> 0 then
            begin
                mensagem ('DIERRPOR', 1); {Erro ao acessar a porta de comunicações}
                configura;
                mensagem ('DIINIMOD', 1); {Inicializando modem}
            end;
    until status = 0;

    for i := 0 to 9 do
        begin
            str (i, s);
            s := pegaParam ('INICMODEM'+s);
            if s <> '' then
                if s = 'ATZ' then
                    sailink (s+ENTER, 3000)
                else
                    sailink (s+ENTER, 500);
        end;

    finalLink;

    writeln;
    mensagem ('DIFIMMOD', 1); {Inicialização do modem concluída, tecle ENTER}
    while readkey <> #$0d do
        sintClek;
    writeln;
end;

{--------------------------------------------------------}
{                      finalização
{--------------------------------------------------------}

procedure finaliza;
begin
    desligaTelefone (true);
    finalLink;

    writeln;
    writeln;
    textBackground (BLUE);
    mensagem ('DIDESLI', 0); {Confira se seu telefone realmente desligou, certo ?}
    textBackground (BLACK);
    writeln;
    writeln;
    mensagem ('DITCHAU', 1); {Até logo, é um prazer servi-lo.}
    delay (2000);

    sintfim;
    doneWinCrt;
end;

{--------------------------------------------------------}
{             controle geral do processamento
{--------------------------------------------------------}

procedure processa;
var
    processando: boolean;
    c: char;

    procedure ajuda;
        begin
            while keypressed do c := readkey;
            mensagem   ('DISAJUD1', 1); {As opções do Discavox são:}
            if not keypressed then
              mensagem ('DISAJUD2', 1); {U - falar com outro usuário}
            if not keypressed then
              mensagem ('DISAJUD3', 1); {R - falar com a Rende');
            if not keypressed then
              mensagem ('DISAJUD4', 1); {T - vira terminal de um computador}
            if not keypressed then
              mensagem ('DISAJUD6', 1); {C - configurar comunicação com computador}
            if not keypressed then
              mensagem ('DISAJUD7', 1); {ESC - termina o programa}
        end;

begin
    processando := true;
    while processando do
        begin
            textBackground (BLUE);
            writeln;
            while keypressed do
                begin
                    c := readkey;
                    sintClek;
                end;

            mensagem ('DISOPCAO', 0); {Discavox - Qual sua opção ? }
            textBackground (BLACK);
            clreol;
            c := upcase (letecla (1));
            case c of
                'U':  falaComGente;
                'R':  falaComRende;
                'T':  termComputador;
                'C':  configura;
               #$0d:  ;
               #$1b:  processando := false;
                 #0:  begin
                          c := readkey;
                          case c of
                              F9: processando := false;
                          else
                             ajuda;
                          end;
                      end;
            else
                 ajuda;
            end;
        end;
end;

begin
    inicializa;
    processa;
    finaliza;
end.
