<?php
//С крипа берет начало каждый класс. Надо будет сделать абстрактным
abstract class Creep
{
	//Базовые данные. потом стоит изменить к ним доступ
	protected $salary;
	protected $thirst;
	protected $output;
	private $tier;
	private $isBig;
 
	//Давать доступ только через конструктор
	public function __construct($tier, $isBig){
		$this->tier = $tier;
		$this->isBig = $isBig;
	}
 
	//Выводит зарплату
	public function countTierSalary(){
		$salary = $this->salary;
		switch($this->tier){
			case 2 : 
				$salary += $salary * 0.25;
				break;
			case 3 :
				$salary += $salary * 0.5;
				break;
		}
		//Если крип- босс, то поднимаем оплату
		if($this->isBig == 1){
			$salary += $salary * 0.5;
		}
		return $salary;
	}
 
	//Выводит потребление
	public function countCreepThirst(){
		$thirst = $this->thirst;
		if($this->isBig == 1){
			$thirst += $thirst * 0.5;
		}
		return $thirst;
	}
 
	//Выводит выхлоп
	public function countCreepOutput(){
		$output = $this->output;
		if($this->isBig == 1){
			$output = 0;
		}
		return $output;
	}
}
 
//Менеджеры
class Manager extends Creep
{
	protected $salary = 500;
	protected $thirst = 20;
	protected $output = 200;
}
 
//Маркетологи
class Marketer extends Creep
{
	protected $salary = 400;
	protected $thirst = 15;
	protected $output = 150;
}
 
//Инженеры
class Engeneer extends Creep
{
	protected $salary = 200;
	protected $thirst = 5;
	protected $output = 15;
}
 
//Аналитики
class Analyst extends Creep
{
	protected $salary = 800;
	protected $thirst = 50;
	protected $output = 5;
}
 
 
//Типы сотрудников
$me1b = new Manager(1, 1);
$me2b = new Manager(2, 1);
$me1 = new Manager(1, 0);
$me2 = new Manager(2, 0);
$me3 = new Manager(3, 0);
$ma2b = new Marketer(2, 1);
$ma3b = new Marketer(3, 1);
$ma1 = new Marketer(1, 0);
$ma2 = new Marketer(2, 0);
$an1 = new Analyst(1, 0);
$an2 = new Analyst(2, 0);
$en1 = new Engeneer(1, 0);
 
//Абстрактный департамент, с него пойдут 4 департамента
abstract class Department
{
	//Массив сотрудников
	protected $listOfCreeps = array();
 
	//Метод, записывающий работника в массив
	public function fillListOfCreeps($creep){
		$this->listOfCreeps[] = $creep;
	}
 
	//Метод, выводящий кол-во сотрудников в департаменте
	public function countNumberOfCreeps(){
		$numberOfCreeps = count($this->listOfCreeps);
		return $numberOfCreeps;
	}
 
	//Метод, выводящий расходы на зарплату
	public function countSalary(){
		$sum = 0;
		foreach($this->listOfCreeps as $creep){
			$sum += $creep->countTierSalary();
		}
		return $sum;
	}
 
	//Метод, выводящий потребление кофе
	public function countThirst(){
		$sum = 0;
		foreach($this->listOfCreeps as $creep){
			$sum += $creep->countCreepThirst();
		}
		return $sum;
	}
 
	//Метод, выводящий кол-во страниц 
	public function countNumOfPages(){
		$sum = 0;
		foreach($this->listOfCreeps as $creep){
			$sum += $creep->countCreepOutput();
		}
		return $sum;
	}
 
	//Средний расход тугриков на страницу
	public function countCharge(){
		$charge = $this->countSalary() / $this->countNumOfPages();
		return floor($charge);
	}
 
	public function getName(){
		return $this->name;
	}
}
 
//Отдел закупок
class Procurement extends Department
{
	protected $name = 'Закупок';
}
 
//Забиваю отдел закупок
$procurement = new Procurement;
$procurement->fillListOfCreeps($me2b);
 
for($i = 0; $i < 9; $i++){
	$procurement->fillListOfCreeps($me1);
}
 
$procurement->fillListOfCreeps($me2);
$procurement->fillListOfCreeps($me2);
$procurement->fillListOfCreeps($me2);
 
$procurement->fillListOfCreeps($me3);
$procurement->fillListOfCreeps($me3);
 
$procurement->fillListOfCreeps($ma1);
$procurement->fillListOfCreeps($ma1);
 
/*
//Вывожу отдел закупок
print "Людей в отделе: ". $procurement->countNumberOfCreeps(). "\n".
"Общая затрата на зарплату: ". $procurement->countSalary(). "\n".
"Общие затраты на кофе: ". $procurement->countThirst(). "\n".
"Общий выхлоп: ". $procurement->countNumOfPages(). "\n".
"Расход денег на страницу: ". $procurement->countCharge(). "\n";
*/
 
