/*--------------------------------------------------------------------
 * FICHERO:  UsrEdita.c
 * OBJETIVO: Definir la fucin Usr_Edita()
 * AUTOR:    Herbert Schildt, adaptado por Pedro Reina
 * FECHA:    J.20.7.1995
 *------------------------------------------------------------------*/

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

#include "Usuario.h"

#include "string.h"        /* memmove() */

/*--------------------------------------------------------------------
 * Definicin de macros constantes
 *------------------------------------------------------------------*/

#define USR_MAXEDITA   32000
#define USR_MAXLINAUX  120

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

static void MuestraPantallaTexto();
static void BorraHastaFinLinea();
static void MuestraLinea();
static void InsertaEnter();
static void InsertaCar();
static void BorraCaracter();
static void ComienzoLinea();
static void FinalLinea();
static void LineaArriba();
static void LineaAbajo();
static void CaracterIzquierda();
static void CaracterDerecha();
static void PaginaAbajo();
static void PaginaArriba();
static void VeteComienzo();
static void VeteFinal();
static void CopiaLinea();
static void CortaLinea();
static void PegaLinea();

/*--------------------------------------------------------------------
 * Variables globales
 *------------------------------------------------------------------*/

static region    RegTex;                   /* Regin donde se edita    */
static caracter  Aux [USR_MAXEDITA];       /* Contiene el texto        */
static caracter  AuxLin [USR_MAXLINAUX];   /* Portapapeles             */
static caracter *Pos, *Ultimo;             /* Posicin actual y ltima */
static menudo    Fila, Columna;            /* Posicin en pantalla     */

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

/*--------------------------------------------------------------Olimpo
 * FUNCION:  Usr_Edita()
 * OBJETIVO: Implementar un pequeo editor de texto
 * ENTRADAS: Una regin donde realizar la edicin y el
 *           texto inicial
 * SALIDAS:  Una cadena con el texto editado
 * EJEMPLO:  Usr_Edita (RegionTexto,"")
 * NOTAS:    1. La cadena hay que destruirla cuando no
 *              sea necesaria
 *           2. El fin de lnea se marca con un solo carcter,
 *              el '\r'
 *           3. El usuario dispone de varias teclas para editar
 *              el texto que no aparecen en la ayuda de pantalla:
 *                Arriba, abajo, izquierda y derecha: mueven
 *                  el cursor
 *                Suprimir: borra el carcter del cursor
 *                Retroceso: borra el carcter a la izquierda
 *                  del cursor
 *                Inicio: comienzo de lnea
 *                Fin: fin de lnea
 *                RePag: retrasa una pantalla
 *                AvPag: avanza una pantalla
 *                Control-RePag: comienzo de texto
 *                Control-AvPag: fin de texto
 *            4. Las lneas slo se manejan hasta la anchura
 *               de la regin
 * ALGORITMO:
 *     Formar la lista de teclas admitidas
 *     Decir al usuario lo que puede hacer
 *     Hacer modo insertar
 *     Escribir y recordar la situacin del sujeta-maysculas
 *     Poner el cursor
 *     Repetir
 *       Pedir una tecla en el rango admitido con validacin rpida
 *       Si hay tecla, procesarla
 *       Si no hay tecla
 *         Mirar la posicin del sujeta-maysculas
 *         Si es necesario, escribir la nueva situacin
 *------------------------------------------------------------------*/
