<?php 

abstract class Employee
{
  protected $boss;
  protected $rang;
  protected $salary;
  protected $coffeeValue;
  protected $paper;

  function __construct($boss, $rang)
  {
    $this->boss = $boss;
    $this->rang = $rang;
  }

  static function recruit ($boss, $rang, $class) {
    return new $class($boss, $rang);
  }

  public function getSalary()
  {
    $salary;

    switch ($this->rang) {
      case 2:
        $salary = $this->salary * 1.25;
        break;
      case 3:
        $salary = $this->salary * 1.5;
      break;
      default:
        $salary = $this->salary;
      break;
    }

    if ($this->boss == true) {
      $salary *= 1.3;
    }

    return $salary;
  }

  public function getCoffee() {
    if ($this->boss) {
      return $this->coffeeValue*2;
    }
    return $this->coffeeValue;
  }

  public function getPaper() {
    if ($this->boss) {
      return 0;
    }
    return $this->paper;
  }
}

class Manager extends Employee
{
  function __construct($boss, $rang)
  {
    parent::__construct($boss, $rang);
    $this->salary      = 500;
    $this->coffeeValue = 20;
    $this->paper       = 200;
  }
}

class Marketer extends Employee
{
  function __construct($boss, $rang)
  {
    parent::__construct($boss, $rang);
    $this->salary      = 400;
    $this->coffeeValue = 15;
    $this->paper       = 150;
  }
}

class Engineer extends Employee
{
  function __construct($boss, $rang)
  {
    parent::__construct($boss, $rang);
    $this->salary      = 200;
    $this->coffeeValue = 5;
    $this->paper       = 50;
  }
}

class Analyst extends Employee
{  
  function __construct($boss, $rang)
  {
    parent::__construct($boss, $rang);
    $this->salary      = 800;
    $this->coffeeValue = 50;
    $this->paper       = 5;
  }
}


class Departament
{
    private $employees = array();
    private $nameOfDepartament;

    public function __construct ($name) {
      $this->nameOfDepartament = $name;
    }

    private function newEmployee($number, $class, $rang, $boss = false) 
    {
        for ($i=0; $i < $number; $i++) { 
            $this->employees[] = Employee::recruit($boss, $rang, $class);
        }
    }

    public function addEmployees($number, $class, $rang)
    {
      $this->newEmployee($number, $class, $rang);
    }

    public function addDirector($class, $rang) 
    {
        $this->newEmployee(1, $class, $rang, $boss = true);
    }

    public function getEmployees()
    {
        return $this->employees;
    }

    public function calculateCostForASalary() 
    {
      $sumOfSalary = 0;
      foreach ($this->employees as $employee) {
        $sumOfSalary += $employee->getSalary();
      }
      return $sumOfSalary;
    }

    public function calculateAmountOfCoffe() 
    {
      $amountOfCoffe = 0;
      foreach ($this->employees as $employee) {
        $amountOfCoffe += $employee->getCoffee();
      }
      return $amountOfCoffe;
    }

    public function calculateAmountOfPaper() 
    {
      $amountOfPaper = 0;
      foreach ($this->employees as $employee) {
        $amountOfPaper += $employee->getPaper();
      }
      return $amountOfPaper;
    }

    public function getNameOfDepartament() {
      return $this->nameOfDepartament;
    }

}


class Company
{
  private $departaments = array();

  public function __construct()
  {
    $departament = new Departament("Отдел закупок");
    $departament->addEmployees(9, "Manager", 1);
    $departament->addEmployees(3, "Manager", 2);
    $departament->addEmployees(2, "Manager", 1);
    $departament->addEmployees(2, "Marketer", 1);
    $departament->addDirector("Manager", 2);

    $this->departaments[] = $departament;

    $departament = new Departament("Отдел продаж");
    $departament->addEmployees(12, "Manager", 1);
    $departament->addEmployees(6, "Marketer", 1);
    $departament->addEmployees(3, "Analyst", 1);
    $departament->addEmployees(2, "Analyst", 1);
    $departament->addDirector("Marketer", 2);

    $this->departaments[] = $departament;

    $departament = new Departament("Отдел рекламы");
    $departament->addEmployees(15, "Manager", 1);
    $departament->addEmployees(10, "Marketer", 2);
    $departament->addEmployees(8, "Manager", 1);
    $departament->addEmployees(2, "Engineer", 1);
    $departament->addDirector("Marketer", 3);

    $this->departaments[] = $departament;

    $departament = new Departament("Отдел логистики");
    $departament->addEmployees(13, "Manager", 1);
    $departament->addEmployees(5, "Manager", 2);
    $departament->addEmployees(5, "Marketer", 1);
    $departament->addDirector("Manager", 1);

    $this->departaments[] = $departament;
  }

  public function showInformation() 
  {
    $sumOfSalary;
    $sumOfCoffee;
    $sumOfPaper;
    $sumOfEmployees;

    foreach ($this->departaments as $departament) {
      echo ( "Название: ".$departament->getNameOfDepartament()."\n" );
      echo ( "Зарплата всего: ".$departament->calculateCostForASalary()."\n" );
      $sumOfSalary += $departament->calculateCostForASalary();
      echo ( "Кофе всего: ".$departament->calculateAmountOfCoffe()."\n" );
      $sumOfCoffee += $departament->calculateAmountOfCoffe();
      echo ( "Страниц всего: ".$departament->calculateAmountOfPaper()."\n" );
      $sumOfPaper += $departament->calculateAmountOfPaper();
      echo ( "Работников всего: ".count( $departament->getEmployees() ) );
      $sumOfEmployees += count( $departament->getEmployees() );
      echo ( "\n\n" );
    }

    echo ( "Всего сотрудников: ".$sumOfEmployees."\n" );
    echo ( "Всего затрачено на зарплату: ".$sumOfSalary."\n" );
    echo ( "Всего выпито кофе: ".$sumOfCoffee."\n" );
    echo ( "Всего страниц: ".$sumOfPaper."\n" );

    echo ( "\n\n" );

    echo ( "В среднем сотрудников: ".$sumOfEmployees/count( $this->departaments )."\n" );
    echo ( "В среднем затрачено на зарплату: ".$sumOfSalary/count( $this->departaments )."\n" );
    echo ( "В среднем выпито кофе: ".$sumOfCoffee/count( $this->departaments )."\n" );
    echo ( "В среднем страниц: ".$sumOfPaper/count( $this->departaments )."\n" );

  }

}

$company1 = new Company();
$company1->showInformation();