#include <iostream>
#include <iomanip>
#include <string>
#include <vector>

//h-fil

class Room
{
public:
  Room(std::string name, double area, bool disrepair = false);

  double get_area() const;
  double get_renovation_area() const;

private:
  std::string name;
  double area;
  bool disrepair;
};

class House
{
public:
  House(double city_distance, bool have_basement = false);

  void add_room(Room const& room);
  double valuation() const;

  House& operator+=(Room const& lhs);
  
private:
  std::vector<Room> room_list;
  double city_distance;
  double basement_impact;
};

//cc-fil

Room::Room(std::string name, double area, bool disrepair)
  : name{name}, area{area}, disrepair{disrepair}
{
  if ( area < 7.0 )
  {
    throw std::invalid_argument{"För litet att räknas som rum"};
  }
}

double Room::get_area() const
{
  return area;
}

double Room::get_renovation_area() const
{
  return disrepair ? area : 0.0;
}


House::House(double city_distance, bool have_basement)
  : room_list{}, city_distance{city_distance}, basement_impact{1.0}
{
  if (have_basement)
    basement_impact = 0.75;
}

void House::add_room(Room const& room)
{
  room_list.push_back(room);
}

double House::valuation() const
{
  double total_area{};
  double total_renovation{};
  
  for ( Room const& room : room_list )
  {
    total_area += room.get_area();
    total_renovation += room.get_renovation_area();
  }

  return ( total_area * 30000.0 * basement_impact * ( 4.0/(city_distance+3.0) + 0.6) - total_renovation * 10000.0 );
}

House& House::operator+=(Room const& lhs)
{
  add_room(lhs);
  return *this;
}

//huvudprogram

int main()
{
  for ( double i{}; i < 80.0; i = (i + 1) * 1.5)
  {
    House a{i};
  
    a.add_room(Room{"Kök", 16, true});
    a.add_room(Room{"Vardagsrum", 30});
    a.add_room(Room{"Badrum", 10, true});
    a.add_room(Room{"Kontor", 12, true});
    a += Room{"Sovrum", 12};
    a += Room{"Sovrum", 15};
    
    std::cout << std::fixed << std::setprecision(1) << std::setw(4) << i << " km => " << std::setprecision(1) << a.valuation() << std::endl;
  }
}