namespace Terminal.Gui;
/// Extension of helper to work with specific
public static class StackExtensions
{
/// Check if the stack object contains the value to find.
/// The stack object type.
/// The stack object.
/// Value to find.
/// The comparison object.
/// true If the value was found.false otherwise.
public static bool Contains (this Stack stack, T valueToFind, IEqualityComparer comparer = null)
{
comparer = comparer ?? EqualityComparer.Default;
foreach (T obj in stack)
{
if (comparer.Equals (obj, valueToFind))
{
return true;
}
}
return false;
}
/// Find all duplicates stack objects values.
/// The stack object type.
/// The stack object.
/// The comparison object.
/// The duplicates stack object.
public static Stack FindDuplicates (this Stack stack, IEqualityComparer comparer = null)
{
comparer = comparer ?? EqualityComparer.Default;
Stack dup = new ();
T [] stackArr = stack.ToArray ();
for (var i = 0; i < stackArr.Length; i++)
{
T value = stackArr [i];
for (int j = i + 1; j < stackArr.Length; j++)
{
T valueToFind = stackArr [j];
if (comparer.Equals (value, valueToFind) && !Contains (dup, valueToFind))
{
dup.Push (value);
}
}
}
return dup;
}
/// Move the first stack object value to the end.
/// The stack object type.
/// The stack object.
public static void MoveNext (this Stack stack)
{
Stack temp = new ();
T last = stack.Pop ();
while (stack.Count > 0)
{
T value = stack.Pop ();
temp.Push (value);
}
temp.Push (last);
while (temp.Count > 0)
{
stack.Push (temp.Pop ());
}
}
/// Move the last stack object value to the top.
/// The stack object type.
/// The stack object.
public static void MovePrevious (this Stack stack)
{
Stack temp = new ();
T first = default;
while (stack.Count > 0)
{
T value = stack.Pop ();
temp.Push (value);
if (stack.Count == 1)
{
first = stack.Pop ();
}
}
while (temp.Count > 0)
{
stack.Push (temp.Pop ());
}
stack.Push (first);
}
/// Move the stack object value to the index.
/// The stack object type.
/// The stack object.
/// Value to move.
/// The index where to move.
/// The comparison object.
public static void MoveTo (
this Stack stack,
T valueToMove,
int index = 0,
IEqualityComparer comparer = null
)
{
if (index < 0)
{
return;
}
comparer = comparer ?? EqualityComparer.Default;
Stack temp = new ();
var toMove = default (T);
int stackCount = stack.Count;
var count = 0;
while (stack.Count > 0)
{
T value = stack.Pop ();
if (comparer.Equals (value, valueToMove))
{
toMove = value;
break;
}
temp.Push (value);
count++;
}
var idx = 0;
while (stack.Count < stackCount)
{
if (count - idx == index)
{
stack.Push (toMove);
}
else
{
stack.Push (temp.Pop ());
}
idx++;
}
}
/// Replaces a stack object values that match with the value to replace.
/// The stack object type.
/// The stack object.
/// Value to replace.
/// Value to replace with to what matches the value to replace.
/// The comparison object.
public static void Replace (
this Stack stack,
T valueToReplace,
T valueToReplaceWith,
IEqualityComparer comparer = null
)
{
comparer = comparer ?? EqualityComparer.Default;
Stack temp = new ();
while (stack.Count > 0)
{
T value = stack.Pop ();
if (comparer.Equals (value, valueToReplace))
{
stack.Push (valueToReplaceWith);
break;
}
temp.Push (value);
}
while (temp.Count > 0)
{
stack.Push (temp.Pop ());
}
}
/// Swap two stack objects values that matches with the both values.
/// The stack object type.
/// The stack object.
/// Value to swap from.
/// Value to swap to.
/// The comparison object.
public static void Swap (
this Stack stack,
T valueToSwapFrom,
T valueToSwapTo,
IEqualityComparer comparer = null
)
{
comparer = comparer ?? EqualityComparer.Default;
int index = stack.Count - 1;
T [] stackArr = new T [stack.Count];
while (stack.Count > 0)
{
T value = stack.Pop ();
if (comparer.Equals (value, valueToSwapFrom))
{
stackArr [index] = valueToSwapTo;
}
else if (comparer.Equals (value, valueToSwapTo))
{
stackArr [index] = valueToSwapFrom;
}
else
{
stackArr [index] = value;
}
index--;
}
for (var i = 0; i < stackArr.Length; i++)
{
stack.Push (stackArr [i]);
}
}
}