/******************************************************************************
 JPtrArray-JString.cc

	Comparison functions for JString, for use with JPtrArray<JString>.

	Copyright © 1997 John Lindal. All rights reserved.

 ******************************************************************************/

#include <JPtrArray-JString.h>
#include <iostream.h>
#include <jAssert.h>

/******************************************************************************
 Stream operators

 ******************************************************************************/

istream&
operator>>
	(
	istream&			input,
	JPtrArray<JString>&	list
	)
{
	list.DeleteAll();

	JSize count;
	input >> count;
	if (input.eof() || input.fail())
		{
		return input;
		}

	for (JIndex i=1; i<=count; i++)
		{
		JString* s = new JString;
		assert( s != NULL );

		input >> *s;
		if (input.fail())
			{
			delete s;
			return input;
			}

		list.Append(s);
		}

	return input;
}

ostream&
operator<<
	(
	ostream&					output,
	const JPtrArray<JString>&	list
	)
{
	const JSize count = list.GetElementCount();
	output << count;

	for (JIndex i=1; i<=count; i++)
		{
		output << ' ' << *(list.NthElement(i));
		}

	return output;
}

/******************************************************************************
 JCopyStrings

	Copies the strings from list1 to list2.  This does *not* clear list2 first.

 ******************************************************************************/

void
JCopyStrings
	(
	const JPtrArray<JString>&	list1,
	JPtrArray<JString>*			list2
	)
{
	const JSize count = list1.GetElementCount();
	for (JIndex i=1; i<=count; i++)
		{
		JString* s = new JString(*(list1.NthElement(i)));
		assert( s != NULL );
		list2->Append(s);
		}
}

/******************************************************************************
 JSameStrings

	Returns kTrue if the two lists contain the same strings.
	This function does not assume that the lists are sorted.

 ******************************************************************************/

JBoolean
JSameStrings
	(
	const JPtrArray<JString>&	list1,
	const JPtrArray<JString>&	list2,
	const JBoolean				caseSensitive
	)
{
JIndex i;

	const JSize count = list1.GetElementCount();
	if (list2.GetElementCount() != count)
		{
		return kFalse;
		}
	else if (count == 0)
		{
		return kTrue;
		}

	JArray<JBoolean> matched(count);
	for (i=1; i<=count; i++)
		{
		matched.AppendElement(kFalse);
		}

	for (i=1; i<=count; i++)
		{
		const JString* s1 = list1.NthElement(i);
		JBoolean found    = kFalse;

		for (JIndex j=1; j<=count; j++)
			{
			if (!matched.GetElement(j) &&
				JStringCompare(*s1, *(list2.NthElement(j)), caseSensitive) == 0)
				{
				found = kTrue;
				matched.SetElement(j, kTrue);
				break;
				}
			}

		if (!found)
			{
			return kFalse;
			}
		}

	return kTrue;
}

/******************************************************************************
 JCompareStringsCaseSensitive

 ******************************************************************************/

JOrderedSetT::CompareResult
JCompareStringsCaseSensitive
	(
	JString* const & s1,
	JString* const & s2
	)
{
	const int r = JStringCompare(*s1, *s2, kTrue);

	if (r > 0)
		{
		return JOrderedSetT::kFirstGreaterSecond;
		}
	else if (r < 0)
		{
		return JOrderedSetT::kFirstLessSecond;
		}
	else
		{
		return JOrderedSetT::kFirstEqualSecond;
		}
}

/******************************************************************************
 JCompareStringsCaseInsensitive

 ******************************************************************************/

JOrderedSetT::CompareResult
JCompareStringsCaseInsensitive
	(
	JString* const & s1,
	JString* const & s2
	)
{
	const int r = JStringCompare(*s1, *s2, kFalse);

	if (r > 0)
		{
		return JOrderedSetT::kFirstGreaterSecond;
		}
	else if (r < 0)
		{
		return JOrderedSetT::kFirstLessSecond;
		}
	else
		{
		return JOrderedSetT::kFirstEqualSecond;
		}
}
