#include "person.h"

#include <iostream>
#include <cstring>
#include "input.h"

using namespace std;

Person::Person(void) :
    name(nullptr),            // empty name
    SSN(-1),               // known invalid SSN
    height(-1.0)          // known invalid height
{}

Person::Person(const char Name[], long sSN, double Height) :
    name(nullptr),            // empty name
    SSN(-1),               // known invalid SSN
    height(-1.0)          // known invalid height
{
    set_name(Name);         // protect our data
    set_SSN(sSN);           // from programmer
    set_height(Height);     // stupidity
}

Person::Person(const Person & p) :
    name(nullptr),            // empty name
    SSN(-1),               // known invalid SSN
    height(-1.0)          // known invalid height
{
    set_name(p.name);
    set_SSN(p.SSN);
    set_height(p.height);
}

Person::~Person(void)
{
    delete [] name;
    name = nullptr;            // empty name
    SSN = -1;               // known invalid SSN
    height = -1.0;          // known invalid height
}

Person & Person::operator=(const Person & p)
{
    if (this != &p)
    {
        delete [] name;
        set_name(p.name);
        set_SSN(p.SSN);
        set_height(p.height);
    }
    return *this;
}

void Person::input(istream & in)
{
    long s;
    double h;
    get_line(name, in);         // no extra protection needed -- see lib
    in >> s >> h;
    set_SSN(s);                 // protect our SSN from user entry
    set_height(h);              // protect our height from user entry
    return;
}

bool Person::valid(void) const
{
    return name != nullptr;
}

void Person::output(ostream & out) const
{
    if (valid())
    {
        out << name << endl
            << SSN << ' ' << height;
    }
    return;
}

void Person::get_name(char Name[], long len) const
{
    if (valid())
    {
        if (len <= 0)
        {
            strcpy(Name, name);           // we don't have their length and so
                                          // can't protect the copy
        }
        else
        {
            strncpy(Name, name, len-1);
            Name[len-1] = '\0';
        }
    }
    else
    {
        Name[0] = '\0';
    }
    return;
}

long Person::get_SSN(void) const
{
    return (valid()) ? (SSN) : (0);
}

double Person::get_height(void) const
{
    return (!valid()) ? (0.0) : (height);
}

void Person::set_name(const char Name[], long len)
{
    delete [] name;
    name = new char [(len <= 0 ? strlen(Name) : len)+1];
    if (valid())
    {
        strcpy(name, Name);
    }
    return;
}

void Person::set_SSN(long sSN)
{
    SSN = (sSN < 0) ? (0) : (sSN);   // we don't want negative SSNs
    return;
}

void Person::set_height(double Height)
{
    height = (Height < 0) ? (0.0) : (Height);    // nor negative heights
    return;
}

