void AdvancedBox::calculate(const Int2& parPos, const Int2& parSize, const Int2& parHotSpot, float angleDegrees, int xTopDeformation, int xBottomDeformation)
	{
		float angleRadians = angleDegrees * MathUtils::PI / 180.0f;

		data[0] = getRotatedPoint(
			parPos.x() + parSize.width() - parHotSpot.x(), parPos.y() + parSize.height() - parHotSpot.y(),
			angleRadians,
			parPos.x()/*-1*/, parPos.y(), xBottomDeformation);

		data[1] = getRotatedPoint(
			parPos.x() - parHotSpot.x(), parPos.y() + parSize.height() - parHotSpot.y(),
			angleRadians,
			parPos.x(), parPos.y(), xBottomDeformation);

		data[2] = getRotatedPoint(
			parPos.x() - parHotSpot.x(), parPos.y() - parHotSpot.y(),
			angleRadians,
			parPos.x(), parPos.y(), xTopDeformation);

		data[3] = getRotatedPoint(
			parPos.x() + parSize.width() - parHotSpot.x(), parPos.y() - parHotSpot.y(),
			angleRadians,
			parPos.x()/*-1*/, parPos.y(), xTopDeformation);

		/*PrintValue(data[0]);
		PrintValue(data[1]);
		PrintValue(data[2]);
		PrintValue(data[3]);
		Print("");*/
	}
