package de.joshuagleitze.tilinggame.test;
import static de.joshuagleitze.tilinggame.LineType.NONE;
import static de.joshuagleitze.tilinggame.LineType.RED;
import static de.joshuagleitze.tilinggame.LineType.YELLOW;
import static de.joshuagleitze.tilinggame.test.TileTestHelper.EMPTY_TILE_DEFINITION;
import static de.joshuagleitze.tilinggame.test.TileTestHelper.TEST_TILES_DEFINITIONS;
import static de.joshuagleitze.tilinggame.test.TileTestHelper.isTile;
import static de.joshuagleitze.tilinggame.test.TileTestHelper.tile;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import de.joshuagleitze.tilinggame.LineType;
import de.joshuagleitze.tilinggame.Tile;
public class TileInteractionTest {
	@Test
	public void worksheetInteraction() {
		final Tile t1 = new Tile();
		assertTrue(t1.isEmpty()); 
		assertThat(t1.getNumberOfColors(), is(0)); 
		assertThat(t1.toString(), is("------")); 
		final Tile t2 = new Tile(new LineType[] {NONE, YELLOW, NONE, NONE, NONE, YELLOW});
		assertThat(t2.toString(), is("-Y---Y")); 
		t1.canBeRecoloredTo(t2); 
		final Tile t3 = new Tile(new LineType[] {NONE, YELLOW, RED, NONE, RED, YELLOW});
		assertTrue(t3.dominates(t1)); 
		assertTrue(t3.dominates(t2)); 
		assertFalse(t2.canBeRecoloredTo(t3)); 
		final Tile t4 = t3.copy();
		assertTrue(t4.isExactlyEqualTo(t3)); 
		t4.rotateClockwise();
		t4.rotateClockwise();
		t4.rotateClockwise();
		assertThat(t4.toString(), is("-RY-YR")); 
		assertFalse(t4.isExactlyEqualTo(t3)); 
		assertTrue(t4.isRotationEqualTo(t3)); 
		assertTrue(t4.canBeRecoloredTo(t3)); 
	}
	@Test
	public void rotationAndToString() {
		final Tile tile = tile("YY----");
		tile.rotateClockwise();
		assertThat("string representation works for a rotated tile", tile.toString(), is("-YY---"));
		tile.rotateCounterClockwise();
		tile.rotateCounterClockwise();
		assertThat("string representation works for a rotated tile", tile.toString(), is("Y----Y"));
	}
	@Test
	public void rotateAndExactlyEqual() {
		final String definition = "RGYYRG";
		final Tile tile = tile(definition);
		for (int i = 0; i < 5; i++) {
			tile.rotateClockwise();
			assertThat(tile + " is not " + definition, tile.isExactlyEqualTo(tile(definition)),
					is(definition.equals(EMPTY_TILE_DEFINITION)));
		}
		tile.rotateClockwise();
		for (int i = 0; i < 5; i++) {
			tile.rotateCounterClockwise();
			assertThat(tile + " is not " + definition, tile.isExactlyEqualTo(tile(definition)),
					is(definition.equals(EMPTY_TILE_DEFINITION)));
		}
	}
	@Test
	public void copyAndRotate() {
		final String definition = "RGYYRG";
		final Tile tile = tile(definition);
		Tile copy = tile.copy();
		copy.rotateClockwise();
		assertThat("rotating a copy should not rotate the original", tile, isTile(definition));
		copy = tile.copy();
		copy.rotateCounterClockwise();
		assertThat("rotating a copy should not rotate the original", tile, isTile(definition));
	}
	@Test
	public void copyAndToString() {
		assertThat("copying should preserve the string presentation", new Tile().copy().toString(),
				is(EMPTY_TILE_DEFINITION));
		for (final String definition : TEST_TILES_DEFINITIONS) {
			assertThat("copying should preserve the string presentation", tile(definition).copy().toString(),
					is(definition));
		}
	}
	@Test
	public void rotationEqualsDoesNotModify() {
		final String definition = "RR-YY-";
		final String roatatedDefinition = "YY-RR-";
		final Tile tile = tile(definition);
		final Tile rotatedTile = tile(roatatedDefinition);
		tile.isRotationEqualTo(rotatedTile);
		assertThat("neither tile should be modified in isRotationEqualTo", tile, isTile(tile(definition)));
		assertThat("neither tile should be modified in isRotationEqualTo", rotatedTile,
				isTile(tile(roatatedDefinition)));
		assertThat("neither tile should be modified in isRotationEqualTo", tile.toString(), is(definition));
		assertThat("neither tile should be modified in isRotationEqualTo", rotatedTile.toString(),
				is(roatatedDefinition));
		assertFalse("neither tile should be modified in isRotationEqualTo", tile.isExactlyEqualTo(rotatedTile));
	}
	@Test
	public void dominatesDoesNotModify() {
		final String definition = "RR-YY-";
		final String dominatedDefinition = "RR----";
		final Tile tile = tile(definition);
		final Tile dominatedTile = tile(dominatedDefinition);
		tile.dominates(dominatedTile);
		assertThat("neither tile should be modified in dominates", tile, isTile(tile(definition)));
		assertThat("neither tile should be modified in dominates", dominatedTile, isTile(tile(dominatedDefinition)));
		assertThat("neither tile should be modified in dominates", tile.toString(), is(definition));
		assertThat("neither tile should be modified in dominates", dominatedTile.toString(), is(dominatedDefinition));
		assertFalse("neither tile should be modified in dominates", tile.isExactlyEqualTo(dominatedTile));
	}
}