#include "CS_DiscoBall.h"

CS_DiscoBall::CS_DiscoBall()
{
	ani.png = L"CS_CaveStoryMod";
	ani.sprite_index = L"ls_discoball";
}

void CS_DiscoBall::Init(std::weak_ptr<Entity> self)
{
	ball_x = x;
	ball_y = y + 40;
	if (!(arg_nLayer == -1 &&
		arg_layerSpacing == -1 &&
		arg_lightSpacing == -1))
		SetLight(arg_nLayer, arg_layerSpacing, arg_lightSpacing);
	else
		SetLight(5, 48, 48);
	auto wselfLight = selfLight.lock();
	if (!wselfLight)
	{
		selfLight = wselfLight = std::make_shared<CS_DiscoBallLight>();
		wselfLight->SetRadius(5);
		wselfLight->last_x = wselfLight->x = ball_x;
		wselfLight->last_y = wselfLight->y = ball_y;
		gameFunc->SetEntity(shared_from_this(), wselfLight);
	}
	Entity::Init(self);
}

void CS_DiscoBall::Step()
{
	//旋转灯
	for (auto p : group)
	{
		for (auto& l : p.lights)
		{
			auto wl = l.lock();
			if (wl)
			{
				float radian = (rotation_counter * rotationSpeed + wl->angle) * deg2rad;
				wl->last_x = wl->x;
				wl->x = ball_x + p.r * cosf(radian);
				wl->last_y = wl->y;
				wl->y = ball_y + p.r * sinf(radian);
				wl->hide = lr != 0;
			}
		}
	}
	auto wselfLight = selfLight.lock();
	if (wselfLight)
		wselfLight->hide = lr != 0;
	rotation_counter++;
}

void CS_DiscoBall::SetState(int stateID, int lr)
{
	if (el.arg.length() && ParseInts(el.arg.c_str(), argbuff))
	{
		if (argbuff.size() >= 3)
		{
			arg_nLayer = argbuff[0];
			arg_layerSpacing = (float)argbuff[1];
			arg_lightSpacing = (float)argbuff[2];
			el.arg.clear();
		}
	}
	this->lr = lr;
	ani.image_index = lr == 0 ? 0 : 1;
}

void CS_DiscoBall::Destroy()
{
	ClearLight();
	auto wselfLight = selfLight.lock();
	if (wselfLight)
		wselfLight->Destroy();
	Entity::Destroy();
}

void CS_DiscoBall::ClearLight()
{
	for (auto& p : group)
	{
		for (auto& l : p.lights)
		{
			auto wl = l.lock();
			if (wl)
				wl->Destroy();
		}
	}	
	group.clear();
}

void CS_DiscoBall::SetLight(int nLayer, float layerSpacing, float lightSpacing)
{
	ClearLight();
	group.resize(nLayer);
	for (int i = 0; i < nLayer; i++)
	{
		auto& p = group[i];
		p.r = (i + 1) * layerSpacing;
		//计算该层可以放置的灯光数量
		int num = (int)floorf(p.r * 2 * XM_PI / lightSpacing);
		//创建灯
		for (int t = 0; t < num; t++)
		{
			auto l = std::make_shared<CS_DiscoBallLight>();
			p.lights.push_back(l);
			gameFunc->SetEntity(shared_from_this(), l);
			//给这盏灯设置它的初始角度
			l->angle = 360.0f * (t + 1) / num;
		}
	}
}

std::shared_ptr<Entity> CreateCS_DiscoBall()
{
	return std::make_shared<CS_DiscoBall>();
}
