<?php
header("Content-Type: text/plain");
mb_internal_encoding('utf-8');

//  ООП. Вектор и антикризичные меры

// Статический класс коофициентов для расчетов
class Coefficients
{
    // Коофициенты зарплаты для ранга
    static private $xRankSalary = array (1 => '1',
                                         2 => '1.25',
                                         3 => '1.5');
    // Коофициенты зарплаты для начальников
    static private $xChiefSalary = array (0 => '1',
                                          1 => '1.5');
    // Коофициенты потребления кофе для начальников
    static private $xChiefCoffee = array (0 => '1',
                                          1 => '2');
    // Коофициенты продуктивности для начальников
    static private $xChiefProduct = array (0 => '1',
                                           1 => '0');

    // Возвращаем коэф. зарплаты согласно рангу
    static public function getXRankSalary ($rank)
    {
        return self::$xRankSalary[$rank];
    }
    // Возвращаем коэф. зарплаты шефа
    static public function getXChiefSalary ($сhief)
    {
        return self::$xChiefSalary[$сhief];
    }
    // Возвращаем коэф. потребления кофе шефа
    static public function getXChiefCoffee ($сhief)
    {
        return self::$xChiefCoffee[$сhief];
    }
    // Возвращаем коэф. производительности шефа
    static public function getXChiefProduct ($сhief)
    {
        return self::$xChiefProduct[$сhief];
    }
}

// Класс сотрудника
class Employee
{
    private $rank    = 1;    // ранг
    private $chief   = 0;    // статус руководителя
    private $profession;     // профессия

    public function __construct ($profession, $rank, $chief)
    {
        // Присвоение профессии сотруднику
        $this->profession = $profession;
        // Присвоение ранга сотруднику
        $this->rank = $rank;
        // Присвоение статуса начальник
        $this->chief = $chief;
    }
    // Присвоение профессии сотруднику
    public function addProfession (Profession $profession)
    {
        $this->profession = $profession;
    }
    // Присвоение ранга сотруднику
    public function setRank ($rank)
    {
        $this->rank = $rank;
    }
    // Присвоение статуса начальник
    public function setСhief ($chief)
    {
        $this->chief = $chief;
    }
    // Меням профессию
    public function setProfession ($profession)
    {
        $this->profession = $profession;
    }
    // Возвращаем ранг сотрудника
    public function getRank ()
    {
        return $this->rank;
    }
    // Возвращаем название профессии сотрудника
    public function getProfessionName ()
    {
        return $this->profession->name;
    }
    // Возвращаем статус шафа сотрудника
    public function getChief ()
    {
        return $this->chief;
    }
    // Расчет зарплаты
    public function getSalary ()
    {
        // Профессия
        $profession = $this->profession;
        // Ставка по профессии
        $salaryRate = $profession->getSalaryRate();
        // Узнаем коэффициент согласно рангу сотрудника
        $tmpxRank = Coefficients::getXRankSalary($this->rank);
        // Узнаем коэффициент для начальника
        $tmpxChiefSalary = Coefficients::getXChiefSalary($this->chief);
        // Расчет зарплаты
        $salary = $salaryRate * $tmpxRank * $tmpxChiefSalary;

        return $salary;
    }
    // Расчет потребления кофе
    public function getCoffee ()
    {
        // Профессия
        $profession = $this->profession;
        // Потребление кофе по профессии
        $coffeeRate = $profession->getCoffeeRate();
        // Вычисляем коэффициент для начальника
        $tmpxChiefCoffee = Coefficients::getXChiefCoffee($this->chief);;
        // Расчет потребления кофе
        $coffee = $coffeeRate * $tmpxChiefCoffee;

        return $coffee;
    }
    // Расчет продуктивности
    public function getProduct ()
    {
        // Профессия
        $profession = $this->profession;
        // Продуктивность по профессии
        $productRate = $profession->getProduct();
        // Вычисляем коэффициент для начальника
        $tmpxChiefProduct = Coefficients::getXChiefProduct($this->chief);;
        // Расчет продуктивности
        $product = $productRate * $tmpxChiefProduct;

        return $product;
    }
}

