<?php
 
error_reporting(-1);
mb_internal_encoding('utf-8');

class Employee
{
	public $quantity;
	public $position;
	public $boss;
	public $rank;
	
	const POSITION_MANAGER = 'Manager';
	const POSITION_MARKETER = 'Marketer';
	const POSITION_ANALYST = 'Analyst';
	const POSITION_ENGINEER = 'Engineer';
 
	public function __construct($position, $rank, $boss, $quantity)
	{
		$this->quantity = $quantity;
		$this->boss = $boss;
		$this->rank = $rank;
		
		if ($position == self::POSITION_MANAGER||$position == self::POSITION_MARKETER||
		$position == self::POSITION_ANALYST||$position == self::POSITION_ENGINEER)
		{
			$this->position = $position;
		}else{
			echo 'Професия введена неверно.';
		}
 
	}
	
		protected function getSalary()
	{
		if ($this->rank == 1){
			$factor = 1;
		}elseif($this->rank == 2){
			$factor = 1.25;
		}elseif($this->rank == 3){
			$factor = 1.5;
		}
		if ($this->boss == true)
		{
			$bossFactor = 1.5;
		}else{
			$bossFactor = 1;
		}
		$salary = $this->rate * $factor * $bossFactor;
		return $salary;
	}
 
	protected function getCoffe()
	{
		if ($this->boss == true)
		{
			$bossFactor = 2;
		}else{
			$bossFactor = 1;
		}
		$coffe = $this->coffe * $bossFactor;
		return $coffe;
	}
 
	protected function getPages()
	{
		if ($this->boss == true)
		{
			$bossFactor = 0;
		}else{
			$bossFactor = 1;
		}
		$pages = $this->pages * $bossFactor;
		return $pages;
	}
}
 
class Manager extends Employee
{
	protected $rate = 500;
	protected $coffe = 20;
	protected $pages = 200;
 
	public $rank;
	public $boss;
 
	public function __construct($rank, $boss)
	{
		$this->rank = $rank;
		$this->boss = $boss;
	}
 
	public function getSalary()
	{
		return parent::getSalary();
	}
 
	public function getCoffe()
	{
		return parent::getCoffe();
	}
 
	public function getPages()
	{
		return parent::getPages();
	}
}
 
class Marketer extends Employee
{
	protected $rate = 400;
	protected $coffe = 15;
	protected $pages = 150;
 
	public $rank;
	public $boss;
 
	public function __construct($rank, $boss)
	{
		$this->rank = $rank;
		$this->boss = $boss;
	}
 
	public function getSalary()
	{
		return parent::getSalary();
	}
 
	public function getCoffe()
	{
		return parent::getCoffe();
	}
 
	public function getPages()
	{
		return parent::getPages();
	}
}
 
class Engineer extends Employee
{
	protected $rate = 200;
	protected $coffe = 5;
	protected $pages = 50;
 
	public $rank;
	public $boss;
 
	public function __construct($rank, $boss)
	{
		$this->rank = $rank;
		$this->boss = $boss;
	}
 
	public function getSalary()
	{
		return parent::getSalary();
	}
 
	public function getCoffe()
	{
		return parent::getCoffe();
	}
 
	public function getPages()
	{
		return parent::getPages();
	}
}
 
class Analyst extends Employee
{
	protected $rate = 800;
	protected $coffe = 50;
	protected $pages = 5;
 
	public $rank;
	public $boss;
 
	public function __construct($rank, $boss)
	{
		$this->rank = $rank;
		$this->boss = $boss;
	}
 
	public function getSalary()
	{
		return parent::getSalary();
	}
 
	public function getCoffe()
	{
		return parent::getCoffe();
	}
 
	public function getPages()
	{
		return parent::getPages();
	}
}
 
class Department
{
	public $departmentName;
	public $quantity;
	public $position;
	public $boss;
	public $rank;
 
	public function __construct($employees, $departmentName)
	{
		foreach ($employees as $employee)
		{
			$this->quantity[] = $employee->quantity;
			$this->position[] = $employee->position;
			$this->boss[] = $employee->boss;
			$this->rank[] = $employee->rank;
		}
		$this->departmentName = $departmentName;
	}
 
