// @topic W13-2-020 pet license application v2
// @brief C++ classes implementation

#include <cstdlib>
#include <iomanip>
#include "pet_license.h"

Pet::Pet(
    std::string name,
    //char type,
    int age,
    std::string color,
    bool adoption
    )
    : // initializer list
    name( name ),
    //type( type ),
    age( age ),
    color( color ),
    adoption( adoption )
{
}//Pet::Pet()


PetOwner::PetOwner(
    std::string name,
    int age,
    std::string address
    )
    : // initializer list
    name( name ),
    age( age ),
    address( address )
{
}//PetOwner::PetOwner()


void PetOwner::add( Pet* ptr_pet )
{
    pets.push_back( ptr_pet );
}//PetOwner::add()


void PetOwner::print() const
{
    std::cout << "Name: " << name << "\n";
    std::cout
        << "Senior Citizen: "
        << ( is_senior_citizen() ? 'Y' : 'N' )
        << "\n"
        ;
    std::cout << "Address: " << address << "\n";
    for ( Pet const* pet : pets ) {
        // C++2011
        pet->print();
    }
}//PetOwner::print()


bool PetOwner::is_senior_citizen() const
{
    return ( age >= SENIOR_CITIZEN_AGE );
}//PetOwner::is_senior_citizen()


void Pet::print() const
{
    //std::cout << ( type == 'C' ? "Cat" : "Dog" );
    std::cout << "\t name: " << name;
    std::cout << " age " << age;
    std::cout << ( adoption ? " (adoption)" : "" ) << "\n";
}//Pet::print()


PetLicense::PetLicense( PetOwner* powner )
    :
    powner( powner ),
    total_fee( 0.00 ),
    license_number( rand() % 10000 + 10000 )
{
}//PetLicense::PetLicense()


double PetLicense::calculate_fee()
{
    // Rules:
    // 1). One processing fee per dog
    // 2). One processing fee per three cats
    total_fee = 0.00;
    total_fee += compute_fee();
    total_fee -= compute_discounts();
    total_fee += powner->compute_fee();
    total_fee -= powner->compute_discounts();

    for ( Pet const* pet : powner->pets ) {
        total_fee += pet->compute_fee();
        total_fee -= pet->compute_discounts();
    }//for
    return total_fee;
}//PetLicense::calculate_fee()


void PetLicense::print() const
{
    std::cout << "---------------------------------------\n";
    std::cout << "PET LICENSE #" << license_number << "\n";
    powner->print();
    std::cout
        << "\nTotal license fee charge: "
        << std::fixed
        << std::setprecision( 2 )
        << total_fee << "\n";
    std::cout << "---------------------------------------\n";
}//PetLicense::print()


double Pet::compute_fee() const
{
    //if ( type == 'D' ) {
        return tag_fee + dog_fee;
    //} else {
        return tag_fee + cat_fee;
    //}
}//Pet::compute_fee()

double Pet::compute_discounts() const
{
    if ( adoption ) {
        return tag_fee;
    }
    return 0.0;
}//Pet::compute_discounts()

double PetOwner::compute_fee() const
{
    return 0.0;
}//PetOwner::compute_fee()

double PetOwner::compute_discounts() const
{
    if ( is_senior_citizen() ) {
        return discount_fee;
    }
    return 0.0;
}//PetOwner::compute_discounts()


double PetLicense::compute_fee() const
{
    return license_fee + processing_fee + donation_fee + state_fee;
}//PetLicense::compute_fee()

double PetLicense::compute_discounts() const
{
    return 0.0;
}//PetLicense::compute_discounts()



Dog::Dog(
    std::string name,
    int age,
    std::string color,
    bool adoption
)
:
Pet( name, age, color, adoption )
{
}//Dog::Dog


Cat::Cat(
    std::string name,
    int age,
    std::string color,
    bool adoption
)
:
Pet( name, age, color, adoption )
{
}//Cat::Cat