<?php

error_reporting(-1);

abstract class Employee
{
	private $rate;
	private $litresOfCoffee;
	private $pgsOfDocs;
	private $rank;
	private $boss;

	public function __construct($rate, $litresOfCoffee, $pgsOfDocs, $rank, $boss = false){
		$this->rate = $rate;
		$this->litresOfCoffee = $litresOfCoffee;
		$this->pgsOfDocs = $pgsOfDocs;
		$this->rank = $rank;
		$this->boss = $boss;
		if ($this->rank > 1) {
			$this->setRateWithRank();
		}
		if ($boss) {
			$this->setBossPrivelege();
		}
	}

	public function getRate(){
		return $this->rate;
	}

	public function getCoffee(){
		return $this->litresOfCoffee;
	}

	public function getPages(){
		return $this->pgsOfDocs;
	}

	private function setRateWithRank(){
		if ($this->rank == 2) {
			$this->rate = $this->rate * 1.25;
		}
		if ($this->rank == 3) {
			$this->rate = $this->rate * 1.50;
		}
	}

	private function setBossPrivelege(){
		$this->rate = $this->rate * 1.50;
		$this->litresOfCoffee = $this->litresOfCoffee * 2;
		$this->pgsOfDocs = 0;
	}
}

class Manager extends Employee
{}
class Marketer extends Employee
{}
class Engineer extends Employee
{}
class Analyst extends Employee
{}

class Department
{
	private $name;
	private $employees;

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

	public function getNumOfEmployees(){
		$numOfEmployees = 0;
		foreach ($this->employees as list($num, $position)) {
			$numOfEmployees += $num;
		}
		return $numOfEmployees;
	}

	public function getSalaryOfEmployees(){
		$salaryOfEmployees = 0;
		foreach ($this->employees as list($num, $position)) {
			$salaryOfEmployees += $position->getRate() * $num;	
		}
		return $salaryOfEmployees;
	}

	public function getDrunkCoffee(){
		$drunkCoffee = 0;
		foreach ($this->employees as list($num, $position)) {
			$drunkCoffee += $position->getCoffee() * $num;
		}
		return $drunkCoffee;
	}

	public function getPagesOfDocs(){
		$pagesOfDocs = 0;
		foreach ($this->employees as list($num, $position)) {
			$pagesOfDocs += $position->getPages() * $num;
		}
		return $pagesOfDocs;
	}

	public function getTugricsPerPage(){
		return round(($this->getSalaryOfEmployees() / $this->getPagesOfDocs()), 1);
	}

	public function getNameOfDept(){
		return $this->name;
	}

}

class Company
{
	private $departments;
	private $name;

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

	public function getNameOfCompany(){
		return $this->name;
	}
	public function getDepartments(){
		return $this->departments;
	}
}

function padRight($string, $widthOfCol){
	$lengthOfString = mb_strlen($string);
	if ($lengthOfString < $widthOfCol) {
		$formattedString = $string . str_repeat(" ", $widthOfCol - $lengthOfString);
		return $formattedString;
	}
}

function padLeft($string, $widthOfCol){
	$lengthOfString = mb_strlen($string);
	if ($lengthOfString < $widthOfCol) {
		$formattedString = str_repeat(" ", $widthOfCol - $lengthOfString) . $string;
		return $formattedString;
	}
}
//существующие виды сотрудников в компании
$manager1 = new Manager(500, 20, 200, 1);
$manager2 = new Manager(500, 20, 200, 2);
$manager2boss = new Manager(500, 20, 200, 2, true);
$manager3 = new Manager(500, 20, 200, 3);
$marketer1 = new Marketer(400, 15, 150, 1);
$analyst1 = new Analyst(800, 50, 5, 1);
$analyst2 = new Analyst(800, 50, 5, 2);
$marketer2boss = new Marketer(400, 15, 150, 2, true);
$marketer2 = new Marketer(400, 15, 150, 2);
$engineer1 = new Engineer(200, 5, 50, 1);
$marketer3boss = new Marketer(400, 15, 150, 3, true);
$manager1boss = new Manager(500, 20, 200, 1, true);
//Сотрудники в департаментах
$procurementDepartmentEmpls = [
	[9, $manager1],
	[3, $manager2],
	[2, $manager3],
	[2, $marketer1],
	[1, $manager2boss]
];
$salesDepartmentEmpls = [
	[12, $manager1],
	[6, $marketer1],
	[3, $analyst1],
	[2, $analyst2],
	[1, $marketer2boss]
];
$advertisingDepartmentEmpls = [
	[15, $marketer1],
	[10, $marketer2],
	[8, $manager1],
	[2, $engineer1],
	[1, $marketer3boss]
];
$logisticsDepartmentEmpls = [
	[13, $manager1],
	[5, $manager2],
	[5, $engineer1],
	[1, $manager1boss],
];
//Департаменты
$departments = [
	$procurementDepartment = new Department("Закупок", $procurementDepartmentEmpls),
	$salesDepartment = new Department("Продаж", $salesDepartmentEmpls),
	$advertisingDepartment = new Department("Рекламы", $advertisingDepartmentEmpls),
	$logisticsDepartment = new Department("Логистики", $logisticsDepartmentEmpls),
];
//Компания
$company = new Company("Вектор", $departments);

//Вывод информации
$col1 = 15;
$col2 = 10;
$col3 = 10;
$col4 = 10;
$col5 = 10;
$col6 = 12;

echo padRight("Департамент", $col1) .
     padLeft("Сотр.", $col2) . 
     padLeft("Тугр.", $col3) . 
     padLeft("Кофе", $col4) . 
     padLeft("Стр.", $col5) . 
     padLeft("Тугр./стр.", $col6) . "\n\n";

$allEmployees = 0;
$allSalary = 0;
$allCoffee = 0;
$allPages = 0;
$allTugPerPgs = 0;

foreach ($company->getDepartments() as $department) {

	echo padRight($department->getNameOfDept(), $col1) .
	padLeft($department->getNumOfEmployees(), $col2) .
	padLeft($department->getSalaryOfEmployees(), $col3) .
	padLeft($department->getDrunkCoffee(), $col4) .
	padLeft($department->getPagesOfDocs(), $col5) . 
	padLeft($department->getTugricsPerPage(), $col6) . "\n";

	$allEmployees += $department->getNumOfEmployees();
	$allSalary += $department->getSalaryOfEmployees();
	$allCoffee += $department->getDrunkCoffee();
	$allPages += $department->getPagesOfDocs();
	$allTugPerPgs += $department->getTugricsPerPage();
}

$numOfDepartments = count($company->getDepartments());

echo padRight("Среднее", $col1) .
     padLeft(round(($allEmployees / $numOfDepartments),1), $col2) . 
     padLeft(round(($allSalary / $numOfDepartments), 1), $col3) . 
     padLeft(round(($allCoffee / $numOfDepartments), 1), $col4) . 
     padLeft(round(($allPages / $numOfDepartments), 1), $col5) .
     padLeft(round(($allTugPerPgs / $numOfDepartments), 1), $col6) . "\n";

echo padRight("Всего", $col1) .
     padLeft($allEmployees, $col2) . 
     padLeft($allSalary, $col3) . 
     padLeft($allCoffee, $col4) . 
     padLeft($allPages, $col5) .
     padLeft($allTugPerPgs, $col6) . "\n";
