// libros.cpp - Clases abstractas y funciones virtuales puras

#include <iostream>
#include "fichalibro.h"   // clase CFichaLibro
#include "fichavolumen.h" // clase CFichaVolumen
#include "ficharevista.h" // clase CFichaRevista
#include "biblioteca.h"   // clase CBiblioteca
using namespace std;

int leerDato()
{
  int dato = 0;
  cin >> dato;
  while (cin.fail()) // si el dato es incorrecto, limpiar el
  {                  // búfer y volverlo a leer
    cout << '\a';
    cin.clear();
    cin.ignore(numeric_limits<int>::max(), '\n');
    cin >> dato;
  }
  // Eliminar posibles caracteres sobrantes
  cin.ignore(numeric_limits<int>::max(), '\n');
  return dato;
}

CFicha *leerDatos(int op)
{
  CFicha *obj;
  string refe, titulo;
  cout << "Referencia.............: ";
  getline(cin, refe);
  cout << "Título.................: ";
  getline(cin, titulo);
  if (op == 1)
  {
    int nrorev, anyo;
    cout << "Nro. de la revista.....: ";
    nrorev = leerDato();
    cout << "Año de publicación.....: ";
    anyo = leerDato();
    obj = new CFichaRevista(refe, titulo, nrorev, anyo);
  }
  else
  {
    string autor, editorial;
    cout << "Autor..................: ";
    getline(cin, autor);
    cout << "Editorial..............: ";
    getline(cin, editorial);

    if (op == 2)
      obj = new CFichaLibro(refe, titulo, autor, editorial);
    else
    {
      int nrovol;
      cout << "Nro. del volumen.......: ";
      nrovol = leerDato();
      obj = new CFichaVolumen(refe,titulo,autor,editorial,nrovol);
    }
  }
  return obj;
}

int menu()
{
  cout << "\n\n";
  cout << "1.  Añadir ficha\n";
  cout << "2.  Buscar ficha\n";
  cout << "3.  Buscar siguiente\n";
  cout << "4.  Eliminar ficha\n";
  cout << "5.  Listado de la biblioteca\n";
  cout << "6.  Copia de seguridad\n";
  cout << "7.  Restaurar copia de seguridad\n";
  cout << "8.  Salir\n";    
  cout << endl;
  cout << "   Opción: ";
  int op;
  do
    op = (int)leerDato();
  while (op < 1 || op > 8);
  return op;
}

int main()
{
  // Crear un objeto con cero elementos
  CBiblioteca bibli;
  CBiblioteca *copiabibli = 0; // para la copia de seguridad
  CFicha *unaFicha = 0;

  int opcion = 0, pos = -1;
  string cadenabuscar;
  string refe;
  double cantidad;
  bool eliminado = false;

  do
  {
    opcion = menu();
    switch (opcion)
    {
      case 1: // añadir
        cout << "Tipo de ficha < 1-(rev), 2-(lib), 3-(vol) >: ";
        do
          opcion = (int)leerDato();
        while (opcion < 1 || opcion > 3);
        unaFicha = leerDatos(opcion);
        bibli.AnyadirFicha(unaFicha);
        delete unaFicha;
        break;
      case 2: // buscar
        cout << "Título total o parcial, o referencia: ";
        getline(cin, cadenabuscar);
        pos = bibli.buscar(cadenabuscar, 0);
        if (pos == -1)
          if (bibli.longitud() != 0)
            cout << "búsqueda fallida\n";
          else
            cout << "no hay fichas\n";
        else
          cout << bibli[pos] << endl;
        break;
      case 3: // buscar siguiente
        pos = bibli.buscar(cadenabuscar, pos + 1);
        if (pos == -1)
          if (bibli.longitud() != 0)
            cout << "búsqueda fallida\n";
          else
            cout << "no hay fichas\n";
        else
          cout << bibli[pos] << endl;
        break;
      case 4: // eliminar ficha
        cout << "Referencia: "; getline(cin, refe);
        eliminado = bibli.eliminar(refe);
        if (eliminado)
          cout << "registro eliminado\n";
        else
          if (bibli.longitud() != 0)
            cout << "referencia no encontrada\n";
          else
            cout << "no hay fichas\n";
        break;
      case 5: // listado de la biblioteca
        bibli.VisualizarFichas();
        break;
      case 6: // copia de seguridad
        if (bibli.longitud() == 0)
          cout << "no hay fichas\n";
        else
        {
          if (!copiabibli)
          {
            copiabibli= new CBiblioteca(bibli);
            if (copiabibli) cout << "copia realizada con éxito\n";
          }
          else
            cout << "existe una copia, restaurarla\n";
        }
        break;
      case 7: // restaurar copia de seguridad
        if (copiabibli)
        {
          bibli = *copiabibli;
          cout << "copia de seguridad restaurada\n";
          delete copiabibli;
          copiabibli = 0;
        }
        else
          cout << "no hay copia de seguridad\n";
        break;
      case 8: // salir
        if (copiabibli) delete copiabibli;
        break;
    }
  }
  while(opcion != 8);
}

