package oving5.stringgrid;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class StringGridTest {

	private StringGrid grid;

	@BeforeEach
	public void setUp() {
		grid = new StringGridImpl(2, 3);
	}

	@Test
	@DisplayName("Test the size of the grid")
	public void testSize() {
		assertEquals(2, grid.getRowCount(), "The number of rows was incorrect");
		assertEquals(3, grid.getColumnCount(), "The number of columns was incorrect");
	}

	@Test
	@DisplayName("Test that setElement sets the correct grid element")
	public void testGrid() {
		grid.setElement(0, 0, "0, 0");
		grid.setElement(0, 1, "0, 1");
		grid.setElement(0, 2, "0, 2");
		grid.setElement(1, 0, "1, 0");
		grid.setElement(1, 1, "1, 1");
		grid.setElement(1, 2, "1, 2");

		assertEquals("0, 0", grid.getElement(0, 0));
		assertEquals("0, 1", grid.getElement(0, 1));
		assertEquals("0, 2", grid.getElement(0, 2));
		assertEquals("1, 0", grid.getElement(1, 0));
		assertEquals("1, 1", grid.getElement(1, 1));
		assertEquals("1, 2", grid.getElement(1, 2));
	}

	@Test
	@DisplayName("Check the elements in the grid with row-first order")
	public void testGridIteratorRowMajor() {
		StringGridIterator iterator = new StringGridIterator(grid, true);

		grid.setElement(0, 0, "0, 0");
		grid.setElement(0, 1, "0, 1");
		grid.setElement(0, 2, "0, 2");
		grid.setElement(1, 0, "1, 0");
		grid.setElement(1, 1, "1, 1");
		grid.setElement(1, 2, "1, 2");

		assertTrue(iterator.hasNext());

		assertEquals("0, 0", iterator.next());
		assertTrue(iterator.hasNext());

		assertEquals("0, 1", iterator.next());
		assertTrue(iterator.hasNext());

		assertEquals("0, 2", iterator.next());
		assertTrue(iterator.hasNext());

		assertEquals("1, 0", iterator.next());
		assertTrue(iterator.hasNext());

		assertEquals("1, 1", iterator.next());
		assertTrue(iterator.hasNext());

		// False after going through the last one
		assertEquals("1, 2", iterator.next());
		assertFalse(iterator.hasNext());
	}

	@Test
	@DisplayName("Check the elements in the grid with column-first order")
	public void testGridIteratorColumnMajor() {
		StringGridIterator iterator = new StringGridIterator(grid, false);

		grid.setElement(0, 0, "0, 0");
		grid.setElement(0, 1, "0, 1");
		grid.setElement(0, 2, "0, 2");
		grid.setElement(1, 0, "1, 0");
		grid.setElement(1, 1, "1, 1");
		grid.setElement(1, 2, "1, 2");

		assertTrue(iterator.hasNext());

		assertEquals("0, 0", iterator.next(), "A cell was incorrect");
		assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");

		assertEquals("1, 0", iterator.next(), "A cell was incorrect");
		assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");

		assertEquals("0, 1", iterator.next(), "A cell was incorrect");
		assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");

		assertEquals("1, 1", iterator.next(), "A cell was incorrect");
		assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");

		assertEquals("0, 2", iterator.next(), "A cell was incorrect");
		assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");

		// False after going through the last one
		assertEquals("1, 2", iterator.next());
		assertFalse(iterator.hasNext(), "Incorrect number of cells in the grid");
	}
}
