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

class Department {
    public $employees = array();

    public function __construct($boss, $name,
                                $managers1, $managers2, $managers3,
                                $marketers1, $marketers2, $marketers3,
                                $engineers1,
                                $analysts1, $analysts2) {
        $this->name = $name;
        for ($i = 0; $i < $managers1; $i++){
            $this->employees[] = new Manager(1, false);
        }
        for ($i = 0; $i < $managers2; $i++){
            $this->employees[] = new Manager(2, false);
        }
        for ($i = 0; $i < $managers3; $i++){
            $this->employees[] = new Manager(3, false);
        }
        for ($i = 0; $i < $marketers1; $i++){
            $this->employees[] = new Marketer(1, false);
        }
        for ($i = 0; $i < $marketers2; $i++){
            $this->employees[] = new Marketer(2, false);
        }
        for ($i = 0; $i < $marketers3; $i++){
            $this->employees[] = new Marketer(3, false);
        }
        for ($i = 0; $i < $engineers1; $i++){
            $this->employees[] = new Engineer(1, false);
        }
        for ($i = 0; $i < $analysts1; $i++){
            $this->employees[] = new Analyst(1, false);
        }
        for ($i = 0; $i < $analysts2; $i++){
            $this->employees[] = new Analyst(2, false);
        }
        $this->employees[] = $boss;
    }

    public function calcCoffeeConsumption() {
        $consumption = 0;
        foreach ($this->employees as $employee) {
            $consumption = $consumption + $employee->coffee;
        }
        return $consumption;
    }
    public function calcMoneyConsumption() {
        $consumption = 0;
        foreach ($this->employees as $employee) {
            $consumption = $consumption + $employee->salary;
        }
        return $consumption;
    }
    public function calcReportsGeneration() {
        $generation = 0;
        foreach ($this->employees as $employee) {
            $generation = $generation + $employee->reports;
        }
        return $generation;
    }
    public function calcToogreeksPerPage() {
        $toogreeks  = $this->calcMoneyConsumption() / $this->calcReportsGeneration();
        return round($toogreeks, 2);
    }
    public function getNumberOfEmployees() {
        return count($this->employees);
    }
}

abstract class Employee {
    public function countSalary($salary) {
        if ($this->rank == 2) {
            $salary =  $salary * 1.25;
        }elseif ($this->rank == 3) {
            $salary = $salary * 1.5;
        }
        if ($this->isBoss == true) {
            $salary = $salary * 1.5;
        }
        return $salary;
    }
    public function countCoffee($coffee) {
        if ($this->isBoss == true) {
            $coffee = $coffee * 2;
        }
        return $coffee;
    }
    public function countReports($reports) {
        if ($this->isBoss == true) {
            $reports = 0;
        }
        return $reports;
    }
}

class Manager extends Employee {
    public function __construct($rank, $isBoss) {
    	$salary = 500;
    	$coffee = 20;
    	$reports = 200;
        $this->rank = $rank;
        $this->isBoss = $isBoss;
        $this->salary = $this->countSalary($salary);
        $this->coffee = $this->countCoffee($coffee);
        $this->reports = $this->countReports($reports);
    }
}
class Marketer extends Employee {
    public function __construct($rank, $isBoss) {
    	$salary = 400;
    	$coffee = 15;
    	$reports = 150;
        $this->rank = $rank;
        $this->isBoss = $isBoss;
        $this->salary = $this->countSalary($salary);
        $this->coffee = $this->countCoffee($coffee);
        $this->reports = $this->countReports($reports);
    }
}
class Engineer extends Employee {
    public function __construct($rank, $isBoss) {
    	$salary = 200;
    	$coffee = 5;
    	$reports = 50;
        $this->rank = $rank;
        $this->isBoss = $isBoss;
        $this->salary = $this->countSalary($salary);
        $this->coffee = $this->countCoffee($coffee);
        $this->reports = $this->countReports($reports);
    }
}
class Analyst extends Employee {
    public function __construct($rank, $isBoss) {
    	$salary = 800;
    	$coffee = 50;
    	$reports = 5;
        $this->rank = $rank;
        $this->isBoss = $isBoss;
        $this->salary = $this->countSalary($salary);
        $this->coffee = $this->countCoffee($coffee);
        $this->reports = $this->countReports($reports);
    }
}

function padLeft($string, $length) {
    $stlen = mb_strlen($string);
    if ($stlen < $length) {
        for ($i = 0; $i < $length - $stlen; $i++) {
            $string = " " . $string;
        }
    }
    return $string;
}
function padRight($string, $length) {
    $stlen = mb_strlen($string);
    if ($stlen < $length) {
        for ($i = 0; $i < $length - $stlen; $i++) {
            $string = $string . " ";
        }
    }
    return $string;
}
function calcAverage($company, $method) {
    $summary = 0;
    foreach ($company as $department) {
        $summary = $summary + $department->$method();
    }
    return round($summary / count($company), 2);
}
function calcTotal($company, $method) {
    $summary = 0;
    foreach ($company as $department) {
        $summary = $summary + $department->$method();
    }
    return $summary;
}

$purchasing = new Department(new Manager(2, true), "Закупок",
                             9, 3, 2,
                             2, 0, 0,
                             0,
                             0, 0);

$sales = new Department(new Marketer(2, true), "Продаж",
                        12, 0, 0,
                        6, 0, 0,
                        0,
                        3, 2);

$marketing = new Department(new Marketer(3, true), "Рекламы",
                            8, 0, 0,
                            15, 10, 0,
                            2,
                            0, 0);

$logistics = new Department(new Manager(1, true), "Логистики",
                            13, 5, 0,
                            0, 0, 0,
                            5,
                            0, 0);

$company = array($purchasing, $sales, $marketing, $logistics);

$col1 = 20;
$col2 = 8;
$col3 = 10;
$col4 = 10;
$col5 = 10;
$col6 = 12;
echo padRight("Департамент", $col1) .
     padLeft("сотр.", $col2) .
     padLeft("тугр.", $col3) .
     padLeft("кофе", $col4) .
     padLeft("стр.", $col5) .
     padLeft("тугр./стр.", $col6) . "\n----------------------------------------------------------------------\n-\n";
foreach ($company as $department) {
    echo padRight($department->name, $col1) .
         padLeft(count($department->employees), $col2) .
         padLeft($department->calcMoneyConsumption(), $col3) .
         padLeft($department->calcCoffeeConsumption(), $col4) .
         padLeft($department->calcReportsGeneration(), $col5) .
         padLeft($department->calcToogreeksPerPage(), $col6) . "\n";
}
echo "-\n" . padRight("Среднее", $col1) .
     padLeft(calcAverage($company, 'getNumberOfEmployees'), $col2) .
     padLeft(calcAverage($company, 'calcMoneyConsumption'), $col3) .
     padLeft(calcAverage($company, 'calcCoffeeConsumption'), $col4) .
     padLeft(calcAverage($company, 'calcReportsGeneration'), $col5) .
     padLeft(calcAverage($company, 'calcToogreeksPerPage'), $col6) . "\n";
echo padRight("Всего", $col1) .
     padLeft(calcTotal($company, 'getNumberOfEmployees'), $col2) .
     padLeft(calcTotal($company, 'calcMoneyConsumption'), $col3) .
     padLeft(calcTotal($company, 'calcCoffeeConsumption'), $col4) .
     padLeft(calcTotal($company, 'calcReportsGeneration'), $col5) .
     padLeft(calcTotal($company, 'calcToogreeksPerPage'), $col6) . "\n";
?>
