#include <cxxtest/TestSuite.h>
#include <algorithm>
#include "../vidmode.h"

class TestVidmode : public CxxTest::TestSuite
{                                            
	public:
		void test_str() {
			VidMode v(0, 123,456,789,"foo",NULL);
			TS_ASSERT_EQUALS(v.str(), "123x456@789");
		}
};

class TestVidmodeParse : public CxxTest::TestSuite
{                                            
	public:
		screen_list_t screens;
		void setUp() { screens.clear(); }

		void test_parse_mode() {
			int w,h,r;
			TS_ASSERT_EQUALS(parse_mode(w,h,r,"123x456@789"), 0);
			TS_ASSERT_EQUALS(w, 123);
			TS_ASSERT_EQUALS(h, 456);
			TS_ASSERT_EQUALS(r, 789);
		}

		void test_parse_arg() {
			int w,h,r;
			TS_ASSERT_EQUALS(parse_arg(screens,w,h,r,"0:123x456@789",1, 0), 0);
			TS_ASSERT_EQUALS(w, 123);
			TS_ASSERT_EQUALS(h, 456);
			TS_ASSERT_EQUALS(r, 789);
			TS_ASSERT_EQUALS(screens.size(), 1);
			TS_ASSERT_EQUALS(screens.front(), 0);
		}
		void test_parse_arg_defscreen() {
			int w,h,r;
			TS_ASSERT_EQUALS(parse_arg(screens,w,h,r,"123x456@789",3, 0), 0);
			TS_ASSERT_EQUALS(w, 123);
			TS_ASSERT_EQUALS(h, 456);
			TS_ASSERT_EQUALS(r, 789);
			TS_ASSERT_EQUALS(screens.size(), 1);
			TS_ASSERT_EQUALS(screens.front(), 0);
		}
		void test_parse_arg_defscreen2() {
			int w,h,r;
			TS_ASSERT_EQUALS(parse_arg(screens,w,h,r,"123x456@789",3, 2), 0);
			TS_ASSERT_EQUALS(w, 123);
			TS_ASSERT_EQUALS(h, 456);
			TS_ASSERT_EQUALS(r, 789);
			TS_ASSERT_EQUALS(screens.size(), 1);
			TS_ASSERT_EQUALS(screens.front(), 2);
		}
		void test_parse_arg_curscreen() {
			int w,h,r;
			TS_ASSERT_EQUALS(parse_arg(screens,w,h,r,"cur:124x457@790",3, 0), 0);
			TS_ASSERT_EQUALS(w, 124);
			TS_ASSERT_EQUALS(h, 457);
			TS_ASSERT_EQUALS(r, 790);
			TS_ASSERT_EQUALS(screens.size(), 1);
			TS_ASSERT_EQUALS(screens.front(), 0);
		}
		void test_parse_arg_curscreen2() {
			int w,h,r;
			TS_ASSERT_EQUALS(parse_arg(screens,w,h,r,"cur:122x455@788",3, 2), 0);
			TS_ASSERT_EQUALS(w, 122);
			TS_ASSERT_EQUALS(h, 455);
			TS_ASSERT_EQUALS(r, 788);
			TS_ASSERT_EQUALS(screens.size(), 1);
			TS_ASSERT_EQUALS(screens.front(), 2);
		}
		void test_parse_arg_allscreens() {
			int w,h,r;
			TS_ASSERT_EQUALS(parse_arg(screens,w,h,r,"all:9123x8456@6789",3, 0), 0);
			TS_ASSERT_EQUALS(w, 9123);
			TS_ASSERT_EQUALS(h, 8456);
			TS_ASSERT_EQUALS(r, 6789);
			TS_ASSERT_EQUALS(screens.size(), 3);
			TS_ASSERT_EQUALS(screens.front(), 0);
			TS_ASSERT_EQUALS(screens[1], 1);
			TS_ASSERT_EQUALS(screens[2], 2);
		}

};

class TestVidmodeParseArgModes : public CxxTest::TestSuite
{                                            
	public:
		screen_mode_list_t amodes;
		screen_mode_list_t modes;
		void setUp() { 
			modes.clear(); amodes.clear();
			modes.push_back(mode_list_t());
			amodes.push_back(mode_list_t());
			modes.push_back(mode_list_t());
			amodes.push_back(mode_list_t());
			amodes[0].push_back(new VidMode(1, 640, 480, 70, "4", (void*)0));
			amodes[0].push_back(new VidMode(0, 800, 600, 60, "up", (void*)1));
			amodes[0].push_back(new VidMode(0, 640, 480, 100, "u", (void*)2));
			amodes[0].push_back(new VidMode(0, 320, 200, 65, "5b7", (void*)3));
			amodes[0].push_back(new VidMode(0, 800, 600, 75, "e", (void*)4));
			amodes[0].push_back(new VidMode(0, 640, 480, 50, "x", (void*)5));

			amodes[1].push_back(new VidMode(0, 456, 625, 76, "au", (void*)10));
			amodes[1].push_back(new VidMode(1, 546, 355, 96, "8b", (void*)11));
			amodes[1].push_back(new VidMode(0, 1546, 955, 76, "eu", (void*)12));
			amodes[1].push_back(new VidMode(0, 640, 480, 74, "4", (void*)13));
			amodes[1].push_back(new VidMode(0, 1546, 955, 77, "exu", (void*)14));
		}

