/**************************************************************************
* AEarthWindow :: paintWorld - paint a view of Earth from space           *
**************************************************************************/
bool AEarthWindow :: computeWorld()
{
  const float
    xRadiusFactor[4] = {1.45, 1.55, 1.60, 1.65},
    yRadiusFactor[4] = {(0.7 - 1.0/8), (0.7 - 1.0/16),
                        (0.7 - 1.0/32), (0.7 - 1.0/64)};
  const IRectangle
    psRect(rect());

/*------------------------------------------------------------------------|
| Construct the IGRect2D space to form the background of the scene.       |
-------------------------------------------------------------------------*/

  IGPoint2D
     bottomLeftPoint(0, 0),
     bottomRightPoint(psRect.width(), 0),
     topLeftPoint(0, psRect.height()),
     topRightPoint(psRect.width(), psRect.height());

  spaceDimensions.setPoint(0, bottomLeftPoint);
  spaceDimensions.setPoint(1, bottomRightPoint);
  spaceDimensions.setPoint(2, topRightPoint);
  spaceDimensions.setPoint(3, topLeftPoint);

/*------------------------------------------------------------------------|
| Compute the dimensions for the earthArcs.                               |
-------------------------------------------------------------------------*/

  IGPoint2D centerPoint(psRect.width() / 2, -psRect.height() * 0.2);
  int xRad, yRad;
  for(int i=0;i<=atmosphereLayers;i++)
     {
        yRad = yRadiusFactor[i] * psRect.height();
        xRad = xRadiusFactor[i] * yRad;
        IGRect2D arcBoundsRect(0, 2 * yRad, 2 * xRad, 0);
        arcDimensions[i].setBounds(arcBoundsRect);
        arcDimensions[i].setCenter(centerPoint);
     }


/*------------------------------------------------------------------------|
| Call computeStars() to compuet the dimensions for the stars.            |
| Then call paintWorld() that uses all these dimensions to create the     |
| objects to be painted.                                                  |
-------------------------------------------------------------------------*/
  computeStars();
  paintWorld();
  refresh();
  return true;

} /* end AEarthWindow :: paintWorld(..) */
void AbstractGLDisplayHelper::displayDecomposePackResults(WorldPtr world, FinalDecomposeResults decomposeResult, FinalPackResults packResult)
{
	initRenderingContext(world);
	std::thread openGLThread(&AbstractGLDisplayHelper::initRenderingLoop, this);

	paintWorld(world);

	while (!_renderer->isReady())
	{
		; // Sleep TODO
	}

	_renderer->commitContext(_renderContext);
	_renderer->addInputListener(this);

	int decomposeResultsIndex = -1;
	bool isCurrentDisplayDecompose = false;

	while (true)
	{
		; // Sleep TODO

		if (_isCallbackReceived)
		{
			if (_lastCallbackKey == KEYBOARD_KEY::KEY_LEFT)
			{
				if (isCurrentDisplayDecompose)
				{
					decomposeResultsIndex--;
				}

				isCurrentDisplayDecompose = !isCurrentDisplayDecompose;
			}
			else if (_lastCallbackKey == KEYBOARD_KEY::KEY_RIGHT)
			{
				if (!isCurrentDisplayDecompose)
				{
					decomposeResultsIndex++;
				}

				isCurrentDisplayDecompose = !isCurrentDisplayDecompose;
			}
			else if (_lastCallbackKey == KEYBOARD_KEY::KEY_1)
			{
				_colorManager->changeMode(ColorMode::CONSISTENT);
			}
			else if (_lastCallbackKey == KEYBOARD_KEY::KEY_2)
			{
				_colorManager->changeMode(ColorMode::BY_INSTANCE);
			}
			else if (_lastCallbackKey == KEYBOARD_KEY::KEY_3)
			{
				_colorManager->changeMode(ColorMode::ORIGINAL);
			}
			else if (_lastCallbackKey == KEYBOARD_KEY::KEY_R)
			{
				_colorManager->regenerateColorsCache();
			}
			
			if (decomposeResultsIndex <= -1)
			{
				decomposeResultsIndex = -1;
				isCurrentDisplayDecompose = false;
			}
			else if (decomposeResultsIndex > packResult->size() - 1) {
				decomposeResultsIndex--;
				isCurrentDisplayDecompose = false;
			}

			_renderContext->clearDataBuffers();

			if ((decomposeResultsIndex == -1) || (decomposeResult->empty()))
			{
				paintWorld(world);
				string description = "World (object mask view)";
				description += decomposeResult->empty() ? ": No solutions" : "";
				_renderContext->setContentDescription(description);
			}
			else if (isCurrentDisplayDecompose)
			{
				_colorManager->resetColorsToSolution(decomposeResultsIndex, true);
				paintSingleSolution(world, decomposeResult->at(decomposeResultsIndex));

				string solutionIndex = std::to_string(decomposeResultsIndex + 1);
				string description = "Decompose solution #" + solutionIndex;
				_renderContext->setContentDescription(description);
			}
			else
			{
				_colorManager->resetColorsToSolution(decomposeResultsIndex, false);
				paintSingleSolution(world, packResult->at(decomposeResultsIndex));

				string solutionIndex = std::to_string(decomposeResultsIndex + 1);
				string description = "Packing solution #" + solutionIndex;
				_renderContext->setContentDescription(description);
			}

			_renderer->commitContext(_renderContext);

			_isCallbackReceived = false;
		}
	}

	DFPLogger::getInstance().log("Main thread quitting", DFPLogger::LogLevel::DEBUG_MODE);
}