<?php
/**
 * Created by PhpStorm.
 * User: Саша
 * Date: 04.05.2016
 * Time: 10:59
 */

abstract class Employee {
    protected $rank = 1;
    protected $coffee = 0;
    protected $pages = 0;
    protected $basicSalary = 0;
    protected $boss = false;

    public function getSalary() {
        $rate = 0;
        if ($this->boss == true) {
            $bossRank = 1.5;
        } else {
            $bossRank = 1;
        }
        if ($this->rank == 1) {
            $rate = 1;
        } elseif ($this->rank == 2) {
            $rate = 1.25;
        } elseif ($this->rank == 3) {
            $rate = 1.5;
        }
        $rate *= $bossRank;
        return $this->basicSalary * $rate;
    }

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

    public function getPages()
    {
        if ($this->boss) {
            return 0;
        } else {
            return $this->pages;
        }
    }
}

class Manager extends Employee {
    protected $rank = 1;
    protected $basicSalary = 500;
    protected $coffee = 20;
    protected $pages = 200;
    protected $boss = false;

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

class MarketingSpecialist extends Employee {
    protected $rank = 1;
    protected $basicSalary = 400;
    protected $coffee = 15;
    protected $pages = 150;
    protected $boss = false;

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

class Engineer extends Employee {
    protected $rank = 1;
    protected $basicSalary = 200;
    protected $coffee = 5;
    protected $pages = 50;
    protected $boss = false;

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

class Analyst extends Employee {
    protected $rank = 1;
    protected $basicSalary = 800;
    protected $coffee = 50;
    protected $pages = 5;
    protected $boss = false;

    function __construct($rank, $boss = false) {
        $this->rank = $rank;
        $this->boss = $boss;
    }
}


class Department {
    private $employees = [];
    private $name;

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

    public function addEmployee($profession, $amount, $rank = 1, $boss = false)
    {
        for ($i=0; $i < $amount; $i++) {
            $this->employees[] = new $profession($rank, $boss);
        }
    }

    public function getDepartmentName()
    {
        return $this->name;
    }

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

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

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

    public function getAllPages()
    {
        $result = 0;
        foreach ($this->employees as $employee)
            $result += $employee->getPages();
        return $result;
    }
}

class Company {
    public $allEmployees = 0;
    public $allCoffee = 0;
    public $allSalary = 0;
    public $allPages = 0;
    public $averageMoneyPerPages = 0;

    public $averageEmployees = 0;
    public $averageCoffee = 0;
    public $averageSalary = 0;
    public $averagePages = 0;
    public $overallMoneyPerPages = 0;

