<?php
error_reporting(-1);

class Organisation //содержит методы для подсчета общих и средних параметров по конторе
{
	public $name;
	public $departments = [];
	
	public function __construct($name)
	{
		$this->name = $name;
	}
	
	public function countTotalWorkers()
	{
		$totalWorkers = 0;
		foreach($this->departments as $unit) {
			$totalWorkers += $unit->countDepWorkers();
		}
		return $totalWorkers;
	}
	
	public function countAveregeWorkers()
	{
		return $this->countTotalWorkers() / count($this->departments);
	}

	public function countTotalCoffe()
	{
		$companyCoffe = 0;
		foreach ($this->departments as $dep) {
			$companyCoffe += $dep->countDepCoffe();
		}
		return $companyCoffe;
	}
	
	public function countTotalSalary()
	{
		$companySalary = 0;
		foreach ($this->departments as $dep) {
			$companySalary += $dep->countDepSalary();
		}
		return $companySalary;
	}
	
	public function countTotalDocs()
	{
		$companyDocs = 0;
		foreach ($this->departments as $dep) {
			$companyDocs += $dep->countDepDocs();
		}
		return $companyDocs;
	}


	public function countAveregeCoffe()
	{
		return $this->countTotalCoffe() / count($this->departments);
	}

	public function countAveregeSalary()
	{
		return $this->countTotalSalary() / count($this->departments);
	}
	
	public function countAveregeDocs()
	{
		return $this->countTotalDocs() / count($this->departments);
	}

	public function countTotalEfficiency() 
	{
		$companyEfficiency = 0;
		foreach ($this->departments as $dep) {
			$companyEfficiency += $dep->countDepEfficiency();
		}
		return $companyEfficiency;
	}
	
	public function countAveregeEfficiency()
	{
		return $this->countTotalEfficiency() / count($this->departments);
	}
		
	public function makeReport()
	{
		
		$col1 = 22;
		$col2 = 13;
		$col3 = 11;
	
		function padLeft ($string, $length) {
			$strLength = mb_strlen($string);
			$num = $length - $strLength - 1;
			if ($num < 0) {
				$num = 0;
			}
			$spases = str_repeat(" ", $num);
			$string = "|" . $spases . $string;
			return $string;
		}
 
		function padRight ($string, $length) {
			$strLength = mb_strlen($string);
				$num = $length - $strLength;
			if ($num < 0) {
				$num = 0;
			}
			$spases = str_repeat(" ", $num);
			$string .= $spases;
			return $string;
		}

	
		echo padRight("Департамент", $col1) .
			padLeft("сотрудников", $col2) .
			padLeft("тугрики", $col3) .
			padLeft("кофе", $col3) .
			padLeft("документы", $col2) .
			padLeft("тугр./документы", $col1) .
			"\n";

		echo "--------------------------------------------------------------------------------\n";

		foreach ($this->departments as $dep) {
			echo padRight($dep->getName(), $col1) .
				padLeft($dep->countDepWorkers(), $col2) .
				padLeft($dep->countDepSalary(), $col3) .
				padLeft($dep->countDepCoffe(), $col3) .
				padLeft($dep->countDepDocs(), $col2) .
				padLeft($dep->countDepEfficiency(), $col1) .
				"\n";
		}

		echo "--------------------------------------------------------------------------------\n";

		echo padRight("Среднее", $col1) . 
				padLeft($this->countAveregeWorkers(), $col2) .
				padLeft($this->countAveregeSalary(), $col3) .
				padLeft($this->countAveregeCoffe(), $col3) .
				padLeft($this->countAveregeDocs(), $col2) .
				padLeft($this->countAveregeEfficiency(), $col1) .
				"\n" ;
		
		echo padRight("Всего", $col1) . 
				padLeft($this->countTotalWorkers(), $col2) .
				padLeft($this->countTotalSalary(), $col3) .
				padLeft($this->countTotalCoffe(), $col3) .
				padLeft($this->countTotalDocs(), $col2) .
				padLeft($this->countTotalEfficiency(), $col1) .
				"\n";
		
		
	}

}

class Department  
{
	public $name;
	public $workers = [];
	
	public function __construct($name)
	{
		$this->name = $name;
	}
	
	public function addWorkers($amount, $class, $rank, $leader) {
		for($i=1; $i<=$amount; $i++ ) {
			$this->workers[] = new $class($rank, $leader); 
		}
	}
	
	public function getName()
	{
		return $this->name;
	}
	
