package jrummikub.model;

import static jrummikub.model.StoneColor.*;
import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

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

/**
 * Test class for {@link Hand}
 */
public class HandTest {

	Hand hand;

	/** */
	@Before
	public void setUp() {
		hand = new Hand();
	}

	/** */
	@Test
	public void testSimpleDrop() {
		Stone stone1 = new Stone(1, RED);
		Stone stone2 = new Stone(5, RED);
		Stone stone3 = new Stone(2, RED);

		hand.drop(stone1, new Position(2, 0));
		hand.drop(stone2, new Position(3, 0));
		hand.drop(stone3, new Position(2.5f, 0));

		assertEquals(new Position(1.5f, 0), hand.getPosition(stone1));
		assertEquals(new Position(3.5f, 0), hand.getPosition(stone2));
		assertEquals(new Position(2.5f, 0), hand.getPosition(stone3));
	}

	/** */
	@Test
	public void testSingleEdgeDrop() {
		Stone stone1 = new Stone(2, RED);
		Stone stone2 = new Stone(4, RED);

		hand.drop(stone1, new Position(0, 0));
		hand.drop(stone2, new Position(0.5f, 0));

		assertEquals(new Position(0, 0), hand.getPosition(stone1));
		assertEquals(new Position(1, 0), hand.getPosition(stone2));
	}

	/** */
	@Test
	public void testNearEdgeDrop() {
		Stone stone1 = new Stone(2, RED);
		Stone stone2 = new Stone(4, RED);

		hand.drop(stone1, new Position(0.25f, 0));
		hand.drop(stone2, new Position(0.5f, 0));

		assertEquals(new Position(0, 0), hand.getPosition(stone1));
		assertEquals(new Position(1, 0), hand.getPosition(stone2));
	}

	/** */
	@Test
	public void testNearEdgeMiddleDrop() {
		Stone stone1 = new Stone(1, RED);
		Stone stone2 = new Stone(5, RED);
		Stone stone3 = new Stone(2, RED);

		hand.drop(stone1, new Position(0.25f, 0));
		hand.drop(stone2, new Position(1.25f, 0));
		hand.drop(stone3, new Position(0.5f, 0));

		assertEquals(new Position(0, 0), hand.getPosition(stone1));
		assertEquals(new Position(2, 0), hand.getPosition(stone2));
		assertEquals(new Position(1, 0), hand.getPosition(stone3));
	}

	/** */
	@Test
	public void testNearRightEdgeDrop() {
		Stone stone1 = new Stone(2, BLUE);
		Stone stone2 = new Stone(4, BLUE);

		hand.drop(stone1, new Position(12.75f, 1));
		hand.drop(stone2, new Position(12.5f, 1));

		assertEquals(new Position(13, 1), hand.getPosition(stone1));
		assertEquals(new Position(12, 1), hand.getPosition(stone2));
	}

	/** */
	@Test
	public void testFullWrapDrop() {
		List<Stone> rowStones = new ArrayList<Stone>();
		for (int i = 0; i < 14; i++) {
			Stone stone = new Stone(i % 9, BLUE);
			rowStones.add(stone);
			hand.drop(stone, new Position(i, 1));
		}
		Stone newStone = new Stone(RED);
		hand.drop(newStone, new Position(12.5f, 1));
		
		for (int i = 0; i < 13; i++) {
			assertEquals(new Position(i, 1), hand.getPosition(rowStones.get(i)));
		}
		assertEquals(new Position(13, 1), hand.getPosition(newStone));
		assertEquals(new Position(0, 2), hand.getPosition(rowStones.get(13)));
	}
}
