<?php

//mb_internal_encoding('utf-8');

abstract class Department {

    protected $depList = array();
    protected $depName;

    public function getName() {
        return $this->depName;
    }

    public function getTotalCoffee() {
        $totalCoffee = 0;
        foreach ($this->depList as $key) {
            $totalCoffee += $key->getCoffee();
        }
        return $totalCoffee;
    }

    public function getTotalSalary(){
        $totalSalary = 0;
        foreach ($this->depList as $key) {
            $totalSalary += $key->getSalary();
        }
        return $totalSalary;
    }

    public function addPeople($object){
        if (is_object($object)) {
        return array_push($this->depList, $object);
    } else return 'Ошибка';

    }

    public function getTotalPeople(){
        return count($this->depList);
    }

    public function getTotalPages(){
        $totalPages = 0;
        foreach ($this->depList as $key) {
            $totalPages += $key->getPages();
        } return $totalPages;
    }
    public function getRatio($moneh, $pages){
        if (!$pages == 0) {
        return round($moneh/$pages, 2);
    } else return 0;
    }
}

class Purchasing extends Department {
    protected $depName = "Закупок";
}

class Sales extends Department {
    protected $depName = "Продаж";
}

class Ads extends Department {
    protected $depName = "Маркетинга";
}

class Logistics extends Department {
    protected $depName = "Логистики";
}



abstract class Employee {
    
    protected $rank;  //1 - 0%, 2 - 25%, 3 - 50%
    protected $baseRate;
    protected $coffee;
    protected $isBoss = false; //Босс получает на 50% больше бабла, пьет в два раза больше кофе
    protected $reportPage;     //и не делает отчеты

    public function __construct($rank, $isBoss){
        if ($rank < 4 && $rank > 0) {
        $this->rank = $rank;
    } else $this->rank = 'Ошибка';
        if (is_bool($isBoss) === true) {
        $this->isBoss = $isBoss;
    } else $this->isBoss = 'Ошибка';
    }

    public function getSalary(){ //Была мысль сделать что-то в стиле if (isBoss) return getSalary()*1.50; но не знаю как реализовать
        if (!$this->isBoss){     //В общем получилось ТУПО
        if ($this->rank == 3) {
            return $this->baseRate*1.50;
        } else if ($this->rank == 2) {
            return $this->baseRate*1.25;
        } else return $this->baseRate;
    } else if ($this->rank == 3) {
            return $this->baseRate*1.50*1.50;
        } else if ($this->rank == 2) {
            return $this->baseRate*1.25*1.50;
        } else return $this->baseRate*1.50;
}
    public function getCoffee(){
        if (!$this->isBoss) {
        return $this->coffee;
    } else return $this->coffee*2;
    }
    public function getPages(){
        if (!$this->isBoss){
            return $this->reportPage;
        } else return 0;
    }
}

class Manager extends Employee {

    protected $baseRate = 500;
    protected $coffee = 20;
    protected $reportPage = 200;


}

class Marketer extends Employee {

    protected $baseRate = 400;
    protected $coffee = 15;
    protected $reportPage = 150;

}

class Engeneer extends Employee {

    protected $baseRate = 200;
    protected $coffee = 5;
    protected $reportPage = 50;

}

class Analytic extends Employee {

    protected $baseRate = 800;
    protected $coffee = 50;
    protected $reportPage = 5;

}


function padLeft($string, $length) {
    $spaces = $length - mb_strlen($string);
    if ($spaces > 0) {
      for ($i = 0; $i<$spaces; $i++) {
          $string = " ".$string;
      }
    }
    else {
        $string = mb_substr($string, 0, $length);
    }
    return $string;
}

function padRight($string, $length) {
    $spaces = $length - mb_strlen($string);
    if ($spaces>0) {
        for ($i=0; $i<$spaces; $i++) {
            $string .= " ";
        }
    }
    else {
        $string = mb_substr($string, 0, $length);
    }
    return $string;
}