// Абстрактный класс профессии
abstract class Profession
{
    public $name = "";   // название профессии

    abstract public function getSalaryRate();
    abstract public function getCoffeeRate();
    abstract public function getProduct();
}

// Класс менджер
class Manager extends Profession
{
    public $name = "Manager";

    public function getSalaryRate()
    {
        return 500;
    }
    public function getCoffeeRate()
    {
        return 20;
    }
    public function getProduct()
    {
        return 200;
    }
}

// Класс маркетолог
class Marketer extends Profession
{
    public $name = "Marketer";

    public function getSalaryRate()
    {
        return 500;
    }
    public function getCoffeeRate()
    {
        return 20;
    }
    public function getProduct()
    {
        return 200;
    }
}

// Класс инженер
class Engineer extends Profession
{
    public $name = "Engineer";

    public function getSalaryRate()
    {
        return 200;
    }
    public function getCoffeeRate()
    {
        return 5;
    }
    public function getProduct()
    {
        return 50;
    }
}

// Класс аналитик
class Analyst extends Profession
{
    public $name = "Analyst";

    public function getSalaryRate()
    {
        return 800;
    }
    public function getCoffeeRate()
    {
        return 50;
    }
    public function getProduct()
    {
        return 5;
    }
}
// Класс аналитик
class NewAnalyst extends Profession
{
    public $name = "Analyst";

    public function getSalaryRate()
    {
        return 1100;
    }
    public function getCoffeeRate()
    {
        return 75;
    }
    public function getProduct()
    {
        return 5;
    }
}

// Класс департамента
class Departament
{
    public $name = "";            // название
    private $employees = array(); // сотрудники

    public function __construct ($name)
    {
        $this->name = $name;
    }
    // Клонирование департамента    
    public function __clone()
    {
        $employeesClones = array(); // клоны работников
        
        foreach($this->employees as $employee) {
           $employee = clone $employee;
           $departamentsClones[] = $employee;
        }
        // Заменяем массив работников массивом клонов
        $this->employees = $departamentsClones;
    }
    // Прием сотрудника на работу
    public function addEmployee (Employee $employee )
    {
        $this->employees[] = $employee;
    }
    // Расчет количества сотрудников по профессии, не указанный параметр возвращает общее кол-во
    public function countEmployees ($profession = '')
    {
        $employeesNumber = 0; // число сотрудников
        
        // Если считаем сотрудников определенной профессии
        foreach ($this->employees as $employee) {
                
            // Если сотрудник не соответствует профессии
            if ($employee->getProfessionName() == $profession) {
                continue;
            }                
            // Счетчик
            $employeesNumber++;
        }
        // Если профессия не задана
        if ($profession == "") {
            $employeesNumber = count($this->employees); 
        }   
        return $employeesNumber;
    }
    // Возвращаем сотрудников массивом
    public function getEmployees()
    {
        return $this->employees;
    }
    // Поиск сотрудника по профессии, рангу, статусу шефа
    // параметр может принимать значение 'all', параметр будет игнорироваться
    public function findEmployee ($profession, $rank, $chief)
    {
        $employee = null; // искомый Сотрудник
           
        // Перебираем всех сотрудников
        foreach ($this->employees as $employee) {
                
            // Если сотрудник не соответствует профессии
            if ($employee->getProfessionName() != $profession &&
                $profession != 'all') {
                continue;
            }
            // Если сотрудник не соответствует рангу
            if ($employee->getRank() != $rank &&
                $rank != 'all') {
               continue;
            }
            // Если сотрудник не является начальником
            if ($employee->getChief() != $chief &&
                $chief != 'all') {
                continue;
            }                
            // Возвращаем Сотрудника
            return $employee;
        } 
    }
    // Увольнение сотрудника
    public function dismissEmployee($employee)
    {
       $employeeKey = array_search($employee, $this->employees);
       unset ($this->employees[$employeeKey]);
    }
    // Расходы на зарплату
    public function getTotalSalary ()
    {
        $totalSalary = 0;     // сумарная зарплата
        // Для каждого сотрудника
        foreach ($this->employees as $employee) {
            // Запрашиваем зп у сотрудника и суммируем результат
            $totalSalary += $employee->getSalary ();
        }
        return $totalSalary;
    }
    // Рассход кофе
    public function getTotalCoffee ()
    {
        $totalCoffee = 0;     // сумарное потребление кофе
        // Для каждого сотрудника
        foreach ($this->employees as $employee) {
            // Запрашиваем потребление кофе у сотрудника  и суммируем результат
            $totalCoffee += $employee->getCoffee ();
        }
        return $totalCoffee;
    }
    // Суммарная производительность
    public function getTotalProduct ()
    {
        $totalProduct = 0;     // сумарная продуктивность
        // Для каждого сотрудника
        foreach ($this->employees as $employee) {
            // Запрашиваем продуктивность у сотрудника и суммируем результат
            $totalProduct += $employee->getProduct ();
        }
        return $totalProduct;
    }
    // Средний расход тугриков на одну страницу
    public function getAverageCostPerProduct ()
    {
        // Средняя стоимость 1 страницы = суммарная зарплата / сумарное количество страниц
        $avrCostPerProduct = $this->getTotalSalary () / $this->getTotalProduct ();

        return $avrCostPerProduct;
    }
}