    public function __construct($departments)
    {
    }
    public function getAverageEmployees($departments){
        return $this->getAllEmployees($departments) / count($departments);
    }
    public function getAverageSalary($departments){
        return $this->getAllSalary($departments) / count($departments);
    }
    public function getAverageCoffee($departments){
        return $this->getAllCoffee($departments) / count($departments);
    }
    public function getAveragePages($departments){
        return $this->getAllPages($departments) / count($departments);
    }
    public function getAllEmployees($departments) {
        $allEmployees = 0;
        foreach ($departments as $number => $department) {
            $employeesNumber = $departments[$number]->getEmployeesNumber();
            $allEmployees += $employeesNumber;
        };
        return $allEmployees;
    }
    public function getAllCoffee($departments) {
        $allCoffee = 0;
        foreach ($departments as $number => $department) {
            $allCoffee += $departments[$number]->getAllCoffee();
         }
        return $allCoffee;
    }
    public function getAllSalary($departments) {
        $allSalary = 0;
        foreach ($departments as $number => $department) {
            $allSalary += $departments[$number]->getAllSalary();
        }
        return $allSalary;
    }
    public function getAllPages($departments) {
        $allPages = 0;
        foreach ($departments as $number => $department) {
            $allPages += $departments[$number]->getAllPages();
        }
        return $allPages;
    }
    public function getAverageMoneyPerPages($allSalary, $allPages) {
        $averageMoneyPerPages = round($allSalary / $allPages, 2);
        return $averageMoneyPerPages;
    }
    public function getAllAverageMoneyPerPages($departments) {
        $allMoneyPerPages = 0;
        foreach ($departments as $number => $department) {
            $allMoneyPerPages += $this->getAllSalary($departments) / $this->getAllPages($departments);
        }
        return round($allMoneyPerPages, 2);
    }
    
}

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

function padLeft($string, $widthOfTableCell){
    $tableCell = str_repeat(" ", $widthOfTableCell - mb_strlen($string)) . $string;
    return $tableCell;
}

function allIndex($departments) {
    $col1 = 15;
    $col2 = $col3 = $col4 = $col5 = $col6 = 12;
    $countedColumns = $col1 + $col2 + $col3 + $col4 + $col5 + $col6;
    $departmentsNumber = count($departments);
    $allEmployees = 0;
    $allSalary = 0;
    $allCoffee = 0;
    $allPages = 0;
    $averageMoneyPerPages = 0;

    echo padRight("Департамент", $col1) .
        padLeft("сотр.", $col2) .
        padLeft("тугр.", $col3) .
        padLeft("кофе", $col4) .
        padLeft("стр.", $col5) .
        padLeft("тугр./стр.", $col6) ."<br>\n";

    echo str_repeat("-", $countedColumns) ."<br>\n";

    foreach ($departments as $number => $department) {
        $departmentName = $departments[$number]->getDepartmentName();
        $employeesNumber = $departments[$number]->getEmployeesNumber();
        $allDepartmentSalary = $departments[$number]->getAllSalary();
        $allDepartmentCoffee = $departments[$number]->getAllCoffee();
        $allDepartmentPages = $departments[$number]->getAllPages();
        $moneyPerPages = round($allDepartmentSalary / $allDepartmentPages, 2);

        echo padRight($departmentName, $col1) .
            padLeft($employeesNumber, $col2) .
            padLeft($allDepartmentSalary, $col3) .
            padLeft($allDepartmentCoffee, $col4) .
            padLeft($allDepartmentPages, $col5) .
            padLeft($moneyPerPages, $col6) ."<br>\n";

        $allEmployees += $employeesNumber;
        $allSalary += $allDepartmentSalary;
        $allCoffee += $allDepartmentCoffee;
        $allPages += $allDepartmentPages;
        $averageMoneyPerPages += $moneyPerPages;
    }

}

$purchaseDepartment = new Department("Закупок");

$purchaseDepartment->addEmployee("Manager", 9);
$purchaseDepartment->addEmployee("Manager", 3, 2);
$purchaseDepartment->addEmployee("Manager", 2, 3);
$purchaseDepartment->addEmployee("MarketingSpecialist", 2, 1);
$purchaseDepartment->addEmployee("Manager", 1, 2, true);

$saleDepartment = new Department("Продаж");

$saleDepartment->addEmployee("Manager", 12);
$saleDepartment->addEmployee("MarketingSpecialist", 6);
$saleDepartment->addEmployee("Analyst", 3);
$saleDepartment->addEmployee("Analyst", 2, 2);
$saleDepartment->addEmployee("Manager", 1, 2, true);

$advertisingDepartment = new Department("Рекламы");

$advertisingDepartment->addEmployee("MarketingSpecialist", 15);
$advertisingDepartment->addEmployee("MarketingSpecialist", 10, 2);
$advertisingDepartment->addEmployee("Manager", 8);
$advertisingDepartment->addEmployee("Engineer", 2);
$advertisingDepartment->addEmployee("Manager", 1, 3, true);

$logisticsDepartment = new Department("Логистики");

$logisticsDepartment->addEmployee("Manager", 13);
$logisticsDepartment->addEmployee("Manager", 5, 2);
$logisticsDepartment->addEmployee("Engineer", 5);
$logisticsDepartment->addEmployee("Manager", 1, 1, true);

$departments = array($purchaseDepartment, $saleDepartment, $advertisingDepartment, $logisticsDepartment);

allIndex($departments);

$col1 = 15;
$col2 = $col3 = $col4 = $col5 = $col6 = 12;
$countedColumns = $col1 + $col2 + $col3 + $col4 + $col5 + $col6;

$vector = new Company($departments);

echo str_repeat("-", $countedColumns) ."<br>\n";

echo padRight("Среднее", $col1) .
    padLeft($vector->getAverageEmployees($departments), $col2) .
    padLeft($vector->getAverageSalary($departments), $col3) .
    padLeft($vector->getAverageCoffee($departments), $col4) .
    padLeft($vector->getAveragePages($departments), $col5) .
    padLeft($vector->getAverageMoneyPerPages($vector->getAllSalary($departments), $vector->getAllPages($departments)), $col6) ."<br>\n";

echo padRight("Всего", $col1) .
    padLeft($vector->getAllEmployees($departments), $col2) .
    padLeft($vector->getAllSalary($departments), $col3) .
    padLeft($vector->getAllCoffee($departments), $col4) .
    padLeft($vector->getAllPages($departments), $col5) .
    padLeft($vector->getAllAverageMoneyPerPages($departments), $col6) ."<br>\n";