/*--------------------------------------------------------------------
 * FICHERO:  IndAnter.c
 * OBJETIVO: Definir la funcin Ind_Anterior()
 * AUTOR:    Pedro Reina
 * FECHA:    J.13.7.1995
 *------------------------------------------------------------------*/

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

#include "Indice.h"

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

/*--------------------------------------------------------------Olimpo
 * FUNCION:  Ind_Anterior()
 * OBJETIVO: Dar el anterior ndice de un fichero de ndices
 * ENTRADAS: El ndice, una variable en la que dejar el nmero
 *           de registro del ndice encontrado y una cadena
 *           donde dejar la clave
 * SALIDAS:  Lgica, que indica si se ha podido encontrar;
 *           la variable y la cadena quedan modificadas
 * NOTAS:    1. Los registros se numeran a partir de 0
 *           2. La cadena debe ser suficientemente larga como
 *              para recibir la clave, sin olvidar el espacio
 *              para el NULO
 *           3. Si se llama a esta funcin inmediatamente
 *              despus de abrir el ndice, se devuelve
 *              Ind_Ultimo()
 * EJEMPLO:  Ind_Anterior ( Agenda, &NumeroRegistro, Clave )
 * ALGORITMO:
 *      Si estamos fuera del rbol, devolver Ind_Ultimo()
 *      Ver a qu pgina apunta el item
 *      Si apunta a otra pgina
 *        Repetir
 *          Incrementar el nivel bajando a la pgina calculada
 *          Poner el item a MaxItem
 *          Ver la pgina a la que apunta
 *        Mientras exista la pgina
 *        Decrementar el item
 *      Si apunta a la pgina actual (es decir, pgina 0)
 *        Si el item es positivo, decrementarlo
 *        Si no
 *          Hecho es NO
 *          Repetir
 *            Decrementar el nivel. Si no se puede, devolver NO
 *            Decrementar item
 *            Si el nmero de item es mayor o igual a 0, Hecho es SI
 *          Mientras Hecho sea NO
 *      Dar el nmero y la clave del item
 *------------------------------------------------------------------*/
logico Ind_Anterior (Indice, Registro, Clave)
indice  Indice;
entero *Registro;
cadena  Clave;
  {
  logico Respuesta, Hecho, Error;
  entero NuevaPagina;
  
  if ( Ind_Nivel(Indice) == IND_FUERA ) 
    { return ( Ind_Ultimo (Indice, Registro, Clave) ); }
  
  Error = NO;
  
  if ( NuevaPagina = Ind_PaginaApuntada (Indice, Ind_Item(Indice)) )
    {
    do
      {
      Error = ! (Ind_IncrementaNivel (Indice, NuevaPagina));
      Ind_PonItem (Indice,Ind_MaxItem(Indice));
      NuevaPagina = Ind_PaginaApuntada (Indice,Ind_MaxItem(Indice));
      } while ( NuevaPagina && !Error );
    Ind_DecrementaItem (Indice);  
    }
    
  else
    {
    if ( Ind_Item (Indice) ) { Ind_DecrementaItem (Indice); }
    else
      {
      Hecho = NO;
      do 
        {
        Error = ! (Ind_DecrementaNivel (Indice));
        Ind_DecrementaItem (Indice); 
        Hecho = ( Ind_Item (Indice) >= 0 );
        } while ( !Hecho && !Error );
      }
    }  
  
  if ( ! Error )
    {  
    *Registro = Ind_Registro (Indice,Ind_Item(Indice));
    Ind_Clave (Indice,Ind_Item(Indice),Clave);
    Respuesta = SI;
    }
  else { Respuesta = NO; }  
  
  return ( Respuesta );
  }