// Класс компании
class Company
{
    public $name = ""; // название
    private $departaments = array(); // департаменты

    public function __construct($name)
    {
        $this->name = $name;
    }   
    // Клонирование компании
    public function __clone()
    {
        $departamentsClones = array(); // клоны департаментов
        
        foreach($this->departaments as $departament) {
            $departament = clone $departament;
            $departamentsClones[]=$departament;
        }
        // Заменяем массив департаментов массивом клонов
        $this->departaments = $departamentsClones; 
    }
    // Создание департамента
    public function createDepartament ($name)
    {
        $this->departaments[$name] = new Departament ($name);
    }
    // Поиск департамента по названию, аргумент "all" возращает все департааменты
    public function findDepartamentByName ($name = 'all')
    {
        $result = ""; // ссылка на департамент или массив департаментов
        // Ищем департамент в массиве по названию
        if ($name != 'all'){
            $result = $this->departaments[$name];
        }
        // Возвращаем все департаменты массивом, если просят
        if ($name == "all") {
            foreach ($this->departaments as $name => $departament) {
                $result[$name] = $departament;
            }
        }
        // Если ничего не нашли
        if ($result == null) {
            // Ничего не возвращам, мы обиделись
            die ("Департамент не найден");
        }
        return $result;
    }
     // Сумарное количество работников
    public function getTotalEmployees ()
    {
        $totalEmployees = 0;
        // Для каждого департамента
        foreach ($this->departaments as $departament) {
            // Сумируем работников всех департаментов
            $totalEmployees += $departament->countEmployees();
        }
        return $totalEmployees;
    }
    // Расходы на зарплату в сумме
    public function getTotalSalary ()
    {
        $salary = 0;
        // Для каждого департамента
        foreach ($this->departaments as $departament) {
            // Сумируем зп всех департаментов
            $salary += $departament->getTotalSalary();
        }
        return $salary;
    }

    // Рассход кофе в сумме
    public function getTotalCoffee ()
    {
        $coffee = 0;
        // Для каждого департамента
        foreach ($this->departaments as $departament) {
            // Суммируем расход кофе у департаментов
            $coffee += $departament->getTotalCoffee();
        }
        return $coffee;
    }

