/*-------------------------------------------------------------------------
 * drawElements Base Portability Library
 * -------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Basic mathematical operations.
 *//*--------------------------------------------------------------------*/

#include "deMath.h"
#include "deInt32.h"

#if (DE_COMPILER == DE_COMPILER_MSC)
#	include <float.h>
#endif

#if (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
#	include <fenv.h>
#endif

deRoundingMode deGetRoundingMode (void)
{
#if (DE_COMPILER == DE_COMPILER_MSC)
	unsigned int status = 0;
	int ret;

	ret = _controlfp_s(&status, 0, 0);
	DE_ASSERT(ret == 0);

	switch (status & _MCW_RC)
	{
		case _RC_CHOP:	return DE_ROUNDINGMODE_TO_ZERO;
		case _RC_UP:	return DE_ROUNDINGMODE_TO_POSITIVE_INF;
		case _RC_DOWN:	return DE_ROUNDINGMODE_TO_NEGATIVE_INF;
		case _RC_NEAR:	return DE_ROUNDINGMODE_TO_NEAREST_EVEN;
		default:		return DE_ROUNDINGMODE_LAST;
	}
#elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
	int mode = fegetround();
	switch (mode)
	{
		case FE_TOWARDZERO:	return DE_ROUNDINGMODE_TO_ZERO;
		case FE_UPWARD:		return DE_ROUNDINGMODE_TO_POSITIVE_INF;
		case FE_DOWNWARD:	return DE_ROUNDINGMODE_TO_NEGATIVE_INF;
		case FE_TONEAREST:	return DE_ROUNDINGMODE_TO_NEAREST_EVEN;
		default:			return DE_ROUNDINGMODE_LAST;
	}
#else
#	error Implement deGetRoundingMode().
#endif
}

deBool deSetRoundingMode (deRoundingMode mode)
{
#if (DE_COMPILER == DE_COMPILER_MSC)
	unsigned int flag = 0;
	unsigned int oldState;
	int ret;

	switch (mode)
	{
		case DE_ROUNDINGMODE_TO_ZERO:			flag = _RC_CHOP;	break;
		case DE_ROUNDINGMODE_TO_POSITIVE_INF:	flag = _RC_UP;		break;
		case DE_ROUNDINGMODE_TO_NEGATIVE_INF:	flag = _RC_DOWN;	break;
		case DE_ROUNDINGMODE_TO_NEAREST_EVEN:	flag = _RC_NEAR;	break;
		default:
			DE_ASSERT(DE_FALSE);
	}

	ret = _controlfp_s(&oldState, flag, _MCW_RC);
	return ret == 0;
#elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
	int flag = 0;
	int ret;

	switch (mode)
	{
		case DE_ROUNDINGMODE_TO_ZERO:			flag = FE_TOWARDZERO;	break;
		case DE_ROUNDINGMODE_TO_POSITIVE_INF:	flag = FE_UPWARD;		break;
		case DE_ROUNDINGMODE_TO_NEGATIVE_INF:	flag = FE_DOWNWARD;		break;
		case DE_ROUNDINGMODE_TO_NEAREST_EVEN:	flag = FE_TONEAREST;	break;
		default:
			DE_ASSERT(DE_FALSE);
	}

	ret = fesetround(flag);
	return ret == 0;
#else
#	error Implement deSetRoundingMode().
#endif
}

double deFractExp (double x, int* exponent)
{
	if (deIsInf(x))
	{
		*exponent = 0;
		return x;
	}
	else
	{
		int		tmpExp	= 0;
		double	fract	= frexp(x, &tmpExp);
		*exponent = tmpExp - 1;
		return fract * 2.0;
	}
}

/* We could use frexpf, if available. */
float deFloatFractExp (float x, int* exponent)
{
	return (float)deFractExp(x, exponent);
}

double deRoundEven (double a)
{
	double integer;
	double fract = modf(a, &integer);
	if (fabs(fract) == 0.5)
		return 2.0 * deRound(a / 2.0);
	return deRound(a);
}

float deInt32ToFloatRoundToNegInf (deInt32 x)
{
	/* \note Sign bit is separate so the range is symmetric */
	if (x >= -0xFFFFFF && x <= 0xFFFFFF)
	{
		/* 24 bits are representable (23 mantissa + 1 implicit). */
		return (float)x;
	}
	else if (x != -0x7FFFFFFF - 1)
	{
		/* we are losing bits */
		const int		exponent	= 31 - deClz32((deUint32)deAbs32(x));
		const int		numLostBits	= exponent - 23;
		const deUint32	lostMask	= deBitMask32(0, numLostBits);

		DE_ASSERT(numLostBits > 0);

		if (x > 0)
		{
			/* Mask out lost bits to floor to a representable value */
			return (float)(deInt32)(~lostMask & (deUint32)x);
		}
		else if ((lostMask & (deUint32)-x) == 0u)
		{
			/* this was a representable value */
			DE_ASSERT( (deInt32)(float)x == x );
			return (float)x;
		}
		else
		{
			/* not representable, choose the next lower */
			const float nearestHigher	= (float)-(deInt32)(~lostMask & (deUint32)-x);
			const float oneUlp			= (float)(1u << (deUint32)numLostBits);
			const float nearestLower	= nearestHigher - oneUlp;

			/* check sanity */
			DE_ASSERT((deInt32)(float)nearestHigher > (deInt32)(float)nearestLower);

			return nearestLower;
		}
	}
	else
		return -(float)0x80000000u;
}

float deInt32ToFloatRoundToPosInf (deInt32 x)
{
	if (x == -0x7FFFFFFF - 1)
		return -(float)0x80000000u;
	else
		return -deInt32ToFloatRoundToNegInf(-x);
}