cadena Usr_Edita (Region, Texto)
region Region;
cadena Texto;
  {
  static TeclaOrden[] = { TEC_ESC, TEC_F2, TEC_INICIO, TEC_FIN,
                          TEC_ARRIBA, TEC_ABAJO, TEC_IZQUIERDA, TEC_DERECHA,
                          TEC_REPAG, TEC_AVPAG, TEC_CTRL_REPAG, TEC_CTRL_AVPAG,
                          TEC_ENTER, TEC_RETROCESO, TEC_SUPRIMIR,
                          TEC_F4, TEC_CTRL_F4, TEC_MAY_F4, NIL };

  tecla    Tecla, ListaTecla[Tec_Max()-Tec_Min()+19];
  contador i, j=0;
  logico   Sigue = SI;

  cadena   Respuesta;
  logico   Insertar, EstadoMayus, NuevoMayus;

  for ( i=0 ; i<=Tec_Max()-Tec_Min() ; i++ )
    { ListaTecla[j++] = (tecla)(Tec_Min()+i); }
  for ( i=0 ; TeclaOrden[i] ; i++ )
    { ListaTecla[j++] = TeclaOrden[i]; }
  ListaTecla[j] = NIL;

  RegTex = Region;

  Usr_Indica ( "Edita el texto. F2: finaliza. ESC: anula",
               "Lnea -> F4: corta. CTRL-F4: copia. MAY-F4: pega." );
  Cdr_Linea (CDR_SIMPLE,USR_MENSAJE,70,USR_MENSAJE+1,70,VERDE,NEGRO);

  Insertar = SI; Usr_IndicaModo(Insertar);
  if ( Tec_FijadoMayus() ) { EstadoMayus = NuevoMayus = SI; }
  else                     { EstadoMayus = NuevoMayus = NO; }
  Usr_IndicaMayus ( EstadoMayus );
  Pan_CursorVisible (SI);

  /* Clculo de valores iniciales. Se comprueba que
     Texto no sea demasiado largo */
  if ( *Texto )
    {
    if ( Cad_Longitud(Texto) < USR_MAXEDITA )
      {
      Cad_Copia (Aux, Texto);
      Pos = Aux;
      Ultimo = Aux + Cad_Longitud(Texto);
      }
    else
      {
      Usr_Avisa ("No se puede editar el texto por ser demasiado largo");
      return ( Cad_Duplica (Texto) );
      }
    }
  else
    {
    Mem_Asigna (Aux, 0, USR_MAXEDITA);
    Pos = Ultimo = Aux;
    }

  Pan_Color  (Reg_DiPapel(RegTex),Reg_DiTinta(RegTex));
  Reg_Limpia (RegTex, Reg_DiPapel(RegTex));
  Columna = Fila = 0;
  MuestraPantallaTexto (0, 0, Pos);
  Reg_Cursor (RegTex, 0, 0);

  while ( Sigue )
    {
#ifdef OLIMPO_PC
    if ( Pan_Modo() == PAN_GRAFICO )
      {
      /* Se escribe el carcter en vdeo inverso */
      Pan_Color  (Reg_DiTinta(RegTex),Reg_DiPapel(RegTex));
      if ( *Pos!='\r' )  { Pan_Caracter (*Pos); }
      else               { Pan_Caracter (' '); }
      Reg_Cursor (RegTex, Fila, Columna);
      Pan_Color  (Reg_DiPapel(RegTex),Reg_DiTinta(RegTex));
      }
#endif
    if ( Tecla = Tec_ValidadaRapido (ListaTecla) )
      {
#ifdef OLIMPO_PC
      if ( Pan_Modo() == PAN_GRAFICO )
        {
        /* Se escribe el carcter en vdeo normal */
        if ( *Pos!='\r' )  { Pan_Caracter (*Pos); }
        else               { Pan_Caracter (' '); }
        Reg_Cursor (RegTex, Fila, Columna);
        }
#endif
      switch ( Tecla )
        {
        case TEC_ESC:         Sigue = NO;
                              Respuesta = Cad_Duplica(Texto);
                              break;
        case TEC_F2:          Sigue = NO;
                              Respuesta = Cad_Duplica(Aux);
                              break;
        case TEC_INICIO:      ComienzoLinea();     break;
        case TEC_FIN:         FinalLinea();        break;
        case TEC_CTRL_REPAG:  VeteComienzo();      break;
        case TEC_CTRL_AVPAG:  VeteFinal();         break;
        case TEC_IZQUIERDA:   CaracterIzquierda(); break;
        case TEC_DERECHA:     CaracterDerecha();   break;
        case TEC_ARRIBA:      LineaArriba();       break;
        case TEC_ABAJO:       LineaAbajo();        break;
        case TEC_REPAG:       PaginaArriba();      break;
        case TEC_AVPAG:       PaginaAbajo();       break;
        case TEC_F4:          CortaLinea();        break;
        case TEC_MAY_F4:      PegaLinea();         break;
        case TEC_CTRL_F4:     CopiaLinea();        break;
        case TEC_ENTER:       InsertaEnter();      break;
        case TEC_SUPRIMIR:    if ( Pos<Ultimo )
                                { BorraCaracter (); }
                              break;
        case TEC_RETROCESO:   if ( Pos!=Aux )
                                {
                                CaracterIzquierda();
                                BorraCaracter();
                                }
                              break;
        default:    InsertaCar((caracter)Tecla);   break;
        } /* Fin switch Tecla */
      if ( Pos<Aux )
        {
        Columna = Fila = 0;
        Pos = Aux;
        }
      Reg_Cursor (RegTex, Fila, Columna);
      } /* Fin if Tecla */
    else
      {
      if ( Tec_FijadoMayus() ) { NuevoMayus = SI; }
      else                     { NuevoMayus = NO; }
      if ( EstadoMayus != NuevoMayus )
        {
        EstadoMayus = NuevoMayus;
        Usr_IndicaMayus ( EstadoMayus );
        Pan_Color  (Reg_DiPapel(RegTex),Reg_DiTinta(RegTex));
        Reg_Cursor (RegTex, Fila, Columna);
        }
      }
    } /* Fin while Sigue */

  Usr_BorraZona (NEGRO);
  return ( Respuesta );
  }