    // Суммарная производительность
    public function getTotalProduct ()
    {
        $product = 0;
        // Для каждого департамента
        foreach ($this->departaments as $departament) {
            // Суммируем производительность каждого департамента
            $product += $departament->getTotalProduct();;
        }
        return $product;
    }
    // Среднее количество работников по департаментам
    public function getAverageEmployees ()
    {
        // Среднее количество работников = суммарное кол-во работников / кол-во департаментов
        $avrEmployees = $this->getTotalEmployees () / count($this->departaments);

        return $avrEmployees;
    }
    // Средняя зарплата по департаментам
    public function getAverageSalary ()
    {
        // Средняя зарплата = суммарная зарплата / кол-во департаментов
        $avrSalary = $this->getTotalSalary () / count($this->departaments);

        return $avrSalary;
    }
    // Среднее потребление кофе по департаментам
    public function getAverageCoffee ()
    {
        // Среднее потребление кофе = суммарная потребление кофе / кол-во департаментов
        $avrCoffee = $this->getTotalCoffee () / count($this->departaments);

        return $avrCoffee;
    }
    // Средняя производительность по департаментам
    public function getAverageProduct ()
    {
        // Средняя производительность = суммарная производительность / кол-во департаментов
        $avrProduct = $this->getTotalProduct () / count($this->departaments);

        return $avrProduct;
    }
    // Средний расход тугриков на одну страницу по департаментам
    public function getAverageCostPerProduct ()
    {
        $avrCostPerProduct = 0;
        // Для каждого департамента
        foreach ($this->departaments as $departament) {
            // Сумируем средний расход
            $avrCostPerProduct += $departament->getAverageCostPerProduct();
        }
        // Средняя стоимость 1 страницы = cредняя стоимость всех департ  / кол-во департаментов
        $avrCostPerProduct = $avrCostPerProduct / count($this->departaments);

        return $avrCostPerProduct;
    }
}
// Антикризисные меры 1
class AnticrisisFirst
{        
    /*
    *  Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров,
    *  преимущественно самого низкого ранга. Если инженер является боссом,
    *  вместо него надо уволить другого инженера, не босса.
    *  */
    static public function dismissEngineers($company)
    {
        $companyClone = clone $company;
        
        // Запрашивавем все департаменты в компании
        $departaments = $companyClone->findDepartamentByName();
        
        // Перебираем все департаменты в компании
        foreach ($departaments as $departamentName => $departament) {
            
            // Число всех инженеров
            $engineersNumber = $departament->countEmployees("Engineer");
            
            // Число уволенных мамкиных инженеров
            $dismissedEngineers = 0;
        
            // Процент уволенных инженеров
            $procentDismissedEngineers = 0;            
                    
            // Начинаем с первого ранга
            $rank = 1;
        
            // Нужно уволить 40%
            while ($procentDismissedEngineers < 40 && $rank < 3 ) {
                
                // Находим нужного инженера
                $engineer = $departament->findEmployee("Engineer", $rank, 0);
                //var_dump($engineer);
                
                // Если не нашли нужного ранга
                if ($engineer == null) {
                    // Увеличиваем ранг
                    $rank++;
                    // Повторяем цикл сначала
                    continue;
                }
                
                // Увольняем сотрудника
                $departament->dismissEmployee($engineer);
                
                // Число уволенных мамкиных инженеров
                $dismissedEngineers++;
                
                // Процент уволенных инженеров
                $procentDismissedEngineers = $dismissedEngineers / $engineersNumber * 100;
            }
        }
        // Выводим статистику на печать
        printStatistics($companyClone, "Антикризисные меры 1");
    } 
}
/*  Антикризисные меры 2
 *  Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков,
 *  а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах,
 *  где руководитель не является аналитиком, заменить его на аналитика
 *  самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)
 *  */
