// articulos.cpp - Definición de la clase CArticulos
#include <iostream>
#include <string>
#include "registro.h"  // clase CRegistro
#include "articulos.h" // clase CArticulos
#include "leerdatos.h"
using namespace std;

/////////////////////////////////////////////////////////////////
// Constructor
CArticulos::CArticulos()
{
  modo = 0;
}

CArticulos::~CArticulos()
{
  if (is_open()) close();
}

void CArticulos::Nuevo(string& nomf)
{
  // Habilitar las excepciones del tipo failure
  clear(); // desactivar los indicadores que haya activos
  exceptions(ios::failbit | ios::badbit);
  // Crear un nuevo fichero
  if (nomf.empty())
    throw failure(string("Especificar un nombre para el fichero"));

  if (is_open()) close(); // cerrar el fichero si está abierto
  modo = 0;
  // Comprobar si el fichero existe
  if (Existe(nomf))
  {
    cout << "El fichero " << nomf << " existe. "
         << "¿Desea sobrescribirlo? (s/n): ";
    string resp("n");
    leerDato(resp);
    if (resp == "s")
    {
      // Eliminar todos sus registros
      open(nomf.c_str(), ios::out | ios::trunc);
      close();
    }
  }
  // Abrir el fichero para añadir registros
  open(nomf.c_str(), ios::out | ios::app | ios::binary);
  modo = 2; // añadir
}

void CArticulos::Abrir(string& nomf)
{
  // Habilitar las excepciones del tipo failure
  clear(); // desactivar los indicadores que haya activos
  exceptions(ios::failbit | ios::badbit);
  // Abrir un fichero
  if (nomf.empty())
    throw failure(string("Especificar un nombre para el fichero"));

  if (is_open()) close(); // cerrar el fichero si está abierto
  modo = 0;
  // Opciones del menú
  static char *opciones[] = 
  { 
    "leer",
    "añadir",
  };
  int op, nOpciones = sizeof(opciones)/sizeof(char*);

  if ((op = menu(opciones, nOpciones)) == 1) // leer
    open(nomf.c_str(), ios::in | ios::binary);
  else // añadir
    open(nomf.c_str(), ios::out | ios::app | ios::binary);
  modo = op;
}

void CArticulos::Agregar()
{   
  // Habilitar las excepciones del tipo failure
  clear(); // desactivar los indicadores que haya activos
  exceptions(ios::failbit | ios::badbit);
  // Escribir registros en un fichero
  if (modo != 2)
    throw failure(string("Abrir el fichero para añadir"));

  CRegistro reg;
  int tm = sizeof(reg);
  char ref[30];
  float pre;
   
  cout << "\nIntroducir datos. Para finalizar, "
       << "responder \"fin\" a Referencia:.\n\n";
  while(true)
  {
    cout << "Referencia: "; leerDato(ref);
    if (!strcmp(ref, "fin")) break;
    cout << "Precio:     "; leerDato(pre);
     
    reg.AsignarRegistro(ref, pre);
    write(reinterpret_cast<char *>(&reg), tm);
  }
}

float CArticulos::Buscar(string& str)
{
  // Deshabilitar las excepciones del tipo failure
  exceptions(ios::goodbit);
  // Buscar un registro en el fichero
  if (modo != 1)
  {
    cout << "Abrir el fichero para leer\n";
    return -1;
  }
  CRegistro reg;
  seekg(0, ios::beg); // situarse al principio
  
  int tm = sizeof(reg);
  char ref[30];
  // Buscar un artículo y devolver el precio
  string refe;
  if (str.empty()) return false;
  while (read(reinterpret_cast<char *>(&reg), tm))
  {
    // Buscar por la referencia
    refe = string(reg.ObtenerReferencia(ref));
    if (refe.empty()) continue;
    // ¿str es la referencia?
    if (str == refe)
      return reg.ObtenerPrecio();
  }
  clear(); // desactivar eofbit y failbit
  return -1;
}

bool CArticulos::Existe(string& nombf)
{
  // Deshabilitar las excepciones del tipo failure
  exceptions(ios::goodbit);
  // Intentar abrir el fichero para leer
  open(nombf.c_str(), ios::in);
  if (fail())
  {
    clear();
    return false;
  }
  close();
  return true;
}
/////////////////////////////////////////////////////////////////