/*--------------------------------------------------------------------
 * FUNCION:  MuestraPantallaTexto()
 * OBJETIVO: Llenar la regin de texto partiendo de la posicin indicada
 * ENTRADAS: Fila, columna y posicin
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void MuestraPantallaTexto (Fil, Col, Posicion)
menudo    Fil, Col;
caracter *Posicion;
  {
  menudo i;
  Reg_Cursor (RegTex, Fil, Col);

  i = Col + Reg_ColIzq(RegTex);
  while ( Fil<Reg_Alto(RegTex) && *Posicion )
    {
    if ( *Posicion == '\r' )
      {
      Fil++;
      i = Reg_ColIzq(RegTex);
      Reg_Cursor (RegTex, Fil, 0);
      }
    else
      {
      if ( i<=Reg_ColDer(RegTex) )  { Pan_Caracter (*Posicion); }
      i++;
      }
    Posicion++;
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  MuestraLinea()
 * OBJETIVO: Mostrar una linea a partir de una posicin
 * ENTRADAS: La posicin
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void MuestraLinea (Posicion)
caracter *Posicion;
  {
  menudo i;

  i = Columna;
  while ( *Posicion!='\r' && *Posicion && i<Reg_Ancho(RegTex) )
    {
    Pan_Caracter (*Posicion);
    Posicion++;
    i++;
    }

  while ( i<Reg_Ancho(RegTex) )
    {
    Pan_Caracter (' ');
    i++;
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  InsertaEnter()
 * OBJETIVO: Insertar un \r en el texto
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void InsertaEnter()
  {
  /* Ver si queda sitio */
  if (Ultimo == Aux + USR_MAXEDITA - 2)  { return; }

  /* Desplazar todo el texto un carcter para hacer sitio para el \r  */
  memmove (Pos + 1, Pos, Ultimo - Pos + 1);

  *Pos = '\r';    /* Colocar el \r en el texto */
  Pos++;

  BorraHastaFinLinea (Fila, Columna);
  Columna = 0;
  Fila++;

  /* Desplazar el texto de la pantalla */
  if ( Fila==Reg_Alto(RegTex) )
    {
    Fila = Reg_Alto(RegTex) - 1;
    Pan_Mueve (PAN_ARRIBA, 1, Reg_FilSup(RegTex), Reg_ColIzq(RegTex),
                              Reg_FilInf(RegTex), Reg_ColDer(RegTex));
    }
  else
    { Pan_Mueve (PAN_ABAJO, 1, Reg_FilSup(RegTex)+Fila, Reg_ColIzq(RegTex),
                               Reg_FilInf(RegTex), Reg_ColDer(RegTex) ); }

  Reg_Cursor (RegTex, Fila, Columna);
  MuestraLinea (Pos);
  Ultimo++;     /* Desplazar el puntero de final de texto */
  }

/*--------------------------------------------------------------------
 * FUNCION:  InsertaCar()
 * OBJETIVO: Insertar carcter en el texto
 * ENTRADAS: El carcter
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void InsertaCar (Car)
caracter Car;
  {
  /* Ver si queda sitio */
  if ( Ultimo == Aux+USR_MAXEDITA-2 )  { return; }

  /* No se puede escribir pasado el final de la lnea */
  if ( Columna == Reg_Ancho(RegTex) )  { return; }

  /* Desplazar los caracteres hasta el final
     para hacer sitio para el nuevo carcter */
  memmove (Pos + 1, Pos, Ultimo - Pos + 1);

  *Pos = Car;              /* Colocar el carcter en el texto     */
  Pan_Caracter (*Pos);     /* Mostrar el caracter en la pantalla  */
  Columna++;               /* Avanzar la columna de la pantalla   */
  Reg_Cursor (RegTex, Fila, Columna);
  MuestraLinea (Pos + 1);  /* Mostrar la lnea                    */
  Pos++;                   /* Avanzar la posicin en el texto     */
  Ultimo++;                /* Avanzar el puntero al fin del texto */
  }

