#include <iostream>  // cout, endl
#include <cstring>   // strlen, strcpy
#include "Student.h" // [Student] class

#define EFFICIENTx

#ifdef EFFICIENT
Student::Student(const char * login, int age, int year, float GPA) : login_(login)
{
  set_age(age);
  set_year(year);
  set_GPA(GPA);
  std::cout << "[Student] constructor for " << login_ << std::endl;
}
#else
Student::Student(const char * login, int age, int year, float GPA)
{
  set_login(login);
  set_age(age);
  set_year(year);
  set_GPA(GPA);
  std::cout << "[Student] constructor for " << login_ << std::endl;
}
#endif

#ifdef USER_DEFINED
    // Explicit copy constructor
    Student::Student(const Student& student)
    {
      copy_data(student);
      std::cout << "[Student] copy constructor for " << login_ << std::endl;
    }

    // Explicit assignment operator
    Student& Student::operator=(const Student& rhs)
    {
        // Check for self-assignment
      if (&rhs != this)
      {
        copy_data(rhs);
        std::cout << "[Student] operator= for " << login_ << std::endl;
      }
      return *this;
    }

    Student::~Student(void)
    {
      std::cout << "[Student] destructor for " << login_ << std::endl;
    }
#endif


void Student::copy_data(const Student& rhs)
{
  login_ = rhs.login_;
  set_age(rhs.age_);
  set_year(rhs.year_);
  set_GPA(rhs.GPA_);
}

void Student::set_login(const String& login)
{
  login_ = login;
}

void Student::set_login(const char* login)
{
  login_ = login;
}

void Student::set_age(int age)
{
  if ( (age < 18) || (age > 100) )
  {
    std::cout << "Error in age range!\n";
    age_ = 18;
  }
  else
    age_ = age;
}

void Student::set_year(int year)
{
  if ( (year < 1) || (year > 4) )
  {
    std::cout << "Error in year range!\n";
    year_ = 1;
  }
  else
    year_ = year;
}

void Student::set_GPA(float GPA)
{
  if ( (GPA < 0.0) || (GPA > 4.0) )
  {
    std::cout << "Error in GPA range!\n";
    GPA_ = 0.0;
  }
  else
    GPA_ = GPA;
}

void Student::display(void) const
{
  using std::cout;
  using std::endl;

  cout << "login: " << login_ << endl;
  cout << "  age: " << age_ << endl;
  cout << " year: " << year_ << endl;
  cout << "  GPA: " << GPA_ << endl;

}

int Student::get_age(void) const
{
  return age_;
}

int Student::get_year(void) const
{
  return year_;
}

float Student::get_GPA(void) const
{
  return GPA_;
}

const char *Student::get_login(void) const
{
  return login_.c_str();
}