package editortrees;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class EditTreeTest {

	static int points = 0;

	// Feel free to use these strings in your test cases, or not.

	static String s1 = "short string",
			s2 = "a moderately short string",
			s3 = "This string is not as short as the others",
			s4 = "This is a great, big, juicy, longer-than-the-others, string",
			s5 = "You can't always get the strings you want, "
					+ "but if you try sometimes, you just might find you get the strings you need.";

	/**
	 * The variables whose first two digits are your team number are available
	 * for your team's test cases to use. If you want to intiialize them once
	 * and for all instead of in individual test cases, put that code in
	 * setUpXY, where XY is your team number. You may use other variables, of
	 * course, but they should be local to your methods.
	 */
	EditTree t110, t111, t112, t113, t114, t115, t116, t117, t118, t119;
	EditTree t120, t121, t122, t123, t124, t125, t126, t127, t128, t129;
	EditTree t130, t131, t132, t133, t134, t135, t136, t137, t138, t139;
	EditTree t140, t141, t142, t143, t144, t145, t146, t147, t148, t149;
	EditTree t150, t151, t152, t153, t154, t155, t156, t157, t158, t159;
	EditTree t160, t161, t162, t163, t164, t165, t166, t167, t168, t169;
	EditTree t210, t211, t212, t213, t214, t215, t216, t217, t218, t219;
	EditTree t220, t221, t222, t223, t224, t225, t226, t227, t228, t229;
	EditTree t230, t231, t232, t233, t234, t235, t236, t237, t238, t239;
	EditTree t240, t241, t242, t243, t244, t245, t246, t247, t248, t249;
	EditTree t250, t251, t252, t253, t254, t255, t256, t257, t258, t259;
	EditTree t260, t261, t262, t263, t264, t265, t266, t267, t268, t269;
	EditTree ti0, ti1, ti2, ti3, ti4, ti5, ti6, ti7, ti8, ti9;

	// Do not modify this method

	@Before
	public void setUp() throws Exception {
		try {
			setUpInstructors();
		} catch (Exception e) {
			System.out.println("Error in setUpInstructors:");
			e.printStackTrace();
		}
		try {
			setUp11();
		} catch (Exception e) {
			System.out.println("Error in setUp11:");
			e.printStackTrace();
		}
		try {
			setUp12();
		} catch (Exception e) {
			System.out.println("Error in setUp12:");
			e.printStackTrace();
		}
		try {
			setUp13();
		} catch (Exception e) {
			System.out.println("Error in setUp13:");
			e.printStackTrace();
		}
		try {
			setUp14();
		} catch (Exception e) {
			System.out.println("Error in setUp14:");
			e.printStackTrace();
		}
		try {
			setUp15();
		} catch (Exception e) {
			System.out.println("Error in setUp15:");
			e.printStackTrace();
		}
		try {
			setUp16();
		} catch (Exception e) {
			System.out.println("Error in setUp16:");
			e.printStackTrace();
		}
		try {
			setUp21();
		} catch (Exception e) {
			System.out.println("Error in setUp21:");
			e.printStackTrace();
		}
		try {
			setUp22();
		} catch (Exception e) {
			System.out.println("Error in setUp22:");
			e.printStackTrace();
		}
		try {
			setUp23();
		} catch (Exception e) {
			System.out.println("Error in setUp23:");
			e.printStackTrace();
		}
		try {
			setUp24();
		} catch (Exception e) {
			System.out.println("Error in setUp24:");
			e.printStackTrace();
		}
		try {
			setUp25();
		} catch (Exception e) {
			System.out.println("Error in setUp25:");
			e.printStackTrace();
		}
		try {
			setUp26();
		} catch (Exception e) {
			System.out.println("Error in setUp26:");
			e.printStackTrace();
		}
	}

	public void setUpInstructors() throws Exception {

	}

	public void setUp11() throws Exception {

	}

	public void setUp12() throws Exception {

	}

	public void setUp13() throws Exception {

	}

	public void setUp14() throws Exception {

	}

	public void setUp15() throws Exception {

	}

	public void setUp16() throws Exception {

	}

	public void setUp21() throws Exception {

	}

	public void setUp22() throws Exception {

	}

	public void setUp23() throws Exception {

	}

	public void setUp24() throws Exception {
		this.t240 = new EditTree();
		this.t241 = new EditTree("a");
		this.t242 = new EditTree("this is sparta!");
		this.t243 = new EditTree("!@#$%^&*");
		this.t244 = new EditTree(s1);
		this.t245 = new EditTree(s2);
		this.t246 = new EditTree(s3);
		this.t247 = new EditTree(s4);
		this.t248 = new EditTree(s5);
		this.t249 = new EditTree("this is a " + "combined string.");
	}

	public void setUp25() throws Exception {

	}

	public void setUp26() throws Exception {

	}

	// The name of each of your team's tests should end with an underscore
	// followed by your team number,
	// for example, testSize3_13 if you are on team 13.

	// Make sure that each of your tests has a timeout.
	// The timeout should be 1 or 2 seconds unless your
	// test involves VERY complicated operations.

	// Each of your tests should be worth one point.

	// A sample test to remind you of the format:

	@Test
	// (timeout=1000) // one second
	public void testSize3_i() { // i is for instructor
		ti3 = new EditTree(s1);
		ti4 = new EditTree(s2);
		ti5 = new EditTree(s3);
		// System.out.println(ti3.height());
		// System.out.println(ti4.height());
		// System.out.println(ti5.height());
		assertEquals(12, ti3.size());
		points += 1;
		assertEquals(s2.length(), ti4.size());
		points += 1;
		assertEquals(s3.length(), ti5.size());
		points += 1; // only incremented if test passes.
		System.out.println("    points = " + points);
	}

	@Test(timeout = 1000)
	public void testAdd_24() {

		t240.add('a');
		assertEquals(1, t240.size());
		points += 1;
		assertEquals('a', t240.get(0));
		points += 1;
		t240.add('b');
		assertEquals('b', t240.get(1));
		points += 1;
		assertEquals(2, t240.size());
		points += 1;
		t240.add('c');
		assertEquals(true, t240.isHeightBalanced());
		points += 1;

		t248.add('$');
		assertEquals('$', t248.get(s5.length()));
		points += 1;
		assertTrue(t248.isHeightBalanced());
		points += 1;
		
		System.out.println("    points = " + points);

	}

	@Test(timeout = 1000)
	public void testAddPos_24() {

		t242.add('&', 3);
		assertEquals('&', t242.get(3));
		points += 1;
		assertTrue(t242.isHeightBalanced());
		points += 1;

		t244.add('w', 0);
		assertTrue(t244.isHeightBalanced());
		points += 1;
		assertEquals('w', t244.get(0));
		points += 1;

		t248.add('q', s5.length() - 1);
		assertTrue(t248.isHeightBalanced());
		points += 1;
		assertEquals('q', t248.get(s5.length()));
		points += 1;
		System.out.println("    points = " + points);
	}

	@Test(timeout = 1000)
	public void testHeight_24() {
		// TODO
		assertEquals(-1, t240.height());
		points += 1;
		assertEquals(0, t241.height());
		points += 1;
		assertTrue(3 == t242.height() || 4 == t242.height());
		points += 1;
		assertTrue(6 == t248.height() || 7 == t248.height());
		points += 1;
		System.out.println("    points = " + points);

	}

	@Test(timeout = 1000)
	public void testToString_24() {

		assertEquals("", t240.toString());
		points += 1;
		assertEquals("a", t241.toString());
		points += 1;
		assertEquals("this is sparta!", t242.toString());
		points += 1;
		assertEquals("!@#$%^&*", t243.toString());
		points += 1;
		assertEquals(s1, t244.toString());
		points += 1;
		assertEquals(s2, t245.toString());
		points += 1;
		assertEquals(s3, t246.toString());
		points += 1;
		assertEquals(s4, t247.toString());
		points += 1;
		assertEquals(s5, t248.toString());
		points += 1;
		assertEquals("this is a combined string.", t249.toString());
		points += 1;
		System.out.println("    points = " + points);
	}

	@Test(timeout = 1000)
	public void testGet_24() {

		try {
			assertEquals("", t240.get(10));
			fail();
		} catch (IndexOutOfBoundsException e) {
			assertTrue(true);
			points += 1;
		}

		assertEquals('a', t241.get(0));
		points += 1;
		assertEquals('p', t242.get(9));
		points += 1;
		assertEquals('$', t243.get(3));
		points += 1;
		assertEquals('h', t244.get(1));
		points += 1;
		assertEquals('y', t245.get(11));
		points += 1;
		assertEquals(' ', t246.get(14));
		points += 1;
		assertEquals(',', t247.get(15));
		points += 1;
		assertEquals('\'', t248.get(7));
		points += 1;
		assertEquals('c', t249.get(10));
		points += 1;
		System.out.println("    points = " + points);
	}

	@Test(timeout = 1000)
	public void testDelete_24() {

		try {
			t240.delete(0);
			fail();
		} catch (IndexOutOfBoundsException e) {
			assertTrue(true);
			points += 1;
		}

		t241.delete(0);
		assertEquals(-1, t241.size());
		points += 1;

		t242.delete(0);
		assertTrue(t242.isHeightBalanced());
		points += 1;
		assertEquals(14, t242.size());
		points += 1;
		t242.delete(t242.size() - 1);
		assertEquals('a', t242.get(t242.size() - 1));
		points += 1;
		assertTrue(t242.isHeightBalanced());
		points += 1;
		t242.delete(7);
		assertFalse('s' == t242.get(7));
		points += 1;
		assertEquals('p', t242.get(7));
		points += 1;
		assertTrue(t242.isHeightBalanced());
		points += 1;
		System.out.println("    points = " + points);
	}

	@Test(timeout = 1000)
	public void testConcatenate_24() {
		int size1, size2;
		size1 = t242.size();
		size2 = t243.size();

		t242.concatenate(t243);
		assertEquals(size1 + size2, t242.size());
		points += 1;
		assertTrue(t242.isHeightBalanced());
		points += 1;
		assertEquals('t', t242.get(0));
		points += 1;
		assertEquals('*', t242.get(t242.size() - 1));
		points += 1;

		size1 = t248.size();
		size2 = t247.size();

		t248.concatenate(t247);
		assertEquals(size1 + size2, t248.size());
		points += 1;
		assertTrue(t248.isHeightBalanced());
		points += 1;
		assertEquals('Y', t248.get(0));
		points += 1;
		assertEquals('g', t248.get(t248.size() - 1));
		points += 1;

		try {
			t244.concatenate(t244);
			fail();
		} catch (IllegalArgumentException e) {
			assertTrue(true);
			points += 1;
		}
		System.out.println("    points = " + points);
	}

	@Test(timeout = 1000)
	public void testSplit_24() {

		try {
			t240.split(0);
			fail();
		} catch (IndexOutOfBoundsException e) {
			assertTrue(true);
			points += 1;
		}

		try {
			t240.split(1);
			fail();
		} catch (IndexOutOfBoundsException e) {
			assertTrue(true);
			points += 1;
		}

		EditTree newTree = t242.split(4);
		assertTrue(t242.isHeightBalanced());
		points += 1;
		assertTrue(newTree.isHeightBalanced());
		points += 1;
		assertEquals(4, t242.size());
		points += 1;
		assertEquals('s', t242.get(3));
		points += 1;
		assertEquals(11, newTree.size());
		points += 1;
		assertEquals(' ', newTree.get(0));
		points += 1;
		System.out.println("    points = " + points);

	}

	@Test(timeout = 1000)
	public void testDeleteRange_24() {

		try {
			t240.delete(0, 5);
			fail();
		} catch (IndexOutOfBoundsException e) {
			assertTrue(true);
			points += 1;
		}
		try {
			t241.delete(0, 2);
			fail();
		} catch (IndexOutOfBoundsException e) {
			assertTrue(true);
			points += 1;
		}
		t241.delete(0, 1);
		assertEquals(0, t241.size());
		points += 1;
		t245.delete(2, 4);
		assertEquals('t', t245.get(2));
		points += 1;
		assertTrue(t245.isHeightBalanced());
		points += 1;

		t248.delete(0, t248.size());
		assertEquals(0, t248.size());
		points += 1;
		System.out.println("    points = " + points);

	}

	@Test(timeout = 1000)
	public void testCheckRanks_24() {
		assertEquals(t240.getRoot().rank, t240.getRoot().left.size());
		points += 1;
		assertEquals(t241.getRoot().rank, t241.getRoot().left.size());
		points += 1;
		assertEquals(t242.getRoot().rank, t242.getRoot().left.size());
		points += 1;
		assertEquals(t243.getRoot().rank, t243.getRoot().left.size());
		points += 1;
		assertEquals(t244.getRoot().left.rank, t244.getRoot().left.left.size());
		points += 1;
		assertEquals(t245.getRoot().rank, t245.getRoot().left.size());
		points += 1;
		assertEquals(t246.getRoot().rank, t246.getRoot().left.size());
		points += 1;
		assertEquals(t247.getRoot().rank, t247.getRoot().left.size());
		points += 1;
		assertEquals(t248.getRoot().rank, t248.getRoot().left.size());
		points += 1;
		assertEquals(t249.getRoot().right.rank, t249.getRoot().right.left
				.size());
		points += 1;
		System.out.println("    points = " + points);

	}

}