	public function getTotalCoffe()
	{
		$coffe = 0;
 
		for ($x = 0; $x < count($this->rank); $x++){
			if ($this->position[$x] == 'Manager')
			{
				$coffe = ((new Manager($this->rank[$x], $this->boss[$x]))->getCoffe())*$this->quantity[$x] + $coffe;
 
			}elseif ($this->position[$x] == 'Marketer')
			{
				$coffe = ((new Marketer($this->rank[$x], $this->boss[$x]))->getCoffe())*$this->quantity[$x] + $coffe;
 
			}elseif ($this->position[$x] == 'Engineer')
			{
				$coffe = ((new Engineer($this->rank[$x], $this->boss[$x]))->getCoffe())*$this->quantity[$x] + $coffe;
 
			}elseif ($this->position[$x] == 'Analyst')
			{
				$coffe = ((new Analyst($this->rank[$x], $this->boss[$x]))->getCoffe())*$this->quantity[$x] + $coffe;
			}
 
		}
		return $coffe;
	}
 
	public function getTotalSalary()
	{
		$salary = 0;
 
		for ($x = 0; $x < count($this->rank); $x++){
			if ($this->position[$x] == 'Manager')
			{
				$salary = ((new Manager($this->rank[$x], $this->boss[$x]))->getSalary())*$this->quantity[$x] + $salary;
 
			}elseif ($this->position[$x] == 'Marketer')
			{
				$salary = ((new Marketer($this->rank[$x], $this->boss[$x]))->getSalary())*$this->quantity[$x] + $salary;
 
			}elseif ($this->position[$x] == 'Engineer')
			{
				$salary = ((new Engineer($this->rank[$x], $this->boss[$x]))->getSalary())*$this->quantity[$x] + $salary;
 
			}elseif ($this->position[$x] == 'Analyst')
			{
				$salary = ((new Analyst($this->rank[$x], $this->boss[$x]))->getSalary())*$this->quantity[$x] + $salary;
			}
 
		}
		return $salary;
	}
 
	public function getTotalPages()
	{
		$pages = 0;
 
		for ($x = 0; $x < count($this->rank); $x++){
			if ($this->position[$x] == 'Manager')
			{
				$pages = ((new Manager($this->rank[$x], $this->boss[$x]))->getPages())*$this->quantity[$x] + $pages;
 
			}elseif ($this->position[$x] == 'Marketer')
			{
				$pages = ((new Marketer($this->rank[$x], $this->boss[$x]))->getPages())*$this->quantity[$x] + $pages;
 
			}elseif ($this->position[$x] == 'Engineer')
			{
				$pages = ((new Engineer($this->rank[$x], $this->boss[$x]))->getPages())*$this->quantity[$x] + $pages;
 
			}elseif ($this->position[$x] == 'Analyst')
			{
				$pages = ((new Analyst($this->rank[$x], $this->boss[$x]))->getPages())*$this->quantity[$x] + $pages;
			}
 
		}
		return $pages;
	}
 
	public function getPersonelAmount()
	{
		if (array_sum($this->quantity) != 0)
		{
			return array_sum($this->quantity);
		}else{
			return $this->quantity;
		}
	}
 
	public function getSalaryPerPages()
	{
		return round($this->getTotalSalary() / $this->getTotalPages(), 2);
	}
}
 
class Company 
{
	public $total = 'Всего';
	public $totalPersonelAmount;
	public $totalSalary;
	public $totalCoffe;
	public $totalDocumentation;
	public $totalSalaryPerPages;
 
	public $average = 'Среднее';
	public $averagePersonelAmount;
	public $averageSalary;
	public $averageCoffe;
	public $averageDocumentation;
	public $averageSalaryPerPages;
 