/*--------------------------------------------------------------------
 * FUNCION:  BorraHastaFinLinea()
 * OBJETIVO: Borra desde la posicin especificada hasta el final
 *           de la lnea
 * ENTRADAS: Fila y Columna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void BorraHastaFinLinea (Fil, Col)
menudo Fil, Col;
  {
  caracter *Posicion;

  Posicion = Pos;
  Reg_Cursor (RegTex, Fil, Col);
  for ( ;
        Col < Reg_Ancho(RegTex) && *Posicion != '\r' && *Posicion ;
        Col++, Posicion++ )
    { Pan_Caracter (' '); }
  }

/*--------------------------------------------------------------------
 * FUNCION:  BorraCaracter()
 * OBJETIVO: Borrar el carcter de la posicin actual
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void BorraCaracter()
  {
  Reg_Cursor (RegTex, Fila, Columna);

  if ( *Pos=='\r')
    {
    Pan_Mueve (PAN_ARRIBA, 1,
               Reg_FilSup(RegTex)+Fila+1, Reg_ColIzq(RegTex),
               Reg_FilInf(RegTex), Reg_ColDer(RegTex));
    memmove (Pos, Pos + 1, Ultimo - Pos);
    Ultimo--;
    MuestraPantallaTexto (Fila, Columna, Pos);
    }
  else
    {
    memmove (Pos, Pos + 1, Ultimo - Pos);
    Ultimo--;
    MuestraLinea (Pos);
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  ComienzoLinea()
 * OBJETIVO: Colocarse en el comienzo de la lnea actual
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void ComienzoLinea()
  {
  octeto i;

  while ( Columna )
    {
    Columna--;
    Pos--;
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  FinalLinea()
 * OBJETIVO: Colocarse en el final de la lnea actual
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void FinalLinea()
  {
  while ( *Pos!='\r' && *Pos && Columna<Reg_Ancho(RegTex)-1 )
    {
    Pos++;
    Columna++;
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  CaracterIzquierda()
 * OBJETIVO: Mover la posicin un carcter hacia la izquierda
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void CaracterIzquierda()
  {
  if ( Pos == Aux )
    { return; }        /* No podemos ir a la izquierda */

  Columna--;
  if (Columna < 0)
    {                  /* Estamos al comienzo de una lnea */
    Columna = 0;
    LineaArriba();     /* Subir una lnea */

    /* Buscar el final de la lnea */
    while ( *Pos != '\r' && Columna<Reg_Ancho(RegTex)-1 )
      {
      Pos++;
      Columna++;
      }
    }
  else
    { Pos--; }
  }

/*--------------------------------------------------------------------
 * FUNCION:  CaracterDerecha()
 * OBJETIVO: Mover la posicin un carcter hacia la derecha
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void CaracterDerecha()
  {
  if ( Pos+1 > Ultimo )      /* No podemos ir hacia la derecha */
    { return; }

  Columna++;

  /* Si estamos al final de una lnea, pasar a la siguiente */
  if ( Columna>Reg_Ancho(RegTex)-1 || *Pos=='\r')
    {
    /* Si la lnea es ms larga que la pantalla,
       hay que llegar hasta el final real de la lnea */
    while ( *Pos!='\r' ) { Pos++; }

    Columna = 0;
    Fila++;
    if ( Fila == Reg_Alto(RegTex) )
      {                               /* Al final de la pantalla */
      Fila = Reg_Alto(RegTex) - 1;
      LineaAbajo();                   /* Siguiente lnea */

      /* Moverse al comienzo de la nueva lnea */
      Pos--;
      while ( *Pos != '\r' )
        { Pos--; }
      Pos++;
      Columna = 0;
      }
    else
      { Pos++; }
    }
  else
    { Pos++; }
  }

