private bool RemoveAtInt(int startPosition, int endPosition, out int testPosition, out MaskedTextResultHint resultHint, bool testOnly)
{
Debug.Assert(startPosition >= 0 && startPosition <= endPosition && endPosition < _testString.Length, "Out of range input value.");
// Check if we need to shift characters left to occupied the positions left by the characters being removed.
int lastAssignedPos = LastAssignedPosition;
int dstPos = FindEditPositionInRange(startPosition, endPosition, forward); // first edit position in range.
resultHint = MaskedTextResultHint.NoEffect;
if (dstPos == invalidIndex || dstPos > lastAssignedPos) // nothing to remove.
{
testPosition = startPosition;
return true;
}
testPosition = startPosition; // On remove range, testPosition remains the same as startPosition.
bool shiftNeeded = endPosition < lastAssignedPos; // last assigned position is upper.
// if there are assigned characters to be removed (could be that the range doesn't have one, in such case we may be just
// be shifting chars), the result hint is success, let's check.
if (FindAssignedEditPositionInRange(startPosition, endPosition, forward) != invalidIndex)
{
resultHint = MaskedTextResultHint.Success;
}
if (shiftNeeded)
{
// Test shifting characters.
int srcPos = FindEditPositionFrom(endPosition + 1, forward); // first position to shift left.
int shiftStart = srcPos; // cache it here so we don't have to search for it later if needed.
MaskedTextResultHint testHint;
startPosition = dstPos; // actual start position.
while (true)
{
char srcCh = _testString[srcPos];
CharDescriptor chDex = _stringDescriptor[srcPos];
// if the shifting character is the prompt and it is at an unassigned position we don't need to test it.
if (srcCh != PromptChar || chDex.IsAssigned)
{
if (!TestChar(srcCh, dstPos, out testHint))
{
resultHint = testHint;
testPosition = dstPos; // failed position.
return false;
}
}
if (srcPos == lastAssignedPos)
{
break;
}
srcPos = FindEditPositionFrom(srcPos + 1, forward);
dstPos = FindEditPositionFrom(dstPos + 1, forward);
}
// shifting characters is a resultHint == sideEffect, update hint if no characters removed (which would be hint == success).
if (MaskedTextResultHint.SideEffect > resultHint)
{
resultHint = MaskedTextResultHint.SideEffect;
}
if (testOnly)
{
return true; // test completed.
}
// test passed so shift characters.
srcPos = shiftStart;
dstPos = startPosition;
while (true)
{
char srcCh = _testString[srcPos];
CharDescriptor chDex = _stringDescriptor[srcPos];
// if the shifting character is the prompt and it is at an unassigned position we just reset the destination position.
if (srcCh == PromptChar && !chDex.IsAssigned)
{
ResetChar(dstPos);
}
else
{
SetChar(srcCh, dstPos);
ResetChar(srcPos);
}
if (srcPos == lastAssignedPos)
{
break;
}
srcPos = FindEditPositionFrom(srcPos + 1, forward);
dstPos = FindEditPositionFrom(dstPos + 1, forward);
}
// If shifting character are less than characters to remove in the range, we need to remove the remaining ones in the range;
// update startPosition and ResetString belwo will take care of that.
startPosition = dstPos + 1;
}
if (startPosition <= endPosition)
{
ResetString(startPosition, endPosition);
}
return true;
}