$col1 = 20;
$col2 = 10;
$col3 = 10;
$col4 = 10;
$col5 = 10;
$col6 = 14;

$salesDep = new Sales();
$purchasingDep = new Purchasing();
$logisticsDep = new Logistics();
$adsDep = new Ads();

for ($i = 0; $i < 15; $i++) { //супер ТУПО
    if ($i < 8) $purchasingDep->addPeople(new Manager(1, false));
    if ($i < 3) $purchasingDep->addPeople(new Manager(2, false));
    if ($i < 2) $purchasingDep->addPeople(new Manager(3, false));
    if ($i < 2) $purchasingDep->addPeople(new Marketer(1, false));
    if ($i < 1) $purchasingDep->addPeople(new Manager(2, true));
    if ($i < 12) $salesDep->addPeople(new Manager(1, false));
    if ($i < 6) $salesDep->addPeople(new Marketer(1, false));
    if ($i < 3) $salesDep->addPeople(new Analytic(1, false));
    if ($i < 2) $salesDep->addPeople(new Analytic(2, false));
    if ($i < 1) $salesDep->addPeople(new Marketer(2, true));

    $adsDep->addPeople(new Marketer(1, false));
    if ($i < 10) $adsDep->addPeople(new Marketer(2, false));
    if ($i < 8) $adsDep->addPeople(new Manager(1, false));
    if ($i < 2) $adsDep->addPeople(new Engeneer(1, false));
    if ($i < 1) $adsDep->addPeople(new Marketer(3, true));

    if ($i < 13) $logisticsDep->addPeople(new Manager(1, false));
    if ($i < 5) $logisticsDep->addPeople(new Manager(2, false));
    if ($i < 5) $logisticsDep->addPeople(new Engeneer(1, false));
    if ($i < 1) $logisticsDep->addPeople(new Manager(1, true));

} 


$arrayOfDeps = array($salesDep, $purchasingDep, $adsDep, $logisticsDep);


class CountTotal {
        public $totalPeople;
        public $totalSalary; 
        public $totalCoffee;
        public $totalPages;
        public $totalRatio;
    
    function __construct($deps){
        foreach ($deps as $dep) {
            $this->totalPeople += $dep->getTotalPeople();
            $this->totalSalary += $dep->getTotalSalary();
            $this->totalCoffee += $dep->getTotalCoffee();
            $this->totalPages += $dep->getTotalPages();
            $this->totalRatio += $dep->getRatio($dep->getTotalSalary(), $dep->getTotalPages());
        }
    }
    public function getMedPeople() {
        return round($this->totalPeople/4);
    }
    public function getMedSalary() {
        return round($this->totalSalary/4);
    }
    public function getMedCoffee() {
        return round($this->totalCoffee/4);
    }
    public function getMedPages() {
        return round($this->totalPages/4);
    }
    public function getMedRatio() {
        return round($this->totalRatio/4);
    }
}

$summary = new CountTotal($arrayOfDeps);


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

foreach ($arrayOfDeps as $key) {
    echo padRight($key->getName(), $col1).
         padLeft($key->getTotalPeople(), $col2).
         padLeft($key->getTotalSalary(), $col3).
         padLeft($key->getTotalCoffee(), $col4).
         padLeft($key->getTotalPages(), $col5).
         padLeft($key->getRatio($key->getTotalSalary(), $key->getTotalPages()), $col6)."\n";
}

echo padRight("Среднее", $col1).
     padLeft($summary->getMedPeople(), $col2).
     padLeft($summary->getMedSalary(), $col3).
     padLeft($summary->getMedCoffee(), $col4).
     padLeft($summary->getMedPages(), $col5).
     padLeft($summary->getMedRatio(), $col6)."\n";
echo padRight("Всего", $col1).
     padLeft($summary->totalPeople, $col2).
     padLeft($summary->totalSalary, $col3).
     padLeft($summary->totalCoffee, $col4).
     padLeft($summary->totalPages, $col5).
     padLeft($summary->totalRatio, $col6)."\n";