<?php

// your code goes here

/*
Департамент закупок: 9×ме1, 3×ме2, 2×ме3, 2×ма1 + руководитель департамента ме2
Департамент продаж: 12×ме1, 6×ма1, 3×ан1, 2×ан2 + руководитель ма2
Департамент рекламы: 15×ма1, 10×ма2, 8×ме1, 2×ин1 + руководитель ма3
Департамент логистики: 13×ме1, 5×ме2, 5×ин1 + руководитель ме1
*/

error_reporting(-1);

class Employee {
    protected $baseSalary;
    protected $coffee;
    protected $reports;
    protected $rank;
    protected $isHead;

    public function __construct($rank, $isHead) {
        $this->rank = $rank;
        $this->isHead = $isHead;
    }

    public function getSalary() {
        $salary = $this->baseSalary;
        switch ($this->rank) {
            case 2:
                $salary *= 1.25;
                break;
            case 3:
                $salary *= 1.5;
                break;
        }
        if ($this->isHead) {
            $salary *= 1.5;
        }

        return $salary;
    }

    public function setBaseSalary($newSalary) {
        $this->baseSalary = $newSalary;
    }

    public function getCoffee() {
        if ($this->isHead) {
            return $this->coffee * 2;
        } else {
            return $this->coffee;
        }
    }

    public function setCoffe($newCoffee) {
        $this->coffee = $newCoffee;
    }

    public function getReports() {
        if ($this->isHead) {
            return 0;
        } else {
            return $this->reports;
        }
    }

    public function getRank()
    {
        return $this->rank;
    }
    public function setRank($rank)
    {
        $this->rank = $rank;
    }
    public function getIsHead()
    {
        return $this->isHead;
    }
    public function setIsHead($isHead)
    {
        $this->isHead = $isHead;
    }

}

class Manager extends Employee {
    protected $baseSalary = 500;
    protected $coffee = 20;
    protected $reports = 200;
}

class Marketer extends Employee {
    protected $baseSalary = 400;
    protected $coffee = 15;
    protected $reports = 150;
}

class Engineer extends Employee {
    protected $baseSalary = 200;
    protected $coffee = 5;
    protected $reports = 50;
}

class Analyst extends Employee {
    protected $baseSalary = 800;
    protected $coffee = 50;
    protected $reports = 5;
}

class Department {
    private $name;
    private $employees = array();

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

    function __clone() {                                //------------------------
        foreach ($this->employees as &$employee) {
            $employee = clone $employee;
        }                                               //------------------------
    }

    public function getName() {
        return $this->name;
    }
    public function setName($name) {
        $this->name = $name;
    }

    public function getCountAllEmployees() {
        return count($this->employees);
    }

    public function getAllEmployees() {
        return $this->employees;
    }

    public function getAllSalary() {
        $allSalary = 0;
        foreach ($this->employees as $employee) {
            $allSalary += $employee->getSalary();
        }
        return $allSalary;
    }

    public function getAllCoffee() {
        $allCoffee = 0;
        foreach ($this->employees as $employee) {
            $allCoffee += $employee->getCoffee();
        }
        return $allCoffee;
    }

    public function getAllReports() {
        $allReports = 0;
        foreach ($this->employees as $employee) {
            $allReports += $employee->getReports();
        }
        return $allReports;
    }

    public function addEmployees($employees) {
        $this->employees = array_merge($this->employees, $employees);
    }

    public function fireEmployee($looser) {
        $fired = null;
        foreach($this->employees as $key => $employee) {
            if ($looser == $employee) {
                $fired = $looser;
                unset($this->employees[$key]);
                sort($this->employees);
                return $fired;
            }
        }
        return null;
    }
}

function createManagers($quantity, $rank, $isHead) {
    $employees = array();
    for ($i = 0; $i < $quantity; $i++) {
        array_push($employees, new Manager($rank, $isHead));
    }
    return $employees;
}

function createMarketers($quantity, $rank, $isHead) {
    $employees = array();
    for ($i = 0; $i < $quantity; $i++) {
        array_push($employees, new Marketer($rank, $isHead));
    }
    return $employees;
}

function createEngineers($quantity, $rank, $isHead) {
    $employees = array();
    for ($i = 0; $i < $quantity; $i++) {
        array_push($employees, new Engineer($rank, $isHead));
    }
    return $employees;
}

function createAnalysts($quantity, $rank, $isHead) {
    $employees = array();
    for ($i = 0; $i < $quantity; $i++) {
        array_push($employees, new Analyst($rank, $isHead));
    }
    return $employees;
}

function padRight($string, $length) {
    $spacesCount = $length - mb_strlen($string);
    $string .= str_repeat(" ", $spacesCount);
    return $string;
}

function padLeft($string, $length) {
    $modString = "";
    $spacesCount = $length - mb_strlen($string);
    $modString .= str_repeat(" ", $spacesCount);
    $modString .= $string;
    return $modString;
}