	public function countDepWorkers()
	{
		return count($this->workers);
	}
	
	public function countDepCoffe()
	{
		$totalDepCoffe = 0;
		foreach ($this->workers as $worker) {
			$totalDepCoffe += $worker->coffeUsage;
		}
		return $totalDepCoffe;
	}
	
	public function countDepSalary()
	{
		$totalDepSalary = 0;
		foreach ($this->workers as $worker) {
			$totalDepSalary += $worker->salary;
		}
		return $totalDepSalary;
	}
	
	public function countDepDocs()
	{
		$totalDepDocs = 0;
		foreach ($this->workers as $worker) {
			$totalDepDocs += $worker->docs;
		}
		return $totalDepDocs;
	}

	function countDepEfficiency()
	{
		return $this->countDepSalary() / $this->countDepDocs();
	}
	
}

class Employee
{
	public $salary;
	public $coffeUsage;
	public $docs;
	public $rank;
	public $leader;
	public $defaultSalary;
	
	public function __construct($rank, $leader) {
		$this->rank = $rank;
		$this->leader = $leader;
		$this->setSalary();
		$this->setCoffeUsage();
		$this->setDocs();
	}
	
	public function setSalary ()
	{
		if ($this->rank == 2) {
			$rankBonus = 1.25;
		} elseif ($this->rank == 3) {
			$rankBonus = 1.5;
		} else {
			$rankBonus = 1;
		}
		
		if ($this->leader == true) {
			$leaderBonus = 1.5;
		} else {
			$leaderBonus = 1;
		}
		$this->salary = $this->defaultSalary * $rankBonus * $leaderBonus;
	}
	
	public function setCoffeUsage()
	{
		if ($this->leader) {
			$this->coffeUsage = $this->defaultCoffeUsage * 2;
		} else {
			$this->coffeUsage = $this->defaultCoffeUsage;
		}
	}
	
	public function setDocs ()
	{
		if ($this->leader) {
			$this->docs = 0;
		} else {
			$this->docs = $this->defaultDocs;
		}
	}
}

class Manager extends Employee 
{
	public $defaultSalary = 500;
	public $defaultCoffeUsage = 20;
	public $defaultDocs = 200;
}

class MarketGuy extends Employee
{
	public $defaultSalary = 400;
	public $defaultCoffeUsage = 15;
	public $defaultDocs = 150;
}

class Engineer extends Employee
{
	public $defaultSalary = 200;
	public $defaultCoffeUsage = 5;
	public $defaultDocs = 50;
}

class Analyst extends Employee
{
	public $defaultSalary = 800;
	public $defaultCoffeUsage = 50;
	public $defaultDocs = 5;
}









//создаю организацию:
$vector = new Organisation("Вектор");

//департаменты
$purchase = new Department("Департамент закупок"); 
//заполняю планктоном
$purchase->addWorkers(9, "Manager", 1, false); //9 менеджеров 1 ранга, не лидеры
$purchase->addWorkers(3, "Manager", 2, false);
$purchase->addWorkers(2, "Manager", 3, false);
$purchase->addWorkers(2, "MarketGuy", 1, false);
$purchase->addWorkers(1, "Manager", 2, true); //1 менеджер 2 ранга, начальник
$vector->departments[] = $purchase;

$sales = new Department("Департамент продаж");
$sales->addWorkers(12, "Manager", 1, false);
$sales->addWorkers(16, "MarketGuy", 1, false);
$sales->addWorkers(3, "Analyst", 1, false);
$sales->addWorkers(2, "Analyst", 2, false);
$sales->addWorkers(1, "MarketGuy", 2, true);
$vector->departments[] = $sales;

$advertising = new Department("Департамент рекламы");
$advertising->addWorkers(15, "MarketGuy", 1, false);
$advertising->addWorkers(10, "MarketGuy", 2, false);
$advertising->addWorkers(8, "Manager", 1, false);
$advertising->addWorkers(2, "Engineer", 1, false);
$advertising->addWorkers(1, "MarketGuy", 3, true);
$vector->departments[] = $advertising;

$logistics = new Department("Департамент логистики");
$logistics->addWorkers(13, "Manager", 1, false);
$logistics->addWorkers(5, "Manager", 2, false);
$logistics->addWorkers(5, "Engineer", 1, false);
$logistics->addWorkers(1, "Manager", 1, true);
$vector->departments[] = $logistics;


$vector->makeReport();