class AnticrisisSecond
{
    static public function increaseSalaryRate($company)
    {
        $companyClone = clone $company;
        
        // Создаем новую профессию аналитика
        $newAnalyst = new NewAnalyst;
        
        // Запрашивавем все департаменты в компании
        $departaments = $companyClone->findDepartamentByName();
        
        // Перебираем все департаменты в компании
        foreach ($departaments as $departamentName => $departament) {
            
            // Запрашиваем работников
            $employees = $departament->getEmployees();
            
            // Перебираем работников
            foreach($employees as $employee) {
                
                // Если профессия аналитик
                if ($employee->getProfessionName () == "Analyst") {
                    // Меняем профессию на новую
                    $employee->setProfession ($newAnalyst);                    
                }
            }
        }
        foreach ($departaments as $departamentName => $departament) {
            
            // Находим шефа в компании
            $chiefEmployee = $departament->findEmployee ("all", "all", 1);
            // Узнаем профессию
            $professionName = $chiefEmployee->getProfessionName();
            
            // Находим аналитика самого высокого ранга
            // Запрашиваем Аналитиков от 3 до 1 ранга, определяем самый высокй ранг 
            for ($rank = 3; $rank > 0; $rank--) {
                
                // Запрашиваем Ааналитика из Департамента
                $analyst = $departament->findEmployee ("Analyst", $rank, 0);
                
                // Проверяем, вернул ли Департамент Аналитика нужного ранга
                if ($analyst != null) {
                    
                    // Назначаем Аналитика шефом
                    $analyst->setСhief(1);
                    
                    // Снимаем с должности текущего шефа
                    $chiefEmployee->setСhief(0);
                    break;
                }
            }
        }
        // Выводим статистику на печать        
        printStatistics($companyClone, "Антикризисные меры 2");
    }
}

/*  Антикризисные меры 3
 *  В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга
 *  на один ранг с целью расширить их полномочия.
 *  */
class AnticrisisThird
{
    static public function liftManager($company)
    {
        // Создаем новую компанию
        $companyClone = clone $company;
        
        // Запрашивавем все департаменты в компании
        $departaments = $companyClone->findDepartamentByName();
        
        // Перебираем все департаменты в компании
        foreach ($departaments as $departamentName => $departament) {
            
            // Запрашиваем всех работников
            $employees = $departament->getEmployees ();
            
            $managerNumber = 0;         // Количество манагеров 1 и 2 ого ранга
            $liftedManagerNumber = 0;   // Количество повышенных манагеров 1 и 2 ого ранга
            $liftedManagerProcent = 0;  // % повышенных манагеров 1 и 2 ого ранга
            
            // Перебираем всех сотрудников чтобы посчитать кол-во манагеров
            foreach ($employees as $employee) {

                $employeeProfessionName = $employee->getProfessionName();
                $employeeRank = $employee->getRank();
                
                if ($employeeProfessionName != "Manager") {
                    continue;
                }
                if ($employeeRank > 2) {
                    continue;
                }
                // Считаем менеджеров
                $managerNumber++;
            }
            // Перебираем всех сотрудников, чтобы повысить манагеров 1 и 2 ранга
            foreach ($employees as $employee) {

                $employeeProfessionName = $employee->getProfessionName();
                $employeeRank = $employee->getRank();
                
                if ($employeeProfessionName != "Manager") {
                    continue;
                }
                if ($employeeRank > 2) {
                    continue;
                }
                // Повышаем манагера                
                $employee->setRank($employeeRank+1);
                
                // Считаем
                $liftedManagerNumber++;
                $liftedManagerProcent = ($liftedManagerNumber / $managerNumber) * 100;
                
                // Проверяем процент повышенных манагеров                
                if ($liftedManagerProcent > 50){
                    break;
                }
            }            
        }
        printStatistics($companyClone, "Антикризисные меры 3");
    }    
}