function outputString($words) {
    $col = 11;

    echo padRight($words[0], $col);

    for ($i = 1; $i < count($words); $i++) {
        echo padLeft($words[$i], $col);
    }
    echo "\n";
}

function outputResult($departments) {
    $totalEmployees = 0;
    $totalSalary = 0;
    $totalCoffee = 0;
    $totalReports = 0;
    $totalConsumption = 0;

    $words = array("Департамент", "сотр.", "тугр.", "кофе", "стр.", "тугр./стр.");
    outputString($words);

    echo str_repeat("-", 70);
    echo "\n";

    foreach ($departments as $department) {

        $employeesCount = $department->getCountAllEmployees();
        $totalEmployees += $employeesCount;

        $salary = $department->getAllSalary();
        $totalSalary += $salary;

        $coffee = $department->getAllCoffee();
        $totalCoffee += $coffee;

        $reports = $department->getAllReports();
        $totalReports += $reports;

        $consumption = round($salary / $reports, 2);
        $totalConsumption += $consumption;

        $words = array($department->getName(), $employeesCount, $salary, $coffee, $reports, $consumption);
        outputString($words);
    }

    echo "\n";

    $countDepartments = count($departments);
    $words = array("Среднее", $totalEmployees / $countDepartments, $totalSalary / $countDepartments, $totalCoffee / $countDepartments,
        $totalReports / $countDepartments, $totalConsumption / $countDepartments);
    outputString($words);

    $words = array("Всего", $totalEmployees, $totalSalary, $totalCoffee, $totalReports, $totalConsumption);
    outputString($words);
}

$employees = array();
$departments = array();

$employees = array_merge($employees, createManagers(9, 1, false), createManagers(3, 2, false),
    createManagers(2, 3, false), createMarketers(2, 1, false), createManagers(1, 2, true));

$purchases = new Department("Закупок");
$purchases->addEmployees($employees);

array_push($departments, $purchases);

$employees = array();
$employees = array_merge($employees, createManagers(12, 1, false), createMarketers(6, 1, false),
    createAnalysts(3, 1, false), createAnalysts(2, 2, false), createMarketers(1, 2, true));

$sales = new Department("Продаж");
$sales->addEmployees($employees);

array_push($departments, $sales);

$employees = array();
$employees = array_merge($employees, createMarketers(15, 1, false), createMarketers(10, 2, false),
    createManagers(8, 1, false), createEngineers(2, 1, false), createMarketers(1, 3, true));

$ad = new Department("Рекламы");
$ad->addEmployees($employees);

array_push($departments, $ad);

$employees = array();
$employees = array_merge($employees, createManagers(13, 1, false), createManagers(5, 2, false),
    createEngineers(5, 1, false), createManagers(1, 1, true));

$logistics = new Department("Логистики");
$logistics->addEmployees($employees);

array_push($departments, $logistics);

outputResult($departments);

echo "\n\nАнтикризисные меры:\n\n"; //------------------------------------------------------------------------------------

$testDepartments = array();

echo "1. Сократить в каждом департаменте 40% инженеров:\n\n";

foreach ($departments as $department) {
    $countEng = 0;
    $testDepartment = clone $department;
    $employees = $testDepartment->getAllEmployees();
    foreach ($employees as $employee) {
        if ($employee instanceof Engineer) {
            $countEng++;
        }
    }

    $needFire = ceil($countEng * 0.4);

    for ($i = 0; $i < $needFire; $i++) {
        for ($j = 0; $j < count($employees); $j++) {
            if ($employees[$j] instanceof Engineer && !$employees[$j]->getIsHead()) {
                $testDepartment->fireEmployee($employees[$j]);
                break;
            }
        }
    }
    array_push($testDepartments, $testDepartment);
}

outputResult($testDepartments);

echo "\n2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика:\n\n";

$testDepartments = array();

foreach ($departments as $department) {
    $testDepartment = clone $department;
    $employees = $testDepartment->getAllEmployees();
    $haveAnals = false;
    $firstAnal = null;
    foreach ($employees as $employee) {
        if ($employee instanceof Analyst) {
            $employee->setBaseSalary(1100);
            $employee->setCoffe(75);
            if ($firstAnal === null) {
                $haveAnals = true;
                $firstAnal = $employee;
            }
        }

        if ($employee->getIsHead() && !($employee instanceof Analyst) && $haveAnals) {
            $employee->setIsHead(false);
            $firstAnal->setRank(3);
            $firstAnal->setIsHead(true);
        }
    }
    array_push($testDepartments, $testDepartment);
}

outputResult($testDepartments);

/*echo "3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с
        целью расширить их полномочия:<br><br>";*/
echo "\nОригинальная таблица:\n\n";

outputResult($departments);