/*
    class is a bag of data with methods to set and get and process the data.
*/

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


class Employee
{
private:  // Internal data are now private. Not accessible as in struct.

    string name;
    string department;
    int age;
    double salary,tax;

public:

    // In a class, we declare methods that deals with class variables INSIDE the class.
    // The user uses these methods to interact with the class.

    // Constructs an employee
    Employee(string _name, string _department, int _age, double _salary, double _tax)
    {
        name=_name;
        department=_department;
        age=_age;
        salary=_salary;
        tax=_tax;
        
        // Here we could generate errors if any of the input values are wrong.
    }

    // Destroys an employee
    ~Employee()
    {
        // This does nothing.
    }

    // The following are Get'ters and Set'ters:

    void SetName(const string& s)
    {
        name=s;
    }

    string GetName()
    {
        return name;
    }

    void SetDepartment(const string& s)
    {
        department=s;
    }

    string GetDepartment()
    {
        return department;
    }

    void SetAge(int a)
    { 
        // here we should check if a is a valid age
        age=a;
    }

    int GetAge()
    {
        return age;
    }

    void SetSalary(double s)
    {
        salary=s;
    }

    double GetSalary()
    {
        return salary;
    }

    void SetTax(double x)
    {
        // Here we should check if tax rate is valid.
        tax=x;
    }

    double GetTax()
    {
        return tax;
    }

    // Implement business logic here:

    double SalaryAfterTax()
    {
        return salary*(1-tax);
    }

    bool shouldfire()
    {
        return (age>65);
    }

    bool FKFemployee()
    {
        return (department == "FKF");
    }

};

// Teach ostream operator<<  how to handle an employee
ostream& operator<<(ostream& os, Employee& e)
{
    os << "name="       << e.GetName()       << endl;
    os << "department=" << e.GetDepartment() << endl;
    os << "age="        << e.GetAge()        << endl;
    os << "salary="     << e.GetSalary()     << endl;
    os << "tax="        << e.GetTax()        << endl;

    return os;
}


int main()
{
    Employee Emma("Emma Thompson", "FKF", 42, 25000.0, 0.42);
    Employee Mogens("Mogens Glistrup", "BMB", 58, 15000.0, 0.33);

    cout << "Emma: ----------------" << endl;
    cout << Emma << endl;

    cout << "Mogens: --------------" << endl;
    cout << Mogens << endl;

    cout << "Tax data: ------------" << endl;

    cout << Emma.GetName() << " after tax salary" << Emma.SalaryAfterTax() << endl;
    cout << Mogens.GetName() << " after tax salary" << Mogens.SalaryAfterTax() << endl;

    // Changing data in class via Set'ter
    Mogens.SetName("Morten Messerschmidt");
    Mogens.SetTax(0.55);

    cout << "Mogens: --------------" << endl;
    cout << Mogens << endl;

    // We can even copy Employees. (c++ generates operator= for us).
    Emma=Mogens;
    cout << "Emma: ----------------" << endl;
    cout << Emma << endl;
}