void EditText::draw(float fontScale)
{
	Scene2D& scene2D = Engine::instance().getScene2DMgr();

	//AssertRelease(font != NULL);
    if (isCrypted)
    {
        Int2 posRes = pos;
        for (size_t i = 0; i < text.size(); ++i)
        {
            //posx = font->drawText(color, Int2(posx,pos.y()),"*",fontScale).x();
			posRes = scene2D.drawText(NULL, "*", posRes, fontScale, color);
        }
    }
    else
    {
        //font->drawText(color, Int2(pos.x(), pos.y()),text.c_str(),fontScale);
		scene2D.drawText(NULL, text.c_str(), pos, fontScale, color);
    }

    if (isFocused)
    {
        int64_t tim = Utils::getMillisecond();

        if (tim > timeCount + 500)
        {
            timeCount = tim;
            timeIsDisplayed = !timeIsDisplayed;
        }

        if (timeIsDisplayed)
        {
            if (isCrypted)
            {
                //font->drawText(color, Int2(pos.x()+font->getWidth("*",-1,fontScale)*keypos-3,pos.y()),"|",fontScale);
				Int2 size = scene2D.getSizeText(NULL, "*", fontScale);
				scene2D.drawText(NULL, "|", Int2(pos.x()+size.width()*keypos-3,pos.y()), fontScale, color);
            }
            else
            {
				Int2 size = scene2D.getSizeText(NULL, text.c_str(), fontScale, keypos);
                //font->drawText(color, Int2(pos.x()+font->getWidth(text.c_str(),keypos,fontScale)-3,pos.y()),"|",fontScale);
				scene2D.drawText(NULL, "|", Int2(pos.x()+size.width()-3,pos.y()), fontScale, color);
            }
        }
    }
}
void AppSetup::onResizeWindow(const Int2& newSize)
{
	m_inf.windowSize = newSize;

	Float2 newSizeF = Float2((float)newSize.width(), (float)newSize.height());
	Float2 virtualSizeF = Float2((float)m_inf.virtualSize.width(), (float)m_inf.virtualSize.height());

	if (m_inf.automaticFitToWindowSize && (newSize.width() != m_inf.virtualSize.width() || newSize.height() != m_inf.virtualSize.height()))
	{
		Float2 ppp(-1.f,-1.f);
		Int2 virtualPos(-1,-1);

		float ratioW = (float)newSize.width() / (float)m_inf.virtualSize.width();
		float ratioH = (float)newSize.height() / (float)m_inf.virtualSize.height();
		if (m_inf.virtualSizeAllowRatioDeformation)
		{
			ppp = Float2(ratioW,ratioH);
			virtualPos = Int2(0,0);
		}
		else if (newSizeF.width()/newSizeF.height() > virtualSizeF.width() / virtualSizeF.height())
		{
			ppp = Float2(ratioH,ratioH);
			virtualPos = Int2((int)((newSizeF.width()-virtualSizeF.width()*ratioH)/2.f), 0);
		}
		else
		{
			ppp = Float2(ratioW,ratioW);
			virtualPos = Int2(0, (int)((newSizeF.height()-virtualSizeF.height()*ratioW)/2.f));
		}
		
		this->setPixelPerPointLowLevel(ppp, virtualPos);
	}
	else
	{
		this->setPixelPerPointLowLevel(Float2(1.f,1.f), Int2(0,0));
#if defined(USES_WINDOWS_OPENGL) || defined(USES_LINUX)
		m_openGL->setRealWindowSize(newSize);
		m_openGL->set2DMode();
#else
		// do nothing here
#endif
	}

	m_isUsingVirtualSize = (this->getPixelPerPoint() != Float2(1.f, 1.f) || this->getVirtualTopLeftCornerInWindow() != Int2(0, 0));
}
void AppSetup::manageRender()
{
	if (m_isUsingVirtualSize)
	{
		Int2 virtualPos = this->getVirtualTopLeftCornerInWindow();
		Float2 ppp = this->getPixelPerPoint();
		Int2 sizeOrtho2DWindow = this->getSizeOrtho2DWindow();

		this->setPixelPerPointLowLevel(Float2(1.f,1.f), Int2(0,0));
		
		if (m_inf.virtualSizeBorderColor.a() != 0)
		{
			if (m_inf.virtualSize.width() < sizeOrtho2DWindow.width())
			{
				Engine::instance().getScene2DMgr().drawRectangle(
					Int2(0,0), 
					Int2(virtualPos.width(), m_inf.windowSize.height()), 
					m_inf.virtualSizeBorderColor, true);
				Engine::instance().getScene2DMgr().drawRectangle(
					Int2(m_inf.windowSize.width()-virtualPos.width(), 0), 
					m_inf.windowSize,
					m_inf.virtualSizeBorderColor, true);
			}
			else if (m_inf.virtualSize.height() < sizeOrtho2DWindow.height())
			{
				Engine::instance().getScene2DMgr().drawRectangle(
					Int2(0, 0), 
					Int2(m_inf.windowSize.width(), virtualPos.height()), 
					m_inf.virtualSizeBorderColor, true);
				Engine::instance().getScene2DMgr().drawRectangle(
					Int2(0, m_inf.windowSize.height()-virtualPos.height()), 
					m_inf.windowSize,
					m_inf.virtualSizeBorderColor, true);
			}
		}
		
		this->setPixelPerPointLowLevel(ppp, virtualPos);
	}

#if defined(USES_WINDOWS_OPENGL) || defined(USES_LINUX)
	m_openGL->manageOpenGL(m_inf.windowSize);
#else

#endif
}
DesktopWindow::DesktopWindow(HINSTANCE hInstance, int nCmdShow, DesktopWindowMessageHandler* messageReceiver, bool isFullscreen, const Int2& windowSize, const std::string& windowTitle)
:m_messageReceiver(messageReceiver), m_mustBeDestroyed(false)
{
	// Register class
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
	wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(5 + 1);
	wcex.lpszMenuName = nullptr;
	wcex.lpszClassName = L"TutorialWindowClass";
	wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_APPLICATION);
	if (!RegisterClassEx(&wcex))
		Assert(false);

	// Create window
	RECT rc = { 0, 0, windowSize.width(), windowSize.height() };
	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE); ;
	HWND hwnd = CreateWindow(L"TutorialWindowClass", Utils::convertStringToWString(windowTitle).c_str(), isFullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW,
		// WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME
		CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance, nullptr);
	Assert(hwnd != nullptr);

	ShowWindow(hwnd, isFullscreen ? SW_MAXIMIZE : nCmdShow);

	// resize to take into consideration the border size
	/*RECT rcClient, rcWind;
	POINT ptDiff;
	GetClientRect(hwnd, &rcClient);
	GetWindowRect(hwnd, &rcWind);
	ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right;
	ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom;
	MoveWindow(hwnd, rcWind.left, rcWind.top, (rc.right - rc.left) + ptDiff.x, (rc.bottom - rc.top) + ptDiff.y, TRUE);*/

	m_hwnd = hwnd;

	s_hwnds[hwnd] = this;
}