{--------------------------------------------------------}
{
{    Programa Editor Vocal
{
{    Autor: Marcelo Luis Pinheiro
{
{    Orientador Academico: Jose' Antonio Borges
{
{    Em 10/12/93
{
{    Versao 3.0 de 25/4/96
{
{--------------------------------------------------------}

{$M 16384,8192}

program Edivox;
uses
    WinProcs,   { rotinas do Windows }
    WinTypes,   { tipos do Windows }
    Strings,    { manipulacao de cadeias estilo Windows }
    dvCrt,      { rotinas de manuseio da tela }
    dvWin,      { rotinas basicas de fala }
    dvWav,      { rotinas básicas de som }
    dvHora,     { rotinas de manipulação da hora }
    edVars,     { variaveis e acesso basico a elas }
    edMensag,   { mensagens }
    edFala,     { controle da fala }
    edTela,     { manuseio de tela }
    edCursor,   { manipulacao de caracteres e cursor }
    edAcento,   { tratamento dos acentos }
    edLinha,    { tratamento de linhas }
    edArq,      { funcoes de arquivos}
    edBloco,    { blocos de linhas }
    edBusca,    { busca e substituicao de textos }
    edMargem,   { margens e tabulacoes }
    edConfig,   { configuracao }
    edTransf;   { area de transferencia }

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

procedure inicializa;
var
     s: string;
     erro: integer;
     n: integer;
     c: char;

begin
    checkbreak := false;
    checkFocus := true;
    dirSomEdivox := sintAmbiente ('EDIVOX', 'DIREDIVOX');

    s := sintAmbiente ('EDIVOX', 'VELOCIDADE');
    if s = '' then
        n := 0
    else
        val (s, n, erro);
    sintInic (n, DIRsomEdivox);

    tamMaxLinha := 79;
    desenhaTelaInicial;

    while keypressed do c := readkey;

    nomeArq := '';
    if paramCount >= 1 then
        nomeArq := paramStr(1);

    fala ('EDMSGINI');

    margdir := 72;
    margesq := 1;
    ntabs := 0;

    mudo := false;
    soletrando := true;
    rapidinho := false;

    enterInsLinha := copy (sintAmbiente ('EDIVOX', 'ENTERINSLINHA'), 1, 1) = 'S';
    acentuando := copy (sintAmbiente ('EDIVOX', 'ACENTUAR'), 1, 1) <> 'N';
    quebraAuto := copy (sintAmbiente ('EDIVOX', 'QUEBRARLINHAS'), 1, 1) <> 'N';
    falaPontuacao := copy (sintAmbiente ('EDIVOX', 'FALARPONTUACAO'), 1, 1) <> 'N';
    autofala := copy (sintAmbiente ('EDIVOX', 'FALAAUTOMATICA'), 1, 1) = 'S';

    statusTecControle := 0;
    maxlinhas := 0;
    buscado := #0;
    linhaRemovida := '';

    salvaCurx := 1;
    salvaCury := 1;

    deslocEsqTela := 0;
    corLetra := LIGHTGRAY;
    corFundo := BLACK;

    inicBloco;
end;

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

procedure comandoInterativo;
var tecla: char;

label deNovo;

begin
deNovo:
    fala ('EDCOMAND');   { comando ? }
    tecla := leTeclaMaiusc;
    escreveTela;

    case tecla of
       'C': cmdCursor;
       'L': cmdLinha;
       'P': cmdBusca;
       'M': cmdMargem;
       'A': cmdArquivo;
       'B': cmdBloco;
       'F': cmdFala;
       'I': cmdConfig;
       'E': trataLetrasEspeciais;
       #$0: begin
                ajuda ('EDAJIN', 10);
                goto deNovo;
            end;
      #$1b: begin
                fala ('EDDESIST');
                exit;
            end
    else
        sintBip;
    end;

    escreveTela;
end;

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

procedure trataPFeALT (tecla: char);
var salva: integer;
Begin
    Case tecla of
        F1 :  begin
                  if getKeyState (vk_Menu) >= 0 then
                      falaPalavra
                  else
                      begin
                          tecla := ALTF1;
                          falaRestoTexto;
                      end;
              end;

        CTLF1 :  falaRestoLinha;
        ALTF1 :  falaRestoTexto;

        F2 :     salvaArquivo (1, maxlinhas, true);
        F3 :     begin
                     trocaarquivo;
                     inicBloco;
                     escreveTela;
                 end;

        F4 :    if getKeyState (vk_Menu) >= 0 then
                    acionaSoletragem
                else
                    terminaPrograma;
        CTLF4 :  trocaVeloc;

        F5 :     buscaPalavra;
        CTLF5 :  buscaDeNovo;
        F6:      trocaPalavra;
        F7:      trocaTamTela;

        F8:      falaHora;
        CTLF8:   falaDia;

        F9:      comandoInterativo;
        F10:     pedeMargens;

        CTLPGUP: inicioTexto;
        CTLPGDN: fimTexto;

        CTLDIR:  palavraDir (true);
        CTLESQ:  palavraEsq (true);
        CTLHOME: setaVertCima;
        CTLEND:  setaVertBaixo;

        INS :    acionaInsert;
        DEL :    removeProxLetra;

        DIR :    setaDir;
        ESQ :    setaEsq;

        CIMA:    if (statusTecControle and CONTROL) <> 0 then
                     SetaVertCima
                 else
                     SetaCima;

        BAIX:    if (statusTecControle and CONTROL) <> 0 then
                     SetaVertBaixo
                 else
                     Setabaixo;

        HOME: coluna1;
        TEND: ultimaColuna;
        PGUP: voltaPag;
        PGDN: pulaPag;

        CTLINS:       jogaAreaTransf;
        SHIFTINS:     pegaAreaTransf;

        else  { of case }

            sintBip;
            sintBip;
    end;

    if tecla in [CTLF1, ALTF1, F3, F5, CTLF5, F6, F7, F9, F10,
             CTLPGUP, CTLPGDN, CTLDIR, CTLESQ, CTLHOME, CTLEND,
             CIMA, BAIX, PGUP, PGDN,
             SHIFTINS] then
        escreveTela
    else
        escreveLinha;

    if tecla in [CIMA,BAIX, PGUP, PGDN, CTLPGUP, CTLPGDN, F3, F5, CTLF5, F6] then
        if autoFala then
            begin
                salva := posx;     
                falaRestoLinha;
                posx := salva;
            end;
End;

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

function criaLinhaNaMargem: string;
var s: string;
    i: integer;
begin
    s := '';
    for i := 1 to margEsq-1 do
        s := s + ' ';

    sintClek;
    if margEsq > 1 then
        sintClek;

    criaLinhaNaMargem := s;
end;

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

procedure proxLinhaNaMargem;
var salva: string;

begin
    setaBaixo;
    salva := texto[posy]^;
    while length (salva) < margEsq do
        salva := salva + ' ';
    removeLinha (false);
    insereLinha (salva, false);
    posx := margEsq;
end;

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

procedure trataControls (tecla: char);
begin
    case tecla of
        ^a : acionaAcentos;

        ^y : removelinha (true);
        ^d : apagaFimlinha;
        ^s : apagaInicioLinha;

        ^q : quebralinha;

        ^j:  { control enter }
             insereLinha (criaLinhaNaMargem, true);

        ^m : {tratamento de enter}
             if enterInsLinha or (posy = maxLinhas) then
                 insereProxLinha (criaLinhaNaMargem, true)
             else
                 proxLinhaNaMargem;

        ^I : tabulaInsere;
        ^t : tabula;
        ^h : removeLetra;
        ^b : trataBloco;

        ^l : informaLinha;
        ^c : informaColuna;

        ^u : voltaRemovida;
        ^e : trataLetrasEspeciais;
        ^x : gravaETermina;
        ^g : posicEmLinha;

        CTLBS:   apagaPalavra;

    else { case }

        sintBip;   { teclas invalidas dao dois bips }
        sintBip;
    end;

    escreveTela;
end;

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

function confirmasaida: boolean;
var resp: char;

begin
    confirmaSaida := true;

    repeat
        fala ('EDCNFSAI');     {--- confirma saida ---}
        resp := leTeclaMaiusc;
    until resp in ['S','N'];

    if resp = 'N' then
        begin
            confirmaSaida := false;
            exit;
        end;

    repeat                     {--- ve se quer salvar o arquivo ---}
        delay (500);
        fala ('EDQUERSV');
        resp := leTeclaMaiusc;
    until resp in ['S', 'N'];

    if resp = 'S' then
        salvaArquivo (1, maxLinhas, true);
end;

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

var tecla, tecla2: char;
    progAcabou: boolean;
    ultimoTitulo, tituloAtual: array [0..80] of char;
    trocouJanela: boolean;

begin
{$R+}
    inicializa;
    if not abrearquivo then
        terminaPrograma;

    escreveTela;
    getWindowText (getFocus, ultimoTitulo, 80);
    trocouJanela := false;
    if autoFala then falaRestoLinha;
    posx := 1;

    progAcabou := false;
    repeat
        gotoxy (posx-deslocEsqTela, 15);
        forceCursor;

        repeat
            trataStatusTec (statusTecControle);
            gotoxy (posx-deslocEsqTela, 15);
        until keypressed;

        tecla := readkey;
        waveStop;
        unforceCursor;

        case tecla of
             GOTFOCUS, NOFOCUS: ;
             '''', '^', '~', '`','"':
                         if acentuando then
                             trataAcentos (tecla)
                         else
                             insereLetra (tecla);
             #32..#126,
             #128..#255: insereLetra (tecla);

             #27 :       progAcabou := confirmasaida;

             #0:         trataPFeALT (readkey);

             #1..#31, #127:
                         trataControls (tecla);
        End;

    Until progAcabou;

    terminaPrograma;
end.