// Функция создания компании
function createCompany($name)
{
    // Создаем новый класс компании
    $vector = new Company('$name');

    // Создаем классы департаментов
    $vector->createDepartament('Департамент закупок');
    $vector->createDepartament('Департамент продаж');
    $vector->createDepartament('Департамент рекламы');
    $vector->createDepartament('Департамент логистики');

    // Создаем классы профессий
    $me = new Manager();
    $ma = new Marketer();
    $en = new Engineer();
    $an = new Analyst();

    // Добавляем профессии в масив для последующего создания сотрудников пачкой
    $professions['me'] = $me;
    $professions['ma'] = $ma;
    $professions['en'] = $en;
    $professions['an'] = $an;

    // Лист вакансий: департамент => группы вакансий: профессияРанг статус_начальника => кол-во
    $vacancies = array(
                    'Департамент закупок' => array('me1'=>'9', 'me2'=>'3', 'me3'=>'2', 'ma1'=>'2', 'me2 1'=>'1'),
                    'Департамент продаж' => array('me1'=>'12', 'ma1'=>'6', 'an1'=>'3', 'an2'=>'2', 'ma2 1'=>'1'),
                    'Департамент рекламы' => array('ma1'=>'15', 'ma2'=>'10', 'me1'=>'8', 'en1'=>'2', 'ma3 1'=>'1'),
                    'Департамент логистики' => array('me1'=>'13', 'me2'=>'5', 'en1'=>'5', 'me1 1'=>'1')
                  );

    // Для каждого департамента
   foreach ($vacancies as $depName => $vacancyGroup) {
    
        // Для каждой группы вакансий
        foreach ($vacancyGroup as $vacancyName => $vacancyQuantity) {
    
            // Достаем название профессии из вакансии
            $professionIndex = mb_substr ($vacancyName, 0, 2);
            $profession = $professions[$professionIndex];
            // Достаем ранг из вакансии
            $rank = mb_substr ($vacancyName, 2, 1);
            // Достаем статус начальника из вакансии
            $chief = mb_substr ($vacancyName, 4, 1);
            $chief = ($chief==null)? 0 : 1; // если статус не определен явно, считаем что 0
    
            // Создаем столько сотрудников, сколько вакансий в группе
            for ($id = 1; $id <= $vacancyQuantity; $id++) {
                // Создаем сотрудника
                $employee = new Employee($profession, $rank, $chief);
    
                // Запрашиваем в Компании нужный департамент
                $departament = $vector->findDepartamentByName($depName);
                // Добавляем сотрудника в этот Департамент
                $departament->addEmployee($employee);
            }
        }
    }
    // Возвращаем объект Компания
    return $vector;
}

// Класс строки таблицы, хранит не фарматированную строку
class TableRow
{
    private $columns = array();   // строка это массив из колонок

    // Конструктор принимает массив колонок
    public function __construct ($columns)
    {
        $this->columns = $columns;
    }
    // Метод возвращает содержимое строки (все ее колоночки)
    public function getColumns()
    {
        return $this->columns;
    }
}
// Класс таблицы
class Table
{
    private $tableRows = array ();  // массив объектов Строк
    private $length = 15;           // ширина колонок

