/*--------------------------------------------------------------------
 * FICHERO:  DbnEdita.c
 * OBJETIVO: Definir la funcin Dbn_Edita()
 * AUTOR:    Pedro Reina
 * FECHA:    J.10.8.1995
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * Funciones privadas
 *
 *   Dbn_Representa()
 *   Dbn_RepresentaPunto()
 *   Dbn_RepresentaMarca()
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * Ficheros de cabecera
 *------------------------------------------------------------------*/

#include "Diblane.h"

/*--------------------------------------------------------------------
 * Declaracin de funciones
 *------------------------------------------------------------------*/

static void Dbn_Representa();
static void Dbn_RepresentaPunto();
static void Dbn_RepresentaMarca();

/*--------------------------------------------------------------------
 * Definicin de funciones
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------Olimpo
 * FUNCION:  Dbn_Edita()
 * OBJETIVO: Editar un objeto "diblane" en una zona
 * ENTRADAS: Un diblane y una zona
 * SALIDAS:  Lgica, que indica si el diblane ha sido modificado,
 *           entendiendo como modificado que el usuario termin
 *           pulsando ENTER
 * EJEMPLO:  Dbn_Edita (Dibujo, Zona)
 * NOTAS:    1. Esta funcin slo se debe usar con diblanes
 *              de pequeas dimensiones
 *           2. Esta funcin cambia la escala de la zona
 * ALGORITMO:
 *      Calcular las dimensiones de los cuadros que representarn los puntos
 *      Representar el diblane en la zona
 *      Pedir memoria auxiliar
 *      Si hay memoria
 *        Copiar los datos del diblane a memoria reservada
 *        Pedir teclas y tratarlas
 *        Si el usuario termina con ESC
 *          Copiar los datos de la memoria reservada al diblane
 *      Si no hay memoria, avisar al usuario
 *------------------------------------------------------------------*/
logico Dbn_Edita (Dibujo, Zona)
diblane Dibujo;
zona    Zona;
  {
  static tecla Orden[] = { TEC_IZQUIERDA, TEC_DERECHA, TEC_ARRIBA, TEC_ABAJO,
                           TEC_INICIO, TEC_FIN, TEC_AVPAG, TEC_REPAG,
                           TEC_ENTER, TEC_ESC, TEC_ESPACIO,
                           TEC_F3, TEC_F4, TEC_F5, NIL };
  real    AltoPunto, AnchoPunto, AltoMarca, AnchoMarca;
  entero  Fila=0, Columna=0, NuevaFila=0, NuevaColumna=0;
  logico  Sigue, Respuesta;
  octeto  Valor;
  tecla   Tecla;
  memoria Aux;

  Zon_Escala (Zona, 1000.0, -1000.0, 0.0, 0.0 );

  AnchoPunto = Abs (Zon_Ancho(Zona)) / Dbn_Ancho(Dibujo);
  AltoPunto = Abs (Zon_Alto(Zona)) / Dbn_Alto(Dibujo);

  AnchoMarca = AnchoPunto / 3;
  AltoMarca = AltoPunto / 3;

  Dbn_Representa (Dibujo, Zona, AnchoPunto, AltoPunto);

  if ( Aux = Mem_Crea (Dbn_Tamano(Dibujo)) )
    {
    Mem_Copia (Aux, Dbn_Dato(Dibujo), Dbn_Tamano(Dibujo));
    Usr_Indica (
      "CURSOR, INICIO, FIN, AVPAG, REPAG: mueve marca. ESPACIO: cambia color.",
      "ENTER: termina. ESC: anula. F3: invierte. F4: original. F5: borra." );

    while ( Sigue )
      {
      Dbn_RepresentaMarca (Zona, Fila, Columna, AnchoPunto, AltoPunto,
                           AnchoMarca, AltoMarca);
      switch ( Tecla = Tec_Validada (Orden) )
        {
        case TEC_ENTER:     Sigue = NO;  Respuesta = SI;          break;
        case TEC_ESC:       Sigue = NO;  Respuesta = NO;          break;
        case TEC_INICIO:    NuevaColumna = 0;                     break;
        case TEC_FIN:       NuevaColumna = Dbn_Ancho(Dibujo)-1;   break;
        case TEC_REPAG:     NuevaFila = 0;                        break;
        case TEC_AVPAG:     NuevaFila = Dbn_Alto(Dibujo)-1;       break;
        case TEC_DERECHA:   if ( Columna < Dbn_Ancho(Dibujo)-1 )
                              { NuevaColumna = Columna+1; }
                            break;
        case TEC_IZQUIERDA: if ( Columna )
                              { NuevaColumna = Columna-1; }
                            break;
        case TEC_ABAJO:     if ( Fila < Dbn_Alto(Dibujo)-1 )
                              { NuevaFila = Fila+1; }
                            break;
        case TEC_ARRIBA:    if ( Fila )
                              { NuevaFila = Fila-1; }
                            break;
        case TEC_ESPACIO:   Valor = Dbn_Punto(Dibujo,Fila,Columna) ? 0 : 1;
                            Dbn_PonPunto (Dibujo, Fila, Columna, Valor);
                            break;
        case TEC_F3:        Dbn_Invierte (Dibujo);
                            Dbn_Representa (Dibujo, Zona,
                                            AnchoPunto, AltoPunto);
                            break;
        case TEC_F4:        Mem_Copia (Dbn_Dato(Dibujo), Aux,
                                       Dbn_Tamano(Dibujo));
                            Dbn_Representa (Dibujo, Zona,
                                            AnchoPunto, AltoPunto);
                            break;
        case TEC_F5:        Mem_Asigna (Dbn_Dato(Dibujo), 0,
                                        Dbn_Tamano(Dibujo));
                            Dbn_Representa (Dibujo, Zona,
                                            AnchoPunto, AltoPunto);
                            break;
        }

      if ( Fila == NuevaFila && Columna == NuevaColumna &&
           Tecla != TEC_ENTER && Tecla != TEC_ESC && Tecla != TEC_ESPACIO &&
           Tecla != TEC_F3 && Tecla != TEC_F4 && Tecla != TEC_F5 )
        { Son_MalaTecla(); }

      else
        {
        Dbn_RepresentaPunto (Dibujo, Zona, Fila, Columna,
                             AnchoPunto, AltoPunto);
        Fila = NuevaFila;
        Columna = NuevaColumna;
        }
      }

    if ( Respuesta == NO )
      { Mem_Copia (Dbn_Dato(Dibujo), Aux, Dbn_Tamano(Dibujo)); }

    Mem_Destruye (Aux);
    Usr_BorraZona (NEGRO);
    }

  else  /* No hay memoria para reservar el dibujo */
    {
    Usr_Avisa ("No hay memoria para la edicin");
    Respuesta = NO;
    }

  return ( Respuesta );
  }

