package jp.sourceforge.nicoro.test;

import java.util.LinkedList;
import java.util.Random;

import jp.sourceforge.nicoro.AbstractNicoroPlayer;
import jp.sourceforge.nicoro.MessageChat;
import jp.sourceforge.nicoro.MessageChatController;
import android.graphics.Paint;
import android.test.AndroidTestCase;

public class MessageChatsTests extends AndroidTestCase {

	@Override
	protected void setUp() throws Exception {
		super.setUp();
	}
	
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
	}
	
	public void testShitaY() {
		Paint paint = new Paint();
		
		MessageChat chat = new MessageChat("medium shita", 0);
		chat.computeLineHeight(paint);
		int fontSize = chat.getFontSize();
		assertEquals(MessageChat.FONTSIZE_PX_MEDIUM, fontSize);
		paint.setTextSize(fontSize);
		float ascent = paint.ascent();
		assertTrue(ascent < 0.0f);
		float descent = paint.descent();
		assertTrue(descent > 0.0f);
		
		assertEquals(0, chat.getY());
		assertEquals(0.0f, chat.getDrawY());
//		assertEquals(-fontSize, chat.getNextY());
		
		int lineHeight = chat.getSingleLineHeight();
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3 - lineHeight,
				chat.setY(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3, paint));
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3 - lineHeight,
				chat.getNextY());
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3, chat.getY());
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3 - descent,
				chat.getDrawY());
	}

	public void testComputeShitaNextY() {
		Paint paint = new Paint();
		
		MessageChat chat1 = new MessageChat("medium shita", 0);
		MessageChat chat2 = new MessageChat("medium shita", 0);
		MessageChat chat3 = new MessageChat("medium shita", 0);
		chat1.computeLineHeight(paint);
		chat2.computeLineHeight(paint);
		chat3.computeLineHeight(paint);
		int fontSize = chat1.getFontSize();
		assertEquals(MessageChat.FONTSIZE_PX_MEDIUM, fontSize);
		assertEquals(fontSize, chat2.getFontSize());
		assertEquals(fontSize, chat3.getFontSize());
		
		LinkedList<MessageChat> chats = new LinkedList<MessageChat>();
		Random random = new Random();
		
		int lineHeight = chat1.getSingleLineHeight();
		int nextY = chat1.computeShitaNextY(chats, random);
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3, nextY);
		assertEquals(nextY - lineHeight,
				chat1.setY(nextY, paint));
		
		chats.add(chat1);
		nextY = chat2.computeShitaNextY(chats, random);
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3 - lineHeight, nextY);
		assertEquals(nextY - lineHeight,
				chat2.setY(nextY, paint));
		
		chats.add(chat2);
		nextY = chat3.computeShitaNextY(chats, random);
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3 - lineHeight * 2, nextY);
		assertEquals(nextY - lineHeight,
				chat3.setY(nextY, paint));
	}
	
	public void testComputeUeNextY() {
		Paint paint = new Paint();
		
		MessageChat chat1 = new MessageChat("medium ue", 0);
		MessageChat chat2 = new MessageChat("medium ue", 0);
		MessageChat chat3 = new MessageChat("medium ue", 0);
		chat1.computeLineHeight(paint);
		chat2.computeLineHeight(paint);
		chat3.computeLineHeight(paint);
		int fontSize = chat1.getFontSize();
		assertEquals(MessageChat.FONTSIZE_PX_MEDIUM, fontSize);
		assertEquals(fontSize, chat2.getFontSize());
		assertEquals(fontSize, chat3.getFontSize());
		
		LinkedList<MessageChat> chats = new LinkedList<MessageChat>();
		Random random = new Random();
		
		int lineHeight = chat1.getSingleLineHeight();
		int nextY = chat1.computeUeNextY(chats, random);
		assertEquals(0, nextY);
		assertEquals(nextY + lineHeight,
				chat1.setY(nextY, paint));
		
		chats.add(chat1);
		nextY = chat2.computeUeNextY(chats, random);
		assertEquals(lineHeight, nextY);
		assertEquals(nextY + lineHeight,
				chat2.setY(nextY, paint));
		
		chats.add(chat2);
		nextY = chat3.computeUeNextY(chats, random);
		assertEquals(lineHeight * 2, nextY);
		assertEquals(nextY + lineHeight,
				chat3.setY(nextY, paint));
	}
	
	public void testComputeNakaNextY1() {
		Paint paint = new Paint();
		MessageChatController controller = new MessageChatController();
		
		MessageChat chat1 = new MessageChat("medium naka", 0);
		chat1.setText("foo");
		chat1.prepareAdd(controller, paint, 0);
		MessageChat chat2 = new MessageChat("medium naka", 0);
		chat2.setText("foo");
		chat2.prepareAdd(controller, paint, 0);
		MessageChat chat3 = new MessageChat("medium naka", 0);
		chat3.setText("foo");
		chat3.prepareAdd(controller, paint, 0);
		int fontSize = chat1.getFontSize();
		assertEquals(MessageChat.FONTSIZE_PX_MEDIUM, fontSize);
		assertEquals(fontSize, chat2.getFontSize());
		assertEquals(fontSize, chat3.getFontSize());
		
		LinkedList<MessageChat> chats = new LinkedList<MessageChat>();
		Random random = new Random();
		
		int lineHeight = chat1.getSingleLineHeight();
		int nextY = chat1.computeNakaNextY(0, chats, random);
		assertEquals(0, nextY);
		assertEquals(nextY + lineHeight,
				chat1.setY(nextY, paint));
		
		chats.add(chat1);
		nextY = chat2.computeNakaNextY(0, chats, random);
		assertEquals(lineHeight, nextY);
		assertEquals(nextY + lineHeight,
				chat2.setY(nextY, paint));
		
		chats.add(chat2);
		nextY = chat3.computeNakaNextY(0, chats, random);
		assertEquals(lineHeight * 2, nextY);
		assertEquals(nextY + lineHeight,
				chat3.setY(nextY, paint));
	}
	
	public void testComputeNakaNextY2() {
		Paint paint = new Paint();
		
		MessageChat chat1 = new MessageChat("medium naka", 0);
		chat1.setText("foo");
		chat1.computeWidth(paint);
		chat1.computeSpeed();
		chat1.computeLineHeight(paint);
		MessageChat chat2 = new MessageChat("medium naka", 100);
		chat2.setText("foo");
		chat2.computeWidth(paint);
		chat2.computeSpeed();
		chat2.computeLineHeight(paint);
		MessageChat chat3 = new MessageChat("medium naka", 200);
		chat3.setText("foo");
		chat3.computeWidth(paint);
		chat3.computeSpeed();
		chat3.computeLineHeight(paint);
		int fontSize = chat1.getFontSize();
		assertEquals(MessageChat.FONTSIZE_PX_MEDIUM, fontSize);
		assertEquals(fontSize, chat2.getFontSize());
		assertEquals(fontSize, chat3.getFontSize());
		
		LinkedList<MessageChat> chats = new LinkedList<MessageChat>();
		Random random = new Random();
		
		int lineHeight = chat1.getSingleLineHeight();
		int nextY = chat1.computeNakaNextY(0, chats, random);
		assertEquals(0, nextY);
		assertEquals(nextY + lineHeight,
				chat1.setY(nextY, paint));
		
		chats.add(chat1);
		nextY = chat2.computeNakaNextY(100, chats, random);
		assertEquals(0, nextY);
		assertEquals(nextY + lineHeight,
				chat2.setY(nextY, paint));
		
		chats.add(chat2);
		nextY = chat3.computeNakaNextY(200, chats, random);
		assertEquals(0, nextY);
		assertEquals(nextY + lineHeight,
				chat3.setY(nextY, paint));
	}
	
	public void testAddShitaOrder() {
		Paint paint = new Paint();
		
		MessageChat chat1 = new MessageChat("medium shita", 0);
		MessageChat chat2 = new MessageChat("medium shita", 0);
		MessageChat chat3 = new MessageChat("medium shita", 0);
		chat1.computeLineHeight(paint);
		chat2.computeLineHeight(paint);
		chat3.computeLineHeight(paint);
		int lineHeight = chat1.getSingleLineHeight();
		
		LinkedList<MessageChat> chats = new LinkedList<MessageChat>();
		Random random = new Random();
		int nextY = chat1.computeShitaNextY(chats, random);
		assertEquals(nextY - lineHeight,
				chat1.setY(nextY, paint));
		
		chat1.addShitaOrder(chats);
		assertEquals(chat1, chats.get(0));

		nextY = chat2.computeShitaNextY(chats, random);
		assertEquals(nextY - lineHeight,
				chat2.setY(nextY, paint));

		chat2.addShitaOrder(chats);
		assertEquals(chat2, chats.get(1));

		nextY = chat3.computeShitaNextY(chats, random);
		assertEquals(nextY - lineHeight,
				chat3.setY(nextY, paint));

		chat3.addShitaOrder(chats);
		assertEquals(chat3, chats.get(2));

		chats.remove(chat1);
		MessageChat chat4 = new MessageChat("big shita", 0);
		chat4.computeLineHeight(paint);
		assertEquals(MessageChat.FONTSIZE_PX_BIG, chat4.getFontSize());
		int lineHeightBig = chat4.getSingleLineHeight();
		
		nextY = chat4.computeShitaNextY(chats, random);
		assertEquals(chat3.getNextY(), nextY);
		assertEquals(nextY - lineHeightBig,
				chat4.setY(nextY, paint));
		chat4.addShitaOrder(chats);
		assertEquals(chat4, chats.get(2));
		
		MessageChat chat5 = new MessageChat("medium shita", 0);
		chat5.computeLineHeight(paint);
		int lineHeightMedium = chat5.getSingleLineHeight();
		nextY = chat5.computeShitaNextY(chats, random);
		assertEquals(AbstractNicoroPlayer.REAL_PLAYER_HEIGHT_PX_4_3, nextY);
		assertEquals(nextY - lineHeightMedium,
				chat5.setY(nextY, paint));
		chat5.addShitaOrder(chats);
		assertEquals(chat5, chats.get(0));
	}
	
	public void testComputeSpeed() {
		Paint paint = new Paint();
		
		MessageChat chat = new MessageChat("medium naka", 0);
		chat.setText("");
		chat.computeWidth(paint);
		assertEquals(0, chat.getWidth());
		
		chat.computeSpeed();
		assertEquals((float) -AbstractNicoroPlayer.REAL_PLAYER_WIDTH_PX_4_3 / (float) MessageChat.DISPLAY_TIME_VPOS_NAKA,
				chat.getSpeed());
		
		chat.setText("ニコニコ");
		float[] widths = new float[4];
		chat.computeWidth(paint);
		assertEquals(4, paint.getTextWidths("ニコニコ", widths));
		float sumWidths = widths[0] + widths[1] + widths[2] + widths[3];
		assertEquals((int) sumWidths, chat.getWidth());
		
		chat.computeSpeed();
		assertEquals((float) -(AbstractNicoroPlayer.REAL_PLAYER_WIDTH_PX_4_3 + sumWidths) / (float) MessageChat.DISPLAY_TIME_VPOS_NAKA,
				chat.getSpeed());
	}
	
	public void testInitializeX() {
		MessageChat chat = new MessageChat("medium naka", 500);
		chat.setText("a");
		
		chat.initializeX(650);
		assertEquals(chat.computeX(650), chat.getDrawX());
	}
}