    // Добавление строки в таблицу, принимает массив
    public function addRow ($row)
    {
        // Создаем новую строку
        $this->tableRows[] = new TableRow($row);
    }
    // Печать таблицы
    public function printTable ()
    {
        $caption = 1;   // первая строка - заголовок таблицы

        // Перебираем массив объектов Строк
        foreach($this->tableRows as $row) {

            $stringRow = "";    // строка для печати
            $columnNumber = 0;  // счетчик колонок

            // Извлекаем колонки из строки
            $columns = $row->getColumns();

            // Форматируем каждую колонку в строке
            foreach($columns as $column) {

                // Округляем числа до 2х знаков после запятой
                if (is_float($column)) {
                    $column = round ($column, 2);
                }
                // Добавляем отступы справа для первой колонки
                if ($columnNumber == 0) {
                    $stringRow .= "\n" . $this->padRight($column, $this->length);
                // Добавляем оступы слева для остальных колонок
                } else {
                    $stringRow .= $this->padLeft($column, $this->length);
                }
                $columnNumber++;
            }
            // Добавляем черту после заголовка
            if ($caption == 1) {
                $stringRow .= "\n" . $this->formatCaption($columnNumber, $this->length);
            }
            // Выводим строку на печать
            echo "{$stringRow}";

            $caption--; // останется только один заголовок
        }
    }
    // Добавление пробелов слева
    private function padLeft($string, $length)
    {
        // Разница между переданной строкой и шириной колонки
        $lenghtDifference = $length-mb_strlen($string);
        // Проверка на отрицательное значение при вычитании
        if ($lenghtDifference >= 0) {
            // Заполняем разницу пробелами
            $string = str_repeat(" ", $lenghtDifference) . $string;
        } else {
            // Если таки отрицательное, обрезаем край строки до ширины колонки
            $string = mb_substr ($string, 0, $length);
        }
        return $string;
    }
    // Добавление пробелов справа
    private function padRight($string, $length)
    {
        // Разница между переданной строкой и шириной колонки
        $lenghtDifference = $length-mb_strlen($string);
        // Проверка на отрицательное значение при вычитании
        if ($lenghtDifference >= 0) {
            // Заполняем разницу пробелами
            $string .= str_repeat(" ", $lenghtDifference);
        } else {
            // Если таки отрицательное, обрезаем край строки до ширины колонки
            $string = mb_substr ($string, 0, $length);
        }
        return $string;
    }
    // Делаем горизонтальную черту
    private function formatCaption($columnNumber, $length)
    {
        $string = str_repeat("-", $length * $columnNumber);
        return $string;
    }
}

/*  Вывод таблицы результатов   */

// Функция вывода статистики по компании
function printStatistics($company, $caption) {
    
    // Создаем таблицу
    $table = new Table();
    
    // Заголовок таблицы
    $table->addRow (array ("Департамент",
                           "сотр.",
                           "тугр.",
                           "кофе",
                           "стр.",
                           "тугр./стр.."));
    
    // Статистика по департаентам
    $departaments = $company->findDepartamentByName();
    // Каждый департамент строка
    foreach ($departaments as $departament) {
        unset($columns); // обнуляем массив
        // Заполняем массив строк
        $columns[] = mb_convert_case(mb_substr($departament->name, 12), MB_CASE_TITLE, "UTF-8");
        $columns[] = $departament->countEmployees();
        $columns[] = $departament->getTotalSalary();
        $columns[] = $departament->getTotalCoffee();
        $columns[] = $departament->getTotalProduct();
        $columns[] = $departament->getAverageCostPerProduct();
        // Добавляем строку в таблицу
        $table->addRow($columns);
    }
    
    // Пустая строка
    unset($columns); // обнуляем массив
    $columns[] = ' ';    
    // Добавляем строку в таблицу
    $table->addRow($columns);
    
    // Среднее для всей компании
    unset($columns); // обнуляем массив
    // Заполняем массив строк
    $columns[] = 'Среднее';
    $columns[] = $company->getAverageEmployees();
    $columns[] = $company->getAverageSalary();
    $columns[] = $company->getAverageCoffee();
    $columns[] = $company->getAverageProduct();
    $columns[] = $company->getAverageCostPerProduct();    
    // Добавляем строку в таблицу
    $table->addRow($columns);

    // Всего для всей компании
    unset($columns); // обнуляем массив
    // Заполняем массив строк
    $columns[] = 'Всего';
    $columns[] = $company->getTotalEmployees();
    $columns[] = $company->getTotalSalary();
    $columns[] = $company->getTotalCoffee();
    $columns[] = $company->getTotalProduct();    
    // Добавляdем строку в таблицу
    $table->addRow($columns);
    
    // Выводим на печать заголовок
    echo "{$caption}\n";
    
    // Выводим таблицу на печать
    $table->printTable();
    echo "\n\n";
}
// Регистрируем Vector Inc на Сейшельских островах
$vector = createCompany('Vector');
printStatistics($vector, "Докризисная статистика");
AnticrisisFirst::dismissEngineers($vector);
AnticrisisSecond::increaseSalaryRate($vector);
AnticrisisThird::liftManager($vector);  
?>