		void test_parse_arg_modes() {
			char *args[]={"640x480"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 1);
			TS_ASSERT_EQUALS(modes[0][0], amodes[0][2]);
			TS_ASSERT_EQUALS(modes[1].size(), 0);
		}
		void test_parse_arg_modes2() {
			char *args[]={"640x480@50"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 1);
			TS_ASSERT_EQUALS(modes[0][0], amodes[0][5]);
			TS_ASSERT_EQUALS(modes[1].size(), 0);
		}
		void test_parse_arg_modes3() {
			char *args[]={"640x480"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 1), 0);
			TS_ASSERT_EQUALS(modes[1].size(), 1);
			TS_ASSERT_EQUALS(modes[1][0], amodes[1][3]);
			TS_ASSERT_EQUALS(modes[0].size(), 0);
		}
		void test_parse_arg_modes_max() {
			char *args[]={"max"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 1);
			TS_ASSERT_EQUALS(modes[0][0], amodes[0][4]);
			TS_ASSERT_EQUALS(modes[1].size(), 0);
		}
		void test_parse_arg_modes_s1_max() {
			char *args[]={"1:max"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 0);
			TS_ASSERT_EQUALS(modes[1].size(), 1);
			TS_ASSERT_EQUALS(modes[1][0], amodes[1][4]);
		}
		void test_parse_arg_modes_cur_max() {
			char *args[]={"cur:max"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 1), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 0);
			TS_ASSERT_EQUALS(modes[1].size(), 1);
			TS_ASSERT_EQUALS(modes[1][0], amodes[1][4]);
		}
		void test_parse_arg_modes_all_max() {
			char *args[]={"all:max"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 1);
			TS_ASSERT_EQUALS(modes[0][0], amodes[0][4]);
			TS_ASSERT_EQUALS(modes[1].size(), 1);
			TS_ASSERT_EQUALS(modes[1][0], amodes[1][4]);
		}
		void test_parse_arg_modes_all_1() {
			char *args[]={"all:640x480"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 1);
			TS_ASSERT_EQUALS(modes[0][0], amodes[0][2]);
			TS_ASSERT_EQUALS(modes[1].size(), 1);
			TS_ASSERT_EQUALS(modes[1][0], amodes[1][3]);
		}
		void test_parse_arg_modes_all_1errrate() {
			char *args[]={"all:640x480@74"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 1);
			TS_ASSERT_EQUALS(modes[0].size(), 0);
			TS_ASSERT_EQUALS(modes[1].size(), 1);
			TS_ASSERT_EQUALS(modes[1][0], amodes[1][3]);
		}
		void test_parse_arg_modes_all_err() {
			char *args[]={"all:640x479","all:639x480"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+2, amodes, 0), 4);
			TS_ASSERT_EQUALS(modes[0].size(), 0);
			TS_ASSERT_EQUALS(modes[1].size(), 0);
		}
		void test_parse_arg_modes_all_err2() {
			char *args[]={"all:640x479","all:639x480","0:320x200","1:456x625","0:234x38"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+5, amodes, 0), 5);
			TS_ASSERT_EQUALS(modes[0].size(), 1);
			TS_ASSERT_EQUALS(modes[0][0], amodes[0][3]);
			TS_ASSERT_EQUALS(modes[1].size(), 1);
			TS_ASSERT_EQUALS(modes[1][0], amodes[1][0]);
		}
		void test_parse_arg_modes_all_best() {
			char *args[]={"all:best"};
			TS_ASSERT_EQUALS(parse_arg_modes(modes, args, args+1, amodes, 0), 0);
			TS_ASSERT_EQUALS(modes[0].size(), 3);
			TS_ASSERT(find(modes[0].begin(),modes[0].end(),amodes[0][5])==modes[0].end());
			TS_ASSERT(find(modes[0].begin(),modes[0].end(),amodes[0][4])!=modes[0].end());
			TS_ASSERT(find(modes[0].begin(),modes[0].end(),amodes[0][3])!=modes[0].end());
			TS_ASSERT(find(modes[0].begin(),modes[0].end(),amodes[0][2])!=modes[0].end());
			TS_ASSERT(find(modes[0].begin(),modes[0].end(),amodes[0][1])==modes[0].end());
			TS_ASSERT(find(modes[0].begin(),modes[0].end(),amodes[0][0])==modes[0].end());
			TS_ASSERT_EQUALS(modes[1].size(), 4);
			TS_ASSERT(find(modes[1].begin(),modes[1].end(),amodes[1][0])!=modes[1].end());
			TS_ASSERT(find(modes[1].begin(),modes[1].end(),amodes[1][1])!=modes[1].end());
			TS_ASSERT(find(modes[1].begin(),modes[1].end(),amodes[1][2])==modes[1].end());
			TS_ASSERT(find(modes[1].begin(),modes[1].end(),amodes[1][3])!=modes[1].end());
			TS_ASSERT(find(modes[1].begin(),modes[1].end(),amodes[1][4])!=modes[1].end());
		}
};
