#include "Mouse.h"
#include "Window.h"

Mouse::Mouse()
{
}

int Mouse::GetX()
{
	return x;
}

int Mouse::GetY()
{
	return y;
}

bool Mouse::IsLeftClicked()
{
	return isLeftClicked;
}

bool Mouse::IsRightClicked()
{
	return isRightClicked;
}

int Mouse::GetLeftClickAtX()
{
	return leftClickAtX;
}

int Mouse::GetLeftClickAtY()
{
	return leftClickAtY;
}

int Mouse::GetRightClickAtX()
{
	return rightClickAtX;
}

int Mouse::GetRightClickAtY()
{
	return rightClickAtY;
}

int Mouse::GetRightDragDeltaX()
{
	return rightDragDeltaX;
}

int Mouse::GetRightDragDeltaY()
{
	return rightDragDeltaY;
}

int Mouse::GetWheelDelta()
{
	return wheelDelta;
}

void Mouse::OnMouseMove(int newX, int newY)
{
	x = newX;
	y = newY;
	if (rightClickAtX != NULL)
	{
		rightDragDeltaX = newX - rightClickAtX;
		rightDragDeltaY = newY - rightClickAtY;
	}
	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::Move, *this));
	TrimEvents();
}

void Mouse::OnLeftClick(int newX, int newY)
{
	isLeftClicked = true;
	leftClickAtX = newX;
	leftClickAtY = newY;
	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::LClick, *this));
	TrimEvents();
}

void Mouse::OnleftRelease(int newX, int newY)
{
	isLeftClicked = false;
	leftClickAtX = NULL;
	leftClickAtY = NULL;
	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::LRelease, *this));
	TrimEvents();
}

void Mouse::OnRightClick(int newX, int newY)
{
	isRightClicked = true;
	rightClickAtX = newX;
	rightClickAtY = newY;
	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::RClick, *this));
	TrimEvents();
}

void Mouse::OnRightRelease(int newX, int newY)
{
	isRightClicked = false;
	rightClickAtX = NULL;
	rightClickAtY = NULL;
	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::RRelease, *this));
	TrimEvents();
}

void Mouse::OnWheelDelta(int x, int y, int delta)
{
	wheelDelta += delta;
	if (wheelDelta >= 2.0f * WHEEL_DELTA)
	{
		wheelDelta = 2.0f * WHEEL_DELTA;
	}
	if (wheelDelta <= -120.0f * WHEEL_DELTA)
	{
		wheelDelta = -120.0f * WHEEL_DELTA;
	}

	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::Wheel, *this));
	TrimEvents();

	// generate events for every 120
	// 默认每次达到120，执行一次滚轮事件。如果数字够大，可以执行复数次
	//if (wheelDelta >= 0.0f)
	//{
	//	//wheelDelta -= WHEEL_DELTA;
	//	OnWheelUp(x, y);
	//}
	//else
	//{
	//	//wheelDelta += WHEEL_DELTA;
	//	OnWheelDown(x, y);
	//}
}

//void Mouse::OnWheelUp(int x, int y)
//{
//	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::WheelUp, *this));
//	TrimEvents();
//}
//
//void Mouse::OnWheelDown(int x, int y)
//{
//	mouseEvents.push(Mouse::MouseEvent(Mouse::MouseEvent::Type::WheelDown, *this));
//	TrimEvents();
//}

Mouse::MouseEvent Mouse::ReadEvent()
{
	if (mouseEvents.size() > 0)
	{
		Mouse::MouseEvent mouseEvent = mouseEvents.front();
		mouseEvents.pop();
		return mouseEvent;
	}
	else
	{
		return Mouse::MouseEvent();
	}
}

void Mouse::TrimEvents()
{
	while (mouseEvents.size() > bufferSize)
	{
		mouseEvents.pop();
	}
}

bool Mouse::IsQueueEmpty()
{
	return mouseEvents.empty();
}