{--------------------------------------------------------}
{
{    Jogavox - criador de jogos educacionais
{
{    Módulo de edição dos slides de um local
{
{    Autores: José Antonio Borges
{             Lidiane Figueira Silva
{             Bernard Condorcet
{
{    Em Março/2009
{
{--------------------------------------------------------}

unit joslides;

interface

uses
    windows, dvwin, dvcrt, classes, dvform, sysUtils, jovars, jomsg, joarq, joexibe;

function inicializaSlide: PSlide;
procedure editaSlides (lugarPai: PLugar);
procedure desalocaSlide (sl: PSlide);
procedure criaSlideAuto (lugarPai: PLugar);

implementation

{--------------------------------------------------------}
{                    edita o slide
{--------------------------------------------------------}

function editaSlide  (lugarPai: PLugar; slideAtual: integer): char;
const
    MAXCAMPOS = 30;
var
    nom, copiaNom: array [1..MAXCAMPOS] of shortString;
    sl: PSlide;
    i: integer;
    c1, c2: char;
    listaMidias, listaFigs: string;
    iguais: boolean;
    resultEdita: char;

begin
    window (1, 1, 80, 25);
    clrScr;
    setWindowTitle('Jogavox ' + nomeArqJogo);

    TextBackground(BLUE);
    mensagem ('JOEDSLID', 2);      {'Editore o slide, ESC termina'}

    TextBackground (BLACK);

    formCria;
    sl := lugarPai^.slides[slideAtual];

    with sl^ do
        begin
            nom[1] := titulo;
            nom[2] := figura;
            nom[3] := posFigura;
            nom[4] := midiaSlide;
            nom[5] := strBool (esperaMidia);
            nom[6] := avancaEm;
            nom[7] := efeito;
            nom[8] := falaTexto;
            nom[9] := posTexto;
            for i := 1 to 10 do
                if  texto.Count < i then nom[i+9] := ''
                                    else nom[i+9] := texto[i-1];
        end;

    listaFigs   := geraListaArqs ('*.bmp')  + '|' +
                   geraListaArqs ('*.jpg')  + '|' +
                   geraListaArqs ('*.jpeg') + '|' +
                   geraListaArqs ('*.png');
    listaFigs   := normalizaLista (listaFigs);

    listaMidias := geraListaArqs ('*.wav') + '|' +
                   geraListaArqs ('*.wma') + '|' +
                   geraListaArqs ('*.wmv') + '|' +
                   geraListaArqs ('*.mid') + '|' +
                   geraListaArqs ('*.mp3') + '|' +
                   geraListaArqs ('*.avi') + '|' +
                   geraListaArqs ('*.mp4') + '|' +
                   geraListaArqs ('*.mpg') + '|' +
                   geraListaArqs ('*.mpeg');
    listaMidias := normalizaLista (listaMidias);

    copiaNom := nom;

    campo ('JOSL_TIT', nom[1], 60);                       {'Título'}
    campoLista ('JOSL_FIG', nom[2], 80, listaFigs);       {'Figura'}
    campoLista ('JOSL_PFG', nom[3], 60, listaPosicoes);   {'Posição da figura'}
    campoLista ('JOSL_MID', nom[4], 80, listaMidias);     {'Midia a tocar'}
    campoLista ('JOSL_ESP', nom[5], 4,  simNao);          {'Espera a mídia'}
    campoLista ('JOSL_AVN', nom[6], 20, listaAvancos);    {'Avanço automático'}
    campoLista ('JOSL_EFT', nom[7], 60, listaEfeitos);    {'Efeito'}
    campo ('JOSL_FAL', nom[8],  120);     {'Fala Texto'}
    campoLista ('JOSL_PTX', nom[9], 60, listaPosicoes);   {'Posição do texto'}
    campo ('JOSL_T1',  nom[10], 50);      {'Texto 1'}
    campo ('JOSL_T2',  nom[11], 50);      {'Texto 2'}
    campo ('JOSL_T3',  nom[12], 50);      {'Texto 3'}
    campo ('JOSL_T4',  nom[13], 50);      {'Texto 4'}
    campo ('JOSL_T5',  nom[14], 50);      {'Texto 5'}
    campo ('JOSL_T6',  nom[15], 50);      {'Texto 6'}
    campo ('JOSL_T7',  nom[16], 50);      {'Texto 7'}
    campo ('JOSL_T8',  nom[17], 50);      {'Texto 8'}
    campo ('JOSL_T9',  nom[18], 50);      {'Texto 9'}
    campo ('JOSL_T10', nom[19], 50);      {'Texto 10'}
    resultEdita := formEdita(true);

    iguais := true;
    for i := 1 to MAXCAMPOS do
        if nom[i] <> copiaNom [i] then
            begin
                iguais := false;
                break;
            end;
    if iguais then
        begin
            sintetiza (pegaTextoMensagem ('JOOK'));
            result := resultEdita;
            exit;
        end;

    mensagem ('JOCONFAL', 0);            {'Confirma as alterações? '}
    sintLeTecla (c1, c2);
    writeln;
    if (upcase(c1) = 'N') or (c1 = ESC) then
        begin
            result := ESC;
            mensagem ('JODESIST', 2);    {'Desistiu'}
            exit;
        end;

    with sl^ do
        begin
            titulo := nom[1];
            figura := nom[2];
            posFigura := nom[3];
            midiaSlide := nom[4];
            esperaMidia := (nom[5] = '') or (copy (ansiUpperCase (nom[5])[1], 1, 1) <> 'N');
            avancaEm := nom[6];
            efeito := nom[7];
            falaTexto := nom[8];
            posTexto := nom[9];
            texto.clear;
            for i := 1 to 10 do
                texto.add (nom[i+9]);
        end;

    result := resultEdita;
end;

{--------------------------------------------------------}
{               cria um slide e inicializa
{--------------------------------------------------------}

function inicializaSlide: PSlide;
var
    ps: pSlide;
begin
    new (ps);
    ps^.titulo := 'Novo slide';
    ps^.figura := '';
    ps^.posFigura := '';
    ps^.midiaSlide := '';
    ps^.esperaMidia := true;
    ps^.avancaEm := 'AUTO';
    ps^.efeito := '';
    ps^.falaTexto := '';
    ps^.posTexto := '';
    ps^.texto := TStringList.Create;

    result := ps;
end;

{--------------------------------------------------------}
{                   insere um novo slide
{--------------------------------------------------------}

function insereSlide (lugarPai: PLugar; slideAtual: integer; duplicando, perguntando: boolean): boolean;
var
    i: integer;
    sl: PSlide;
    nome: string;
    posic: char;
begin
    result := false;
    if lugarPai^.numSlides >= MAXSLIDESLUGAR then
        begin
            mensagem ('JOSLDMAX', 1);  {'Excedido o número máximo de slides deste lugar'}
            exit;
        end;

    sl := inicializaSlide;
    if duplicando then
        with lugarPai^.slides[slideAtual]^ do
        begin
            sl^.figura := figura;
            sl^.posFigura := posFigura;
            sl^.midiaSlide := midiaSlide;
            sl^.esperaMidia := esperaMidia;
            sl^.avancaEm := avancaEm;
            sl^.efeito := efeito;
            sl^.falaTexto := falaTexto;
            sl^.posTexto := posTexto;
            sl^.texto.assign (texto);
        end;

    if perguntando then
        begin
            mensagem ('JOTITSLD', 1);   {'Informe o título do slide'}
            sintReadln (nome);
            if nome <> '' then
                sl^.titulo := nome;

            mensagem ('JOANTDEP', 0);   {'Insere antes ou depois daqui? }
            posic := upcase(sintReadkey);
            if posic = ESC then
                begin
                    mensagem ('JODESIST', 1);  {'Desistiu'}
                    exit;
                end
            else
                begin
                    write (posic);
                    if posic = 'D' then
                        if slideAtual <= lugarPai^.numSlides then
                             slideAtual := slideAtual + 1;
                end;
        end;

    for i := lugarPai^.numSlides downto slideAtual do
        lugarPai^.slides[i+1] := lugarPai^.slides[i];
    inc (lugarPai^.numSlides);
    lugarPai^.slides[slideAtual] := sl;

    result := true;
end;

{--------------------------------------------------------}
{                   move slides de lugar
{--------------------------------------------------------}

procedure moveSlide (lugarPai: PLugar; slideAtual: integer);
var
    i: integer;
    sl: PSlide;
    c1, c2: char;
    salvaNumSlide: integer;
begin
    mensagem ('JOINFMOV', 1);   {'Informe o lugar para o qual vai mover'}

    salvaNumSlide := slideAtual;

    window (1, 1, 25, 80);
    folheiaCria (1, 7, 30, 7+9);
    for i := 1 to lugarPai^.numSlides do
        folheiaAdiciona (intToStr (i) + ' - ' + lugarPai^.slides[i].titulo);
    folheiaAdiciona ('Último slide');

    if not folheiaExecuta (slideAtual, slideAtual, c1, c2, true) or
            (slideAtual <= 0) or (slideAtual > lugarPai^.numSlides) then
        begin
             folheiaDestroi;
             gotoxy (1, 24);
             mensagem ('JODESIST', 1);   {'Desistiu'}
             while sintFalando do delay (100);
             delay (1000);
             exit;
        end;

    folheiaDestroi;
    sl := lugarPai^.slides[salvaNumSlide];

    for i := salvaNumSlide to lugarPai^.numSlides-1 do
        lugarPai^.slides[i] := lugarPai^.slides[i+1];
    for i := lugarPai^.numSlides downto slideAtual do
        lugarPai^.slides[i+1] := lugarPai^.slides[i];
    lugarPai^.slides[slideAtual] := sl;
end;

{--------------------------------------------------------}
{                 desaloca um slide
{--------------------------------------------------------}

procedure desalocaSlide (sl: PSlide);
begin
    sl.texto.free;
end;

{--------------------------------------------------------}
{                   remove um slide
{--------------------------------------------------------}

procedure removeSlide (lugarPai: PLugar; slideAtual: integer);
var c1, c2: char;
    i: integer;
    sl: PSlide;
begin
    if (SlideAtual < 1) or (slideAtual > lugarPai^.numSlides) then
        begin
             mensagem ('JOSLDINV', 1);   {'Slide inválido'}
             exit;
        end;

    mensagem ('JOCONREM', 0);            {'Confirma a remoção? '}
    sintLeTecla (c1, c2);
    writeln;
    if (upcase(c1) = 'N') or (c1 = ESC) then
        begin
            mensagem ('JODESIST', 2);    {'Desistiu'}
            exit;
        end;

    sl := lugarPai^.slides[slideAtual];
    desalocaSlide (sl);

    with lugarPai^ do
        begin
            for i := slideAtual to numSlides-1 do
                slides[i] := slides[i+1];
            dec (numSlides);
        end;
end;

{--------------------------------------------------------}
{                   visualiza o slide
{--------------------------------------------------------}

procedure visualizaSlide (lugarPai: PLugar; slideAtual: integer);
begin
    if (slideAtual > 0) and (slideAtual <= lugarPai^.numSlides) then
        exibeSlide (lugarPai, slideAtual, '')
    else
        sintBip;
    closeBmp;
end;

{--------------------------------------------------------}
{                  ajuda da edição de locais
{--------------------------------------------------------}

procedure ajudaEditaSlides(falando: boolean);

    procedure msg (som: string; pula: integer);
    begin
        if falando then
            mensagem (som, pula)
        else
            msgMuda (som, pula);
    end;

begin
    window (40, 7, 80, 7 + 6);
    textBackground (MAGENTA);
    clrscr;
    msg ('JOOPCOES', 1);    {'As opções são:'}
    msg ('JOAJS_I', 1);     {'I - inserir novo slide'}
    msg ('JOAJS_M', 1);     {'M - mover slide'}
    msg ('JOAJS_R', 1);     {'R - remover slide'}
    msg ('JOAJS_D', 1);     {'D - duplicar slide'}
    msg ('JOAJS_E', 1);     {'E - editar slide'}
    msg ('JOAJS_V', 0);     {'V - visualizar slide'}
    textBackground (BLACK);

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

{--------------------------------------------------------}
{                   menu de opções
{--------------------------------------------------------}

const
    nitens = 6;

function menuEditaSlides: char;
const
    letrasMenu: array [0..nitens] of char = (ESC, 'I', 'E', 'R', 'M', 'D', 'V');
var
    item: integer;
begin
    window (40, 7, 80, 7+nitens);
    textBackground (BLACK);
    clrscr;
    window (1, 1, 80, 25);

    popupMenuCria(40, 7, 40, nitens, MAGENTA);
    MenuAdiciona('JOAJS_I');  {'I - inserir novo slide'}
    MenuAdiciona('JOAJS_E');  {'E - editar slide'}
    MenuAdiciona('JOAJS_R');  {'R - remover slide'}
    MenuAdiciona('JOAJS_M');  {'M - mover slide'}
    MenuAdiciona('JOAJS_D');  {'D - duplicar slide'}
    MenuAdiciona('JOAJS_V');  {'V - visualizar slide'}

    item := popupMenuSeleciona;

    if (item <= 0) or (item > nitens) then item := 0;
    menuEditaSlides := letrasMenu[item];
end;

{--------------------------------------------------------}
{            cria slide para lugar vazio
{--------------------------------------------------------}

procedure criaSlideAuto (lugarPai: PLugar);
var c1, c2: char;
begin
    writeln;
    mensagem ('JOSEMSLD', 1);   {'Este lugar ainda não tem nenhum slide.'}
    mensagem ('JOCRIAUT', 0);   {'Posso criar automaticamente? '}
    sintLeTecla (c1, c2);
    writeln;
    if c1 = ESC then
        begin
            mensagem ('JODESIST', 2);    {'Desistiu'}
            exit;
        end;
    if upcase(c1) <> 'N' then
        begin
            insereSlide (lugarPai, 1, false, false);
            lugarPai^.slides[1].titulo := lugarPai^.nome + ' 1';
            lugarPai^.slides[1].texto.add (lugarPai^.categoria);
        end;
end;

{--------------------------------------------------------}
{              edita os slides de um local
{--------------------------------------------------------}

procedure editaSlides (lugarPai: PLugar);
var
    c1, c2, codEdita: char;
    i: integer;
    primeiraVez: boolean;

label interpreta;
begin
    if lugarPai^.numSlides = 0 then
        criaSlideAuto (lugarPai);

    primeiraVez := true;
    repeat
        window (1, 1, 80, 25);
        clrScr;
        setWindowTitle('Jogavox ' + nomeArqJogo);

        if not primeiraVez and (lugarPai^.numSlides > 0) then
            begin
                primeiraVez := false;
                c1 := ENTER;
                indSlideEditando := 1;
                goto interpreta;
            end;

        TextBackground(BLUE);
        mensagem ('JOEDISLI', 2);      {'Editando os slides do jogo'}
        TextBackground (BLACK);
        mensagem ('JOSLISET', 2);      {'Escolha o slide com as setas, tecle F9 para opções'}

        TextBackground (BLACK);
        write (pegaTextoMensagem('JOEDNLUG'), ': ', lugarPai^.nome);

        folheiaCria (1, 7, 30, 7+9);
        for i := 1 to lugarPai^.numSlides do
            folheiaAdiciona (intToStr (i) + ' - ' + lugarPai^.slides[i].titulo);
        folheiaAdiciona ('Último slide');

        ajudaEditaSlides (false);

        if not folheiaExecuta (indSlideEditando, indSlideEditando, c1, c2, true) then
            c1 := ESC;

        folheiaDestroi;

interpreta:
        if indSlideEditando < 1 then continue;
        if (indSlideEditando > lugarPai^.numSlides) and
           (upcase(c1) <> 'I') and (c2 <> F9) then continue;

        window (40, 7, 80, 25);
        textBackground (BLACK);
        clrscr;

        if c1 <> #$0 then
            case upcase(c1) of
                'I': insereSlide (lugarPai, indSlideEditando, false, true);
                'D': insereSlide (lugarPai, indSlideEditando, true, true);
                'M': moveSlide  (lugarPai, indSlideEditando);
                'R': removeSlide (lugarPai, indSlideEditando);
                'E', ENTER:
                     begin
                         window (1, 1, 80, 25);
                         repeat
                             codEdita := editaSlide (lugarPai, indSlideEditando);
                             case codEdita of
                                  PGUP:      begin
                                                 if indSlideEditando <= 1 then break;
                                                 dec (indSlideEditando);
                                             end;
                                  PGDN:      begin
                                                 if indSlideEditando >= lugarPai^.numSlides then break;
                                                 inc (indSlideEditando);
                                             end;
                                  CTLPGUP:   indSlideEditando := 1;
                                  CTLPGDN:   indSlideEditando := lugarPai^.numSlides;
                             end;
                         until codEdita = ESC;
                     end;
                'V': begin
                         clrscr;
                         gotoxy (1, 80);
                         visualizaSlide (lugarPai, indSlideEditando);
                         sintetiza (pegaTextoMensagem ('JOAPTENT'));   {'Aperte enter'}
                         readln;
                         clrscr;
                     end;
                ESC: ;
            else
                mensagem ('JOOPINV', 1);    {'Opção inválida'}
                mensagem ('JOF1F9', 2);     {'Aperte F9 para menu, F1 para ajuda'}
            end
        else
            case c2 of
                F1: ajudaEditaSlides (true);
                F2: salvaJogo;
                F7: removeSlide (lugarPai, indSlideEditando);
                F9: begin
                        c1 := menuEditaSlides;
                        c2 := #$0;
                        if c1 <> ESC then goto interpreta;
                    end;
                DIR: begin
                         exibeSlide (lugarPai, indSlideEditando, 'minitela');
                         while not keypressed do waitMessage;
                         InvalidateRect (crtWindow, NIL, true);
                     end;

            else
                mensagem ('JOOPINV', 1);    {'Opção inválida'}
            end;

    until c1 = ESC;
end;

end.