//Отдел продаж
class Selling extends Department
{
	protected $name = 'Продаж';
}
 
//Забиваю отдел продаж
$selling = new Selling;
for($i = 0; $i < 12; $i++){
	$selling->fillListOfCreeps($me1);
}
 
for($i = 0; $i < 6; $i++){
	$selling->fillListOfCreeps($ma1);
}
 
$selling->fillListOfCreeps($an1);
$selling->fillListOfCreeps($an1);
$selling->fillListOfCreeps($an1);
 
$selling->fillListOfCreeps($an2);
$selling->fillListOfCreeps($an2);
 
$selling->fillListOfCreeps($ma2b);
 
//Отдел рекламы
class Marketing extends Department
{
	protected $name = 'Рекламы';
}
 
//Забиваю отдел рекламы
$marketing = new Marketing;
 
for($i = 0; $i < 15; $i++){
	$marketing->fillListOfCreeps($ma1);
}
 
for($i = 0; $i < 10; $i++){
	$marketing->fillListOfCreeps($ma2);
}
 
for($i = 0; $i < 8; $i++){
	$marketing->fillListOfCreeps($me1);
}
 
$marketing->fillListOfCreeps($en1);
$marketing->fillListOfCreeps($en1);
 
$marketing->fillListOfCreeps($ma3b);
 
//Отдел логистики
class Logistics extends Department
{
	protected $name = 'Логистики';
}
 
//Забиваю работников логистики
$logistics = new Logistics;
 
for($i = 0; $i < 13; $i++){
	$logistics->fillListOfCreeps($me1);
}
 
for($i = 0; $i < 5; $i++){
	$logistics->fillListOfCreeps($me2);
}
 
for($i = 0; $i < 5; $i++){
	$logistics->fillListOfCreeps($en1);
}
 
$logistics->fillListOfCreeps($me1b);
 
//Создаю класс компании
class Company
{
	//Массив со всеми департаментами
	private $fullList = array();
 
	//Доступ к массиву
	public function addDepartment($department){
		$this->fullList[] = $department;
	}
 
	//получить массив
	public function getListOfDepartments(){
		return $this->fullList;
	}
 
	//Общее кол-во работников
	public function getNumOfCreeps(){
		$sum = 0;
		foreach($this->fullList as $department){
			$sum += $department->countNumberOfCreeps();
		}
		return $sum;
	}
 
	//Общие затраты на зп
	public function getFinalSalary(){
		$sum = 0;
		foreach($this->fullList as $department){
			$sum += $department->countSalary();
		}
		return $sum;
	}
 
	//Всего кофе выжрали
	public function getFinalThirst(){
		$sum = 0;
		foreach($this->fullList as $department){
			$sum += $department->countThirst();
		}
		return $sum;
	}
 
	//Всего выхлопа
	public function getFinalOutput(){
		$sum = 0;
		foreach($this->fullList as $department){
			$sum += $department->countNumOfPages();
		}
		return $sum;
	}
 
	//Затраты на страничку
	public function getFinalCharge(){
		$charge = $this->getFinalSalary() / $this->getFinalOutput();
		return floor($charge);
	}
}
 
//Создаю вектор
$vector = new Company;
 
//Забиваю департаменты
$vector->addDepartment($procurement);
$vector->addDepartment($selling);
$vector->addDepartment($marketing);
$vector->addDepartment($logistics);
 
 
//Функция для забивания строки пробелами справа
function padRight($string){
 
	//Ширина колонки
	$column = 13;
 
	$length = mb_strlen(strval($string));
	$numOfPads = $column - $length;
	$filledColumn = strval($string). str_repeat(" ", $numOfPads);
	echo $filledColumn;
}
 
//Функция для забивания строки пробелами справа
function padLeft($string){
 
	//Ширина колонки
	$column = 13;
 
	$length = mb_strlen(strval($string));
	$numOfPads = $column - $length;
	$filledColumn = str_repeat(" ", $numOfPads). strval($string);
	echo $filledColumn;
}
 
//Выводим табличку
echo padRight('Департамент'). padLeft('сотр.'). padLeft('денег').
padLeft('кофе'). padLeft('стр.'). padLeft('кпд'). "\n";
 
foreach($vector->getListOfDepartments() as $department){
	echo padRight($department->getName()). padLeft($department->countNumberOfCreeps()). 
	padLeft($department->countSalary()). padLeft($department->countThirst()).
	padLeft($department->countNumOfPages()). padLeft($department->countCharge()). "\n";
}
 
echo padRight('Итого'). padLeft($vector->getNumOfCreeps()). padLeft($vector->getFinalSalary()).
padLeft($vector->getFinalThirst()). padLeft($vector->getFinalOutput()).
padLeft($vector->getFinalCharge());