	public function __construct($departments)
	{
		foreach ($departments as $department)
		{
			$this->totalPersonelAmount = $department->getPersonelAmount() + $this->totalPersonelAmount;
	 		$this->totalSalary = $department->getTotalSalary() + $this->totalSalary;
	 		$this->totalCoffe = $department->getTotalCoffe() + $this->totalCoffe;
			$this->totalDocumentation = $department->getTotalCoffe() + $this->totalDocumentation;
			$this->totalSalaryPerPages = $department->getSalaryPerPages() + $this->totalSalaryPerPages;
		}
		$this->averagePersonelAmount = $this->totalPersonelAmount / count($departments);
		$this->averageSalary = round($this->totalSalary / count($departments), 2);
		$this->averageCoffe = round($this->totalCoffe / count($departments), 2);
		$this->averageDocumentation = round($this->totalDocumentation / count($departments), 2);
		$this->averageSalaryPerPages = round($this->totalSalaryPerPages / count($departments), 2);
 
 
	}
}
 
  function padRight($q, $w){
 return implode("", (array_merge(preg_split('//u', $q, 0, PREG_SPLIT_NO_EMPTY), array_fill(0, $w-mb_strlen($q), " "))));
 }
  function padLeft($q, $w){
 return implode("", (array_merge(array_fill(0, $w-mb_strlen($q), " "), preg_split('//u', $q, 0, PREG_SPLIT_NO_EMPTY))));
 }
 
$workers1 = array(
new Employee ('Manager', 1, false, 9),
new Employee ('Manager', 2, false, 3),
new Employee ('Manager', 3, false, 2),
new Employee ('Marketer', 1, false, 2),
new Employee ('Manager', 2, true, 1)
);
$workers2 = array(
new Employee ('Manager', 1, false, 12),
new Employee ('Marketer', 1, false, 6),
new Employee ('Analyst', 1, false, 3),
new Employee ('Analyst', 2, false, 2),
new Employee ('Marketer', 2, true, 1)
);
$workers3 = array(
new Employee ('Marketer', 1, false, 15),
new Employee ('Marketer', 2, false, 10),
new Employee ('Manager', 1, false, 8),
new Employee ('Engineer', 1, false, 2),
new Employee ('Marketer', 3, true, 1)
);
$workers4 = array(
new Employee ('Manager', 1, false, 13),
new Employee ('Manager', 2, false, 5),
new Employee ('Engineer', 1, false, 5),
new Employee ('Manager', 1, true, 1)
);
 
$departments = array(
	new Department($workers1, 'Закупок'),
	new Department($workers2, 'Продаж'),
	new Department($workers3, 'Рекламы'),
	new Department($workers4, 'Логистики')
	);
$company = new Company($departments);
 
function printData($departments, $company, $headline)
{
$col1 = 20;
$col2 = 8;
$col3 = 12;
$col4 = 12;
$col5 = 12;
$col6 = 12;
$col7 = 50;
if($headline == 0){
echo padRight("Департамент", $col1) .
     padLeft("сотр.", $col2) . 
     padLeft("тугр.", $col3) . 
     padLeft("кофе", $col4) .
     padLeft("стр.", $col5) .
     padLeft("тугр./стр.", $col6) . "\n" . 
     implode("", array_fill(0, 40, '--')) . "\n";
}else{
	echo padLeft ('Анти-кризисная мера #'."{$headline}", $col7)."\n";
	echo implode("", array_fill(0, 40, '--')) . "\n";
}
 
foreach ($departments as $department) {
    echo padRight($department->departmentName, $col1) .
         padLeft($department->getPersonelAmount(), $col2) . 
         padLeft($department->getTotalSalary(), $col3) . 
         padLeft($department->getTotalCoffe(), $col4) . 
         padLeft($department->getTotalPages(), $col5) .
         padLeft($department->getSalaryPerPages(), $col6) . "\n" ;
 
}   echo implode("", array_fill(0, 40, '--')) . "\n";
 
    echo padRight($company->average, $col1) .
         padLeft($company->averagePersonelAmount, $col2) . 
         padLeft($company->averageSalary, $col3) . 
         padLeft($company->averageCoffe, $col4) .
         padLeft($company->averageDocumentation, $col5) .
         padLeft($company->averageSalaryPerPages, $col6) . "\n";
 
    echo padRight($company->total, $col1) .
         padLeft($company->totalPersonelAmount, $col2) . 
         padLeft($company->totalSalary, $col3) . 
         padLeft($company->totalCoffe, $col4) .
         padLeft($company->totalDocumentation, $col5) .
         padLeft($company->totalSalaryPerPages, $col6)."\n\n";
}
printData($departments, $company, 0);