/*--------------------------------------------------------------------
 * FUNCION:  LineaArriba()
 * OBJETIVO: Moverse una lnea hacia arriba. Si es posible, manteniendo
 *           la columna
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void LineaArriba()
  {
  menudo    i;
  caracter *Posicion;

  if ( Pos==Aux )  { return; }  /* Estamos en el primer carcter del texto */

  Posicion = Pos;

  if ( *Posicion=='\r' )  { Posicion--; }
  /* Si al fin de lnea, nos retrasamos */

  /* Buscamos el comienzo de la lnea actual */
  for ( ; *Posicion!='\r' && Posicion>Aux ; Posicion-- )
    ;

  if ( *Posicion!='\r' )  { return; }
  /* Si estamos en la primera lnea, no podemos subir */

  Pos = Posicion;
  Pos--;            /* Saltar el \r */
  i = Columna;      /* Almacenar el valor de Columna */

  /* Buscamos el comienzo de la siguiente lnea */
  while ( *Pos!='\r' && Pos>=Aux )  { Pos--; }
  Fila--;
  Columna = 0;
  Pos++;

  /* Si estamos en la parte de arriba de la regin,
     debemos mover la regin hacia abajo */
  if ( Fila<0 )
    {
    Pan_Mueve (PAN_ABAJO, 1,
               Reg_FilSup(RegTex), Reg_ColIzq(RegTex),
               Reg_FilInf(RegTex), Reg_ColDer(RegTex) );
    Fila = 0;
    Reg_Cursor (RegTex, 0, 0);
    MuestraLinea (Pos);
    }

  /* Colocar el cursor y la posicin en el texto en
     la misma Columna que antes, si es posible */
  while ( i && *Pos!='\r' )
    {
    Pos++;
    Columna++;
    i--;
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  LineaAbajo()
 * OBJETIVO: Moverse una lnea hacia abajo. Si es posible, manteniendo
 *           la columna
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void LineaAbajo()
  {
  menudo    i;
  caracter *Posicion;

  i = Columna;
  Posicion = Pos;

  /* Avanzar hasta el comienzo de la siguiente lnea */
  while ( *Posicion!='\r' && Posicion<Ultimo )
    { Posicion++; }
  if (Posicion == Ultimo)
    { return; }       /* No podemos bajar ms */

  Posicion++;         /* Pasar el \r */
  Pos = Posicion;
  Fila++;
  Columna = 0;

  /* Si nos hemos ido ms abajo de la ltima fila de la pantalla */
  if (Fila == Reg_Alto(RegTex))
    {
    Fila = Reg_Alto(RegTex) - 1;
    Pan_Mueve (PAN_ARRIBA, 1,
               Reg_FilSup(RegTex), Reg_ColIzq(RegTex),
               Reg_FilInf(RegTex), Reg_ColDer(RegTex));
    Reg_Cursor (RegTex, Fila, Columna);
    MuestraLinea (Pos);
    }

  /* Avanzar hasta el carcter correspondiente de la lnea */
  while ( i && *Pos!='\r' && Pos<Ultimo )
    {
    Pos++;
    Columna++;
    i--;
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  PaginaAbajo()
 * OBJETIVO: Desplazar la posicin una pantalla hacia abajo
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void PaginaAbajo()
  {
  menudo i;

  Reg_Limpia (RegTex, Reg_DiPapel(RegTex));

  for ( i=0 ; i<Reg_Alto(RegTex) && Pos<Ultimo ; )
    {
    if ( *Pos == '\r' )  { i++; }
    Pos++;
    }
  Columna = Fila = 0;
  MuestraPantallaTexto (0, 0, Pos);
  }

/*--------------------------------------------------------------------
 * FUNCION:  PaginaArriba()
 * OBJETIVO: Desplazar la posicin una pantalla hacia arriba
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void PaginaArriba()
  {
  menudo i;

  Reg_Limpia (RegTex, Reg_DiPapel(RegTex));

  /* Si estamos en un \r, nos retrasamos un carcter */
  if ( *Pos=='\r' && Pos>Aux )  { Pos--; }

  /* Nos movemos hacia arriba */
  for ( i=0 ; i<Reg_Alto(RegTex)+1 && Pos>Aux ; )
    {
    if ( *Pos == '\r' )  { i++; }
    Pos--;
    }

  /* Si no estamos en la lnea superior, incrementamos
     la posicin para pasar el \r */
  if ( i == Reg_Alto(RegTex)+1 )  { Pos += 2; }

  Columna = Fila = 0;
  MuestraPantallaTexto (0, 0, Pos);
  }

/*--------------------------------------------------------------------
 * FUNCION:  VeteComienzo
 * OBJETIVO: Colocar la posicin en el comienzo del texto
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void VeteComienzo()
  {
  Reg_Limpia (RegTex, Reg_DiPapel(RegTex));
  Pos = Aux;
  Columna = Fila = 0;
  MuestraPantallaTexto (0, 0, Pos);
  }

/*--------------------------------------------------------------------
 * FUNCION:  VeteFinal
 * OBJETIVO: Colocar la posicin en el final del texto
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void VeteFinal()
  {
  Reg_Limpia (RegTex, Reg_DiPapel(RegTex));
  Pos = Ultimo;
  PaginaArriba();
  }

/*--------------------------------------------------------------------
 * FUNCION:  CortaLinea()
 * OBJETIVO: Eliminar una lnea y guardarla sin el '\r'
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void CortaLinea()
  {
  contador  i;
  caracter *Posicion, *PosLinAux;

  ComienzoLinea();
  BorraHastaFinLinea (Fila, Columna);  /* Borrar hasta \r */

  /* Averiguar cuntos caracteres hay en la lnea */
  Posicion = Pos;
  i = 0;
  PosLinAux = AuxLin;
  while ( *Posicion!='\r' && Posicion<Ultimo )
    {
    i++;
    *PosLinAux = *Posicion;       /* Almacenar el carcter */
    Posicion++;
    if ( PosLinAux < AuxLin + USR_MAXLINAUX - 2 )  { PosLinAux++; }
    }
  *PosLinAux = NULO;
  if ( *Posicion=='\r' )  { i++; }

  /* Eliminar la lnea */
  memmove (Pos, Pos+i, Ultimo-Pos);
  Ultimo -= i;

  /* Subir el resto de la pantalla */
  Pan_Mueve (PAN_ARRIBA, 1,
             Reg_FilSup(RegTex)+Fila, Reg_ColIzq(RegTex),
             Reg_FilInf(RegTex), Reg_ColDer(RegTex));
  MuestraPantallaTexto (Fila, Columna, Pos);
  }

/*--------------------------------------------------------------------
 * FUNCION:  CopiaLinea()
 * OBJETIVO: Guardar una lnea sin '\r'
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void CopiaLinea()
  {
  caracter *Posicion, *PosLinAux;
  menudo    Col;

  /* Guardar el valor de la columna */
  Col = Columna;

  ComienzoLinea();

  Posicion = Pos;
  PosLinAux = AuxLin;
  while ( *Posicion!='\r' && Posicion<Ultimo )
    {
    *PosLinAux = *Posicion;       /* Almacenar el carcter */
    Posicion++;
    if ( PosLinAux < AuxLin + USR_MAXLINAUX - 2 )  { PosLinAux++; }
    }
  *PosLinAux = NULO;

  /* Volver a colocar la posicin como al principio */
  while ( Col )
    {
    Col--;
    Pos++;
    Columna++;
    }
  }

