/*!
	@file
	@author		Albert Semenov
	@date		10/2008
	@module
*/
#ifndef __UNITTEST_LIST_H__
#define __UNITTEST_LIST_H__

#include "MyGUI.h"
#include "Mirror_List.h"

namespace unittest
{
	class UnitTest_List
	{
	private:
		MyGUI::List* original_list;
		unittest::Mirror_List * mirror_list;
		size_t count_items;

	public:
		UnitTest_List()
		{
			original_list = MyGUI::Gui::getInstance().createWidget<MyGUI::List>("List", MyGUI::IntCoord(100, 100, 100, 100), MyGUI::Align::Default, "Main");
			mirror_list = new unittest::Mirror_List();
			count_items = 0;
		}

		~UnitTest_List()
		{
			MyGUI::WidgetManager::getInstance().destroyWidget(original_list);
			delete mirror_list;
		}

		void check()
		{
			assert(count_items == original_list->getItemCount());
			assert(original_list->getItemCount() == mirror_list->getItemCount());

			for(size_t pos=0; pos<count_items; ++pos) {
				assert(original_list->getItemNameAt(pos) == mirror_list->getItemNameAt(pos));
				assert(*original_list->getItemDataAt<size_t>(pos) == *mirror_list->getItemDataAt<size_t>(pos));
			}

			original_list->_checkAlign();
		}

		void Begin()
		{
			size_t count = original_list->getItemCount();
			if (count == 0) return;
			size_t index = ((size_t)rand() % count);
			original_list->beginToItemAt(index);

			check();
		}

		void Begin(size_t _count)
		{
			while (_count > 0) {
				Begin();
				--_count;
			}
		}

		void AddItem()
		{
			size_t item = (size_t)rand();
			mirror_list->addItem(MyGUI::utility::toString(item), item);
			original_list->addItem(MyGUI::utility::toString(item), item);
			count_items ++;

			check();
		}

		void AddItem(size_t _count)
		{
			while (_count > 0) {
				AddItem();
				--_count;
			}
		}

		void InsertItem()
		{
			size_t index = count_items == 0 ? 0 : ((size_t)rand() % count_items);
			size_t item = (size_t)rand();

			mirror_list->insertItemAt(index, MyGUI::utility::toString(item), item);
			original_list->insertItemAt(index, MyGUI::utility::toString(item), item);

			count_items ++;

			check();
		}

		void InsertItem(size_t _count)
		{
			while (_count > 0) {
				InsertItem();
				--_count;
			}
		}

		void RemoveItem()
		{
			if (count_items == 0) return;

			size_t index = count_items == 0 ? 0 : ((size_t)rand() % count_items);

			mirror_list->removeItemAt(index);
			original_list->removeItemAt(index);

			count_items --;

			check();
		}

		void RemoveItem(size_t _count)
		{
			while (_count > 0) {
				RemoveItem();
				--_count;
			}
		}

		void RemoveAllItems()
		{
			mirror_list->removeAllItems();
			original_list->removeAllItems();

			count_items = 0;
			check();
		}

		void nextFrame()
		{
			if (count_items > 100) RemoveAllItems();

			size_t index = (size_t)rand() % 4;
			size_t count = (size_t)rand() % 3;

			if (index == 0) InsertItem(count);
			else if (index == 1) AddItem(count);
			else if (index == 2) RemoveItem(count);
			else if (index == 3) Begin(count);
		}

	};

}

#endif // __UNITTEST_LIST_H__
