<?php

namespace svile\sw;

use pocketmine\command\CommandSender;
use pocketmine\command\Command;

use pocketmine\Player;
use pocketmine\Server;

use pocketmine\utils\TextFormat;
use pocketmine\math\Vector3;
use pocketmine\block\Block;

        #Use this for PHP7
use pocketmine\nbt\tag\StringTag as Str;
        #Use this for PHP5
//use pocketmine\nbt\tag\String as Str;


class SWcommands
{
    /** @var SWmain */
    private $pg;

    public function __construct(SWmain $plugin)
    {
        $this->pg = $plugin;
    }

    public function onCommand(CommandSender $sender, Command $command, $label, array $args)
    {
        

        switch (strtolower(array_shift($args))):

            case 'join':
                $bestArena = null;
                $maxPlayers = -1;
                foreach ($this->pg->arenas as $arena) {
                    if ($arena->GAME_STATE == 0) {
                        $count = $arena->getSlot(true);
                        if ($count < $arena->getSlot()) {
                            if ($count > $maxPlayers) {
                                $maxPlayers = $count;
                                $bestArena = $arena;
                            }
                        }
                    }
                }
                if ($bestArena !== null) {
                    $bestArena->join($sender);
                } else {
                    $sender->sendMessage("§cNo available arenas found!");
                }
                return true;

            case 'leave':
                foreach ($this->pg->arenas as $arena) {
                    if ($arena->inArena($sender->getName())) {
                        $arena->quit($sender->getName(), true);
                        $sender->sendMessage("§cYou left the game!");
                        return true;
                    }
                }
                $sender->sendMessage("§cYou are not in a game!");
                return true;

            case 'create':
                if (!(count($args) > 0b11 && count($args) < 0b101)) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fИспользуйте: §a/sw create <Название> <Слоты> <Ожидаемое время> <Время игры>');
                    break;
                }

                $fworld = $sender->getLevel()->getFolderName();
                $world = $sender->getLevel()->getName();

                if ($sender->getServer()->getConfigString('level-name', 'world') == $world || $sender->getServer()->getDefaultLevel()->getName() == $world || $sender->getServer()->getDefaultLevel()->getFolderName() == $world) {
                    $sender->sendMessage('§8(§cОшибка§8) §fВы §cне можете §aсоздать §fарену в §eмире §fпо умолчанию!');
                    unset($fworld, $world);
                    break;
                }

                foreach ($this->pg->arenas as $aname => $arena) {
                    if ($arena->getWorld() == $world) {
                        $sender->sendMessage('§8(§cОшибка§8) §fВы §cне можете §aсоздать §f2 §aарены §fв одном и том же §eмире§f!');
                        $sender->sendMessage('§8* §e/sw list §8- §fотобразить список арен');
                        $sender->sendMessage('§8* §e/sw delete §8- §fудалить арену');
                        unset($fworld, $world);
                        break 2;
                    }
                }