/*--------------------------------------------------------------------
 * FUNCION:  PegaLinea()
 * OBJETIVO: Devolver al texto una lnea previamente eliminada, quiz
 *           en otro sitio
 * ENTRADAS: Ninguna
 * SALIDAS:  Ninguna
 *------------------------------------------------------------------*/
static void PegaLinea()
  {
  char *Posicion;

  ComienzoLinea();
  /* Bajar el resto de la pantalla */
  Pan_Mueve (PAN_ABAJO, 1,
             Reg_FilSup(RegTex)+Fila, Reg_ColIzq(RegTex),
             Reg_FilInf(RegTex), Reg_ColDer(RegTex));
  Reg_Cursor (RegTex, Fila, Columna);

  Posicion = AuxLin;
  while ( *Posicion )
    {
    memmove (Pos + 1, Pos, Ultimo - Pos + 1);
    *Pos = *Posicion;             /* Poner carcter en el texto */
    if ( Columna<Reg_Ancho(RegTex) )
      {
      Pan_Caracter (*Pos);      /* Mostrar el carcter en la pantalla */
      }
    Columna++;
    Pos++;
    Ultimo++;
    Posicion++;
    }

  /* Aadir el '\r' */
  memmove (Pos + 1, Pos, Ultimo - Pos + 1);
  *Pos = '\r';
  Ultimo++;

  MuestraLinea (Pos);
  ComienzoLinea();
  }
