// alumno.cpp - Definición de los métodos de la clase CAlumno
#include <iostream>
#include "alumno.h"
using namespace std;

CAlumno::CAlumno(long dni, string nom, string dir):
DNI(dni), nombre(nom), direccion(dir)
{
  asignarDNI(dni);
  asignatura.reserve(10); // espacio para 10 objetos CAsignatura
}

CAlumno::~CAlumno()
{
  for (unsigned int i = 0; i < numeroAsignaturas(); i++)
    delete asignatura[i];
}

CAlumno::CAlumno(const CAlumno& x)
{
  *this = x;
}

CAlumno& CAlumno::operator=(const CAlumno& x)
{
  // Eliminar las asignaturas del objeto CAlumno destino (*this)
  if (asignatura.size())
  {
    for (unsigned int i = 0; i < asignatura.size(); i++)
      delete asignatura[i];
    // Eliminar todos los elementos de la matriz asignatura
    asignatura.clear();
  }

  // Copiar el alumno origen, x, en el alumno destino
  DNI = x.DNI;
  nombre = x.nombre;
  direccion = x.direccion;
  for (unsigned int i = 0; i < x.asignatura.size(); i++)
    asignatura.push_back(new CAsignatura(*(x.asignatura[i])));

  return *this;
}

void CAlumno::asignarDNI(long dni)
{
  if (dni < 0)
  {
    cerr << "error: DNI no válido\n";
    dni = 0;
  }
  DNI = dni;
}

long CAlumno::obtenerDNI() const
{
  return DNI;
}

void CAlumno::asignarNombre(string& nom)
{
  nombre = nom;
}

string CAlumno::obtenerNombre() const
{
  return nombre;
}

void CAlumno::asignarDireccion(string& dir)
{
  direccion = dir;
}

string CAlumno::obtenerDireccion() const
{
  return direccion;
}

CAsignatura *CAlumno::obtenerAsignatura(unsigned int i)
{
  if (numeroAsignaturas() == 0) return 0;
  if (i >= 0 && i < numeroAsignaturas())
    return asignatura[i];
  else
  {
    cerr << "error: índice fuera de límites\n";
    return 0;
  }
}

void CAlumno::anyadirAsignatura(CAsignatura *asig)
{
  asignatura.push_back(new CAsignatura(*asig));
}

bool CAlumno::estaEnActa(int id, int& i)
{
  // En i se devuelve la posición de la asignatura id en la lista
  if (numeroAsignaturas() == 0) return false;
  // Un alumno pertenece al acta de la asignatura id si se ha
  // matriculado, aún no ha aprobado y no excede el número
  // de convocatorias.
  for (i = 0; i < numeroAsignaturas(); i++)
  {
    CAsignatura *asig = obtenerAsignatura(i);
    if (asig->obtenerID() != id) continue;
    int nconv = asig->convocatoriasConsumidas();
    if (nconv > 0)
      if (asig->obtenerConvocatoria(nconv).obtenerNota() >= 5)
        return false;
    if (nconv == 6)
    {
      cerr << "error: convocatorias agotadas\n";
      break;
    }
    return true; // está en el acta.
  }
  return false;  // no está en el acta.
}

size_t CAlumno::numeroAsignaturas() const
{
  return asignatura.size();
}