                $SWname = array_shift($args);
                if (!($SWname && ctype_alpha($SWname) && strlen($SWname) < 0x10 && strlen($SWname) > 0b10)) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fВ графе §e"Название" §fуказывается название из §bлатинских §fбукв! §b[от 2 до 10]');
                    unset($fworld, $world, $SWname);
                    break;
                }

                if (array_key_exists($SWname, $this->pg->arenas)) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fАрена §a' . $SWname . ' §fуже §eсуществует§f!');
                    unset($fworld, $world, $SWname);
                    break;
                }

                $slot = array_shift($args);
                if (!($slot && is_numeric($slot) && is_int(($slot + 0)) && $slot < 0x33 && $slot > 1)) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fВ графе §e"Слоты" §fуказываются §bцелые §fчисла! §b[от 2 до 50]');
                    unset($fworld, $world, $SWname, $slot);
                    break;
                }
                $slot += 0;

                $countdown = array_shift($args);
                if (!($countdown && is_numeric($countdown) && is_int(($countdown + 0)) && $countdown > 0b1001 && $countdown < 0x12d)) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fВ графе §e"Ожидаемое время" §fуказываются §bцелые §fчисла! §e(от 5 до 300)');
                    unset($fworld, $world, $SWname, $slot, $countdown);
                    break;
                }
                $countdown += 0;

                $maxtime = array_shift($args);
                if (!($maxtime && is_numeric($maxtime) && is_int(($maxtime + 0)) && $maxtime > 0x12b && $maxtime < 0x259)) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fВ графе §e"Время игры" §fуказываются §bцелые §fчисла! §b(от 300 до 600)');
                    unset($fworld, $world, $SWname, $slot, $countdown, $maxtime);
                    break;
                }
                $maxtime += 0;

                if ($fworld == $world) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fСоздавайте §aарену §fв мире! §c(Кроме мира по умолчанию)');
                } else {
                    $sender->sendMessage('§8(§cОшибка§8) §fНе удалось §aсоздать §fарену!');
                    $provider = $sender->getLevel()->getProvider();
                    if ($provider instanceof \pocketmine\level\format\generic\BaseLevelProvider) {
                        $provider->getLevelData()->LevelName = new Str('LevelName', $fworld);
                        $provider->saveLevelData();
                    }
                    unset($fworld, $world, $SWname, $slot, $countdown, $maxtime);
                    break;
                }

                $provider = $sender->getLevel()->getProvider();
                if ($this->pg->configs['world.generator.air'] && $provider instanceof \pocketmine\level\format\generic\BaseLevelProvider) {
                    $provider->getLevelData()->generatorName = new Str('generatorName', 'flat');
                    $provider->getLevelData()->generatorOptions = new Str('generatorOptions', '0;0;0');
                    $provider->saveLevelData();
                }

                $sender->sendMessage('§8(§bSky§fWars§8) §fСоздается §eрезервная копия §fмира! §aТелепортируйтесь §fна спавн!');

                //This is the "fake void"
                $last = 0x80;
                foreach ($sender->getLevel()->getChunks() as $chunk) {
                    for ($x = 0; $x < 0x10; $x++) {
                        for ($z = 0; $z < 0x10; $z++) {
                            for ($y = 0; $y < 0x7f; $y++) {
                                $block = $chunk->getBlockId($x, $y, $z);
                                if ($block !== 0 && $last > $y) {
                                    $last = $y;
                                    break;
                                }
                            }
                        }
                    }
                }
                $void = ($last - 1);

                $sender->teleport($sender->getServer()->getDefaultLevel()->getSpawnLocation());
                foreach ($sender->getServer()->getLevelByName($world)->getPlayers() as $p)
                    $p->close('', '§a» §fRejoin §a«');
                $sender->getServer()->unloadLevel($sender->getServer()->getLevelByName($world));

                //From here @vars are: $SWname , $slot , $world . Now i'm going to Zip the world and make a new arena
                // { ZIP
                $path = realpath($sender->getServer()->getDataPath() . 'worlds/' . $world);
                $zip = new \ZipArchive;
                @mkdir($this->pg->getDataFolder() . 'arenas/' . $SWname, 0755);
                $zip->open($this->pg->getDataFolder() . 'arenas/' . $SWname . '/' . $world . '.zip', $zip::CREATE | $zip::OVERWRITE);
                $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::LEAVES_ONLY);
                foreach ($files as $nu => $file) {
                    if (!$file->isDir()) {
                        $relativePath = $world . '/' . substr($file, strlen($path) + 1);
                        $zip->addFile($file, $relativePath);
                    }
                }
                $zip->close();
                $sender->getServer()->loadLevel($world);
                unset($zip, $path, $files);
                // ENDZIP }

                //SWarena object
                $this->pg->arenas[$SWname] = new SWarena($this->pg, $SWname, $slot, $world, $countdown, $maxtime, $void);
                $sender->sendMessage('§8(§bSky§fWars§8) §fАрена §e' . $SWname . ' §fуспешно §aсоздана§f! Установите точки §eвозраждения §fна арене: §a/sw setspawn [Слот]');
                unset($SWname, $slot, $world, $countdown, $maxtime, $void, $provider);
                break;

            case 'setspawn':
                if (count($args) != 1) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fИспользуйте: §a/sw setspawn <Слот>');
                    break;
                }

                $SWname = '';
                foreach ($this->pg->arenas as $name => $arena) {
                    if ($arena->getWorld() == $sender->getLevel()->getName()) {
                        $SWname = $name;
                        break;
                    }
                }
                if (!($SWname && ctype_alpha($SWname) && strlen($SWname) < 0x10 && strlen($SWname) > 0b10 && array_key_exists($SWname, $this->pg->arenas))) {
                    $sender->sendMessage('§8(§cОшибка§8) §fАрена в §eэтом §fмире §cне найдена§f!');
                    unset($SWname);
                    break;
                }

                $slot = array_shift($args);
                if (!($slot && is_numeric($slot) && is_int(($slot + 0)) && $slot < 0x33 && $slot > 0)) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fВ графе §e"Слоты" §fможно создать §eточку §fвозраждения§f! §b(от 2 до 50)');
                    unset($SWname, $slot);
                    break;
                }
                $slot += 0;

                if ($sender->getLevel()->getName() == $this->pg->arenas[$SWname]->getWorld()) {
                    if ($this->pg->arenas[$SWname]->setSpawn(false, $sender, $slot)) {
                        $sender->sendMessage('§8(§bSky§fWars§8) §fСоздан §eспавн §b' . $slot . ' §fна арене: §d' . $SWname . '§f!');
                        if ($this->pg->arenas[$SWname]->setSpawn(true, ''))
                            $sender->sendMessage('§8(§bSky§fWars§8) §fСозданы все точки §eпоявления§f, §cтелепортируйтесь §fна спавн и создайте §aтабличку§f!');
                    }
                }
                break;

            case 'list':
                if (count($this->pg->arenas) > 0) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fСписок созданных арен:');
                    foreach ($this->pg->arenas as $key => $val) {
                        $sender->sendMessage('§7* §fАрена §e' . $key . ' §b[' . $val->getSlot(true) . '/' . $val->getSlot() . ']');
                    }
                } else {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fАрена §cне найдена§f! Создать арену: §a/sw create');
                }
                break;

            case 'delete':
                if (count($args) != 1) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fИспользуйте: §a/sw delete <Арена>');
                    break;
                }

                $SWname = array_shift($args);
                if (!($SWname && ctype_alpha($SWname) && strlen($SWname) < 0x10 && strlen($SWname) > 0b10 && array_key_exists($SWname, $this->pg->arenas))) {
                    $sender->sendMessage('§8(§cОшибка§8) §fАрена §cне найдена§f!');
                    unset($SWname);
                    break;
                }

                if (!(is_dir($this->pg->getDataFolder() . 'arenas/' . $SWname) && is_file($this->pg->getDataFolder() . 'arenas/' . $SWname . '/settings.yml'))) {
                    $sender->sendMessage('§8(§cОшибка§8) §fАрена §cне найдена§f!');
                    unset($SWname);
                    break;
                }

                $sender->sendMessage('§8(§bSky§fWars§8) §fПодождите! Это §aможет §fзанять немного §eвремени§f!');
                $this->pg->arenas[$SWname]->stop();
                foreach ($this->pg->signs as $loc => $name) {
                    if ($SWname == $name) {
                        $ex = explode(':', $loc);
                        if ($sender->getServer()->loadLevel($ex[0b11])) {
                            $block = $sender->getServer()->getLevelByName($ex[0b11])->getBlock(new Vector3($ex[0], $ex[1], $ex[0b10]));
                            if ($block->getId() == 0x3f || $block->getId() == 0x44)
                                $sender->getServer()->getLevelByName($ex[0b11])->setBlock((new Vector3($ex[0], $ex[1], $ex[0b10])), Block::get(0));
                        }
                    }
                }
                $this->pg->setSign($SWname, 0, 0, 0, 'world', true, false);
                unset($this->pg->arenas[$SWname]);

                foreach (scandir($this->pg->getDataFolder() . 'arenas/' . $SWname) as $file) {
                    if ($file != '.' && $file != '..' && is_file($this->pg->getDataFolder() . 'arenas/' . $SWname . '/' . $file)) {
                        @unlink($this->pg->getDataFolder() . 'arenas/' . $SWname . '/' . $file);
                    }
                }
                @rmdir($this->pg->getDataFolder() . 'arenas/' . $SWname);
                $sender->sendMessage('§8(§bSky§fWars§8) §fАрена §a' . $SWname . ' §fуспешно §cудалена§f!');
                unset($SWname, $loc, $name, $ex, $block);
                break;


            case 'signdelete':
                if (count($args) != 1) {
                    $sender->sendMessage('§8(§bSky§fWars§8) §fИспользуйте: §a/sw signdelete <Арена • All>');
                    break;
                }

                $SWname = array_shift($args);
                if (!($SWname && ctype_alpha($SWname) && strlen($SWname) < 0x10 && strlen($SWname) > 0b10 && array_key_exists($SWname, $this->pg->arenas))) {
                    if ($SWname == 'all') {
                        //Deleting SW signs blocks
                        foreach ($this->pg->signs as $loc => $name) {
                            $ex = explode(':', $loc);
                            if ($sender->getServer()->loadLevel($ex[0b11])) {
                                $block = $sender->getServer()->getLevelByName($ex[0b11])->getBlock(new Vector3($ex[0], $ex[1], $ex[0b10]));
                                if ($block->getId() == 0x3f || $block->getId() == 0x44)
                                    $sender->getServer()->getLevelByName($ex[0b11])->setBlock((new Vector3($ex[0], $ex[1], $ex[0b10])), Block::get(0));
                            }
                        }
                        //Deleting signs from db & array
                        $this->pg->setSign($SWname, 0, 0, 0, 'world', true);
                        $sender->sendMessage('§8(§bSky§fWars§8) Все §aтаблички §bSky§fWars §cудалены§f!');
                        unset($SWname, $loc, $name, $ex, $block);
                    } else {
                        $sender->sendMessage('§8(§bSky§fWars§8) §fАрена §cне найдена§f!');
                        unset($SWname);
                    }
                    break;
                }
                foreach ($this->pg->signs as $loc => $name) {
                    if ($SWname == $name) {
                        $ex = explode(':', $loc);
                        if ($sender->getServer()->loadLevel($ex[0b11])) {
                            $block = $sender->getServer()->getLevelByName($ex[0b11])->getBlock(new Vector3($ex[0], $ex[1], $ex[0b10]));
                            if ($block->getId() == 0x3f || $block->getId() == 0x44)
                                $sender->getServer()->getLevelByName($ex[0b11])->setBlock((new Vector3($ex[0], $ex[1], $ex[0b10])), Block::get(0));
                        }
                    }
                }
                $this->pg->setSign($SWname, 0, 0, 0, 'world', true, false);
                $sender->sendMessage('§8(§bSky§fWars§8) §fТабличка арены §a' . $SWname . " §fуспешно §cудалена§f!");
                unset($SWname, $loc, $name, $ex, $block);
                break;


            default:
                $sender->sendMessage('§8(§bSky§fWars§8) §fИспользуйте: §a/sw <create/setspawn/list/delete/signdelete>');
                break;


        endswitch;
        return true;
    }
}