//def mQRand = QRand:new(0.25, 0.5, 0.75, 0.1);

class QRand(...)
{
	def mUpdateCnt = 0;
	
	def mWeights = {};
	def mLastHitUpdate = {};
	def mPrevLastHitUpdate = {};
	def mCurSway = {};
	def mLastIndex = -1;
	
	SetWeights(unpack(arg));
}

function QRand:SetWeights(...)
{
	if (arg.n == 1)
	{
		mWeights[0] = 1.0 - arg[0];
		mWeights[1] = arg[0];
	}
	else
	{
		local aTotal = 0.0;
		for (anArgNum < arg.n)
		{
			mWeights[anArgNum] = arg[anArgNum];
			aTotal += mWeights[anArgNum];
		}
		
		for (aWeightNum < *mWeights)
			mWeights[aWeightNum] /= aTotal;
	}
	
	for (i = *mLastHitUpdate, *mWeights-1, 1)
	{
		mLastHitUpdate[i] = 0;
		mPrevLastHitUpdate[i] = 0;
	}
}

function QRand:Next()
{
	mUpdateCnt++;

	//local aStr = "";
	local aTotalWeight = 0.0;
	for (aResultNum,aWeight in mWeights)
	{
		if (aWeight != 0)
		{
			local anAvgLength = 1.0 / aWeight;
			local aPctOff = 1.0 + (((mUpdateCnt - mLastHitUpdate[aResultNum]) - anAvgLength) / anAvgLength);
			local aPrevPctOff = 1.0 + (((mUpdateCnt - mPrevLastHitUpdate[aResultNum]) - anAvgLength*2) / (anAvgLength*2));
			
			local aSway = aWeight * math.max(math.min(aPctOff*0.75 + aPrevPctOff*0.25, 3.0), 0.333);
			//aSway = aWeight; // Comment this in to get a normal random number generator
			mCurSway[aResultNum] = aSway;
			aTotalWeight += aSway;
			//aStr = aStr .. aSway .. " ";
		}
		else
			mCurSway[aResultNum] = 0;
	}
		
	
	
	local aRand = math.random() * aTotalWeight;
	local anIdx = 0;
	while (aRand > mCurSway[anIdx])
	{
		aRand -= mCurSway[anIdx];
		anIdx++;
	}
	
	mPrevLastHitUpdate[anIdx] = mLastHitUpdate[anIdx];
	mLastHitUpdate[anIdx] = mUpdateCnt;
	
	mLastIndex = anIdx;
	return anIdx;
}
	
