#include <iostream>
#include <string>
using namespace std;

/* Clase de objetos CCuenta.
 *   Atributos:
 *     nombre, cuenta, saldo y tipo de interés
 *   Métodos:
 *     asignar/obtener nombre
 *     asignar/obtener cuenta
 *     estado de la cuenta (saldo)
 *     ingreso
 *     reintegro
 *     asignar/obtener tipo de interés
 */
class CCuenta
{
  // Atributos
  private:
    string nombre;
    string cuenta;
    double saldo;
    double tipoDeInteres;
  
  // Métodos
  public:
    CCuenta()
    {
      saldo = 0.0;
      tipoDeInteres = 0.0;
    }

    CCuenta(string nom, string cue, double sal, double tipo)
    {
      asignarNombre(nom);
      asignarCuenta(cue);
      saldo = sal;
      tipoDeInteres = tipo;
    }

    void asignarNombre(string nom)
    {
      if (nom.length() == 0)
      {
        cout << "Error: cadena vacía\n";
        return;
      }
      nombre = nom;
    }
    
    string obtenerNombre()
    {
      return nombre;
    }
    
    void asignarCuenta(string cue)
    {
      if (cue.length() == 0)
      {
        cout << "Error: cuenta no válida\n";
        return;
      }
      cuenta = cue;
    }
    
    string obtenerCuenta()
    {
      return cuenta;
    }
    
    double estado()
    {
      return saldo;
    }
    
    void ingreso(double cantidad)
    {
      if (cantidad < 0)
      {
        cout << "Error: cantidad negativa\n";
        return;
      }
      saldo = saldo + cantidad;
    }
    
    void reintegro(double cantidad)
    {
      if (saldo - cantidad < 0)
      {
        cout << "Error: no dispone de saldo\n";
        return;
      }
      saldo = saldo - cantidad;
    }

    void asignarTipoDeInteres(double tipo)
    {
      if (tipo < 0)
      {
        cout << "Error: tipo no válido\n";
        return;
      }
      tipoDeInteres = tipo;
    }
    
    double obtenerTipoDeInteres()
    {
      return tipoDeInteres;
    }
};

/* Clase de objetos CCuentaAhorro.
 */
class CCuentaAhorro : public CCuenta
{
  // Atributos
  private:
    double cuotaMantenimiento;
  // Métodos
  public:
    CCuentaAhorro() {} // constructor sin parámetros

    CCuentaAhorro(string nom, string cue, double sal,
      double tipo, double mant) :
      CCuenta(nom, cue, sal, tipo)// invoca al constructor CCuenta,
    {                             // esto es, al de la clase base
      asignarCuotaManten(mant);   // inicia cuotaMantenimiento
    }

    void asignarCuotaManten(double cantidad)
    {
      if (cantidad < 0)
      {
        cout << "Error: cantidad negativa\n";
        return;
      }
      cuotaMantenimiento = cantidad;
    }
  
    double obtenerCuotaManten()
    {
      return cuotaMantenimiento;
    }
    
    void reintegro(double cantidad)
    {
      double saldo = estado();
      double tipoDeInteres = obtenerTipoDeInteres();

      if ( tipoDeInteres >= 3.5)
      {
        if (saldo - cantidad < 1500)
        {
          cout << "Error: no dispone de esa cantidad\n";
          return;
        }
      }
      // Invocar al método reintegro de la clase base,
      // también llamada superclase    
      CCuenta::reintegro(cantidad); 
    }
}; 

/* Función main:
 *   Punto de entrada y de salida al programa.
 *   Crea una cuenta, cuenta01, y realiza
 *   operaciones sobre ella.
 */
int main()
{
  CCuenta cuenta01;
  CCuentaAhorro cuenta02("Un nombre", "Una cuenta", 6000, 3.5, 2);

  cuenta01.asignarNombre("Un nombre");
  cuenta01.asignarCuenta("Una cuenta");
  cuenta01.asignarTipoDeInteres(2.5);
  cuenta01.ingreso(12000);
  cuenta01.reintegro(3000);

  cout << cuenta01.obtenerNombre() << endl;
  cout << cuenta01.obtenerCuenta() << endl;
  cout << cuenta01.estado() << endl;
  cout << cuenta01.obtenerTipoDeInteres() << endl;
  cout << endl;

  // Cobrar cuota de mantenimiento
  cuenta02.reintegro(cuenta02.obtenerCuotaManten());
  // Ingreso
  cuenta02.ingreso(6000);
  // Reintegro
  cuenta02.reintegro(10000);

  cout << cuenta02.obtenerNombre() << endl;
  cout << cuenta02.obtenerCuenta() << endl;
  cout << cuenta02.estado() << endl;
  cout << cuenta02.obtenerTipoDeInteres() << endl;
}

