<?php

namespace bedwars\entity\api;

use pocketmine\network\protocol\AddPlayerPacket;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent;

use pocketmine\level\Position;

use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\IntTag;

use pocketmine\Player;

use pocketmine\entity\Human;
use pocketmine\item\Item;

class Line extends Human {

	/**
	* @param FullChunk $chunk
	* @param int 	   $key
	* @param string    $text
	* @param float     $x
	* @param float     $y
	* @param float     $z 
	*/
	public static function createLine($chunk, $key, $text, $ownId, $x, $y, $z) {
		$nbt = new CompoundTag("", []);
		$nbt->Pos = new ListTag("Pos", [
			new DoubleTag(0, $x),
			new DoubleTag(1, $y),
			new DoubleTag(2, $z)
		]);
		$nbt->Rotation = new ListTag("Rotation", [
			new FloatTag(0, 0),
			new FloatTag(1, 0)
		]);
		$nbt->Motion = new ListTag("Motion", [
			new DoubleTag(0, 0),
			new DoubleTag(1, 0),
			new DoubleTag(2, 0)
		]);
		$nbt->Health = new ShortTag("Health", 1);
		$nbt->CustomName = new StringTag("CustomName", $text);
		$nbt->CustomNameVisible = new IntTag("CustomName", 1);
		$nbt->OwnId = new IntTag("OwnId", $ownId);
		$nbt->Key = new IntTag("Key", $key);
		
		$line = new Line($chunk, $nbt);
		return $line;
	}

	public function getOwnId() : int {
		return $this->namedtag["OwnId"];
	}

	/**
	 * @param float             $damage
	 * @param EntityDamageEvent $source
	 *
	 * @return bool
	 */
	public function attack($damage, EntityDamageEvent $source) {
		$ownId = $this->getOwnId();
		$entity = $this->level->getEntity($ownId);

		if (($entity instanceof HumanAPI) or ($entity instanceof EntityAPI)) {
			$entity->attack($damage, $source);
		}
	}
	
	public function onUpdate($currentTick) {
		if ($this->closed) {
			return false;
		}
		$ownId = $this->getOwnId();
		$entity = $this->level->getEntity($ownId);
		if (($entity instanceof HumanAPI) or ($entity instanceof EntityAPI)) {
			$parent = $entity->namedtag->Parent;
			$isset = false;

			foreach ($parent as $id) {
				if ($id == $this->id) {
					$isset = true;
					break;
				}
			}
			if ($isset === false) {
				$this->close();
			}
		} else {
			$this->close();
			return false;
		}
		return parent::onUpdate($currentTick);
	}

	/**
	* @param Player $player
	*/
	public function spawnTo(Player $player) {
		if ($player !== $this and !isset($this->hasSpawned[$player->getLoaderId()])) {
			$this->hasSpawned[$player->getLoaderId()] = $player;

			$pk = new AddPlayerPacket();
			$pk->uuid = $this->getUniqueId();
			$pk->username = $this->getName();
			$pk->eid = $this->getId();
			$pk->x = $this->x;
			$pk->y = $this->y;
			$pk->z = $this->z;
			$pk->speedX = $this->motionX;
			$pk->speedY = $this->motionY;
			$pk->speedZ = $this->motionZ;
			$pk->yaw = $this->yaw; 
			$pk->pitch = $this->pitch;
			$pk->item = $this->getInventory()->getItemInHand();
			$pk->metadata = array (
				self::DATA_FLAGS => array (self::DATA_TYPE_BYTE, 1 << self::DATA_FLAG_INVISIBLE),
				self::DATA_NAMETAG => [self::DATA_TYPE_STRING, $this->getDataProperty(2)],
				self::DATA_SHOW_NAMETAG => [self::DATA_TYPE_BYTE, 1],
				self::DATA_NO_AI => array (self::DATA_TYPE_BYTE, 1),
				self::DATA_LEAD_HOLDER => array (self::DATA_TYPE_LONG, -1),
				self::DATA_LEAD => array (self::DATA_TYPE_BYTE, 0)
            );
			$player->dataPacket($pk);

			$this->sendLinkedData();

			$this->inventory->sendArmorContents($player);
		}
	}
}