/*--------------------------------------------------------------------
 * FICHERO:  IndBusca.c
 * OBJETIVO: Definir la funcin Ind_Busca()
 * AUTOR:    Pedro Reina
 * FECHA:    D.27.8.1995
 *------------------------------------------------------------------*/

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

#include "Indice.h"

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

/*--------------------------------------------------------------Olimpo
 * FUNCION:  Ind_Busca()
 * OBJETIVO: Dar el mayor ndice que sea menor o igual que
 *           una clave dada
 * ENTRADAS: El ndice, una variable en la que dejar el nmero
 *           de registro del ndice encontrado, una cadena
 *           donde dejar la clave y que contiene la clave de
 *           referencia y la funcin que se usar para comparar
 *           claves (debe recibir dos cadenas y devolver un
 *           contador).
 * 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
 * EJEMPLO:  Ind_Busca ( Agenda, &NumeroRegistro, Clave,
 *                       FuncionComparacion )
 *------------------------------------------------------------------*/
logico Ind_Busca (Indice, Registro, Clave, Compara)
indice   Indice;
entero  *Registro;
cadena   Clave;
contador Compara();
  {
  logico   Respuesta, Error, SigueBuscando;
  entero   NuevaPagina;
  caracter ClaveReferencia[IND_MAXCLAVE+1];
  contador Comparacion;

  Ind_AlmacenaClave (Indice, ClaveReferencia, Clave);

  Ind_PonNivel (Indice, IND_FUERA);
  NuevaPagina = Ind_DirPosicion(Indice)[0];
  Error = !Ind_IncrementaNivel (Indice, NuevaPagina);

  if ( Error || !Ind_MaxItem (Indice) )
    {
Son_Cambia(); Son_Cambia(); /* Arregla un extrao error en el QL */
    Respuesta = NO;
    Error = SI;
    }

  else
    {
    SigueBuscando = SI;
    while ( NuevaPagina && SigueBuscando && !Error )
      {
      Ind_PonItem (Indice,0);
      do
        {
        Ind_Clave (Indice,Ind_Item(Indice),Clave);
        Comparacion = Compara (ClaveReferencia, Clave);

        if ( Comparacion == 0 )
          { SigueBuscando = NO; }

        else if ( Comparacion > 0 )
          {
          if ( Ind_Item(Indice)+1 >= Ind_MaxItem(Indice) )
            {
            if ( NuevaPagina = Ind_PaginaApuntada (Indice,
                               Ind_MaxItem(Indice)) )
              {
              Ind_IncrementaItem (Indice);
              Ind_IncrementaNivel (Indice, NuevaPagina);
              Comparacion = 0;
              }
            else
              {
              do
                {
                if ( SigueBuscando = Ind_Siguiente (Indice, Registro, Clave) )
                  { Comparacion = Compara (ClaveReferencia, Clave); }
                } while ( Comparacion >= 0 && SigueBuscando );

              if ( !SigueBuscando )
                { Ind_Ultimo (Indice, Registro, Clave); }
              else
                {
                Ind_Anterior (Indice, Registro, Clave);
                SigueBuscando = NO;
                }
              }
            }
          else
            { Ind_IncrementaItem (Indice); }
          }

        else  /* Comparacion < 0 */
          {
          if ( NuevaPagina = Ind_PaginaApuntada (Indice,Ind_Item(Indice)) )
            {
            Ind_IncrementaNivel (Indice, NuevaPagina);
            Ind_IncrementaItem (Indice);
            Comparacion = 0;
            }
          else
            {
            SigueBuscando = NO;
            Error = !Ind_Anterior(Indice, Registro, Clave);
            }
          }

        } while ( Comparacion && SigueBuscando && !Error );
      }  /* Fin while NuevaPagina && SigueBuscando && !Error */
    }

  if ( !Error )
    {
    *Registro = Ind_Registro (Indice,Ind_Item(Indice));
    Ind_Clave (Indice,Ind_Item(Indice),Clave);
    Respuesta = SI;
    }
  else { Respuesta = NO; }

  return ( Respuesta );
  }