/*--------------------------------------------------------------------
 * FUNCION:  Dbn_Representa()
 * OBJETIVO: Representar un diblane en una zona, ampliando cada punto
 * ENTRADAS: Un diblane, una zona, el ancho y el alto que se usarn
 *           para dibujar la representacin de cada punto
 * SALIDAS:  Ninguna
 * EJEMPLO:  Dbn_Representa ( Dibujo, Zona, 25.2, 40.1 )
 *------------------------------------------------------------------*/
void Dbn_Representa (Dibujo, Zona, Ancho, Alto)
diblane Dibujo;
zona Zona;
real Ancho, Alto;
  {
  entero i, j;

  for ( i=0 ; i<Dbn_Alto(Dibujo) ; i++ ) {
  for ( j=0 ; j<Dbn_Ancho(Dibujo) ; j++ ) {
    Dbn_RepresentaPunto (Dibujo, Zona, i, j, Ancho, Alto);
    }}
  }

/*--------------------------------------------------------------------
 * FUNCION:  Dbn_RepresentaPunto()
 * OBJETIVO: Representar un punto de un diblane en una zona
 * ENTRADAS: Un diblane, una zona, la fila y columna del punto
 *           y el ancho y el alto que se usarn
 *           para dibujar la representacin del punto
 * SALIDAS:  Ninguna
 * EJEMPLO:  Dbn_RepresentaPunto ( Dibujo, Zona, 3, 2, 25.4, 40.2 )
 *------------------------------------------------------------------*/
void Dbn_RepresentaPunto (Dibujo, Zona, Fila, Columna, Ancho, Alto)
diblane Dibujo;
zona   Zona;
entero Fila, Columna;
real   Ancho, Alto;
  {
  octeto Color;
  real   ComienzoX, ComienzoY, FinalX, FinalY;

  Color = Dbn_Punto (Dibujo, Fila, Columna) ? BLANCO : NEGRO;
  ComienzoX = Ancho * Columna;
  ComienzoY = Alto * Fila;
  FinalX = ComienzoX + Ancho;
  FinalY = ComienzoY + Alto;

  Zon_Bloque (Zona, ComienzoX, ComienzoY, FinalX, FinalY, Color);
  }

/*--------------------------------------------------------------------
 * FUNCION:  Dbn_RepresentaMarca()
 * OBJETIVO: Representar una marca en un punto de un diblane en una zona
 * ENTRADAS: Una zona, la fila y columna del punto
 *           y el ancho y el alto que se usarn para dibujar la
 *           representacin del punto y el ancho y alto que se usarn
 *           para representar la marca
 * SALIDAS:  Ninguna
 * EJEMPLO:  Dbn_RepresentaPunto ( Dibujo, Zona, 3, 2, 25.2, 40.0,
                                   8.1, 13.0 )
 *------------------------------------------------------------------*/
void Dbn_RepresentaMarca (Zona, Fila, Columna, Ancho, Alto,
                          AnchoMarca, AltoMarca)
zona   Zona;
entero Fila, Columna;
real   Ancho, Alto, AnchoMarca, AltoMarca;
  {
  real ComienzoX, ComienzoY, FinalX, FinalY;

  ComienzoX = Ancho * Columna + AnchoMarca;
  ComienzoY = Alto * Fila + AltoMarca;
  FinalX = ComienzoX + AnchoMarca;
  FinalY = ComienzoY + AltoMarca;

  Zon_Bloque (Zona, ComienzoX, ComienzoY, FinalX, FinalY, VERDE);
  }
