package com.example.wordbook;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Instrumentation.ActivityMonitor;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.test.ActivityInstrumentationTestCase2;

/**
 * メイン画面テストクラス
 */
public class MainActivityTest extends
		ActivityInstrumentationTestCase2<MainActivity> {

	/**
	 * コンストラクタ
	 */
	public MainActivityTest() {
		super(MainActivity.class);
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.test.ActivityInstrumentationTestCase2#setUp()
	 */
	@Override
	protected void setUp() throws Exception {
		super.setUp();
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.test.ActivityInstrumentationTestCase2#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
	}

	/**
	 * パラメータを与えない場合でも起動することを確認する
	 */
	public void testLaunch() {
		MainActivity activity = getActivity();

		// 作成できることを確認する
		assertNotNull("Activity should launch successfully.", activity);
		// 終了しないことを確認する
		assertFalse("Activity should not be finishing.", activity.isFinishing());
	}

	/**
	 * オリエンテーション時の動作を確認する
	 * 
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	public void testOrientation() throws Throwable {
		final MainActivity activity = getActivity();

		// クラスオブジェクト取得
		Class<? extends MainActivity> c = activity.getClass();
		// メンバ変数取得
		Field f_mPos = c.getDeclaredField("mPos");
		Field f_mMain = c.getDeclaredField("mMain");
		// アクセス権限追加
		f_mPos.setAccessible(true);
		f_mMain.setAccessible(true);
		// 初期状態
		int pos = 2;
		int size = 4;
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < size; i++) {
			Map<String, Object> item = new HashMap<String, Object>();
			item.put("index", i);
			item.put("title", "T");
			item.put("value", "V");
			item.put("count", i * 16);
			item.put("zero", i * 8);
			item.put("ok", i * 4);
			item.put("ng", i * 2);
			list.add(item);
		}
		f_mPos.setInt(activity, pos);
		f_mMain.set(activity, list);

		List<Map<String, Object>> res;
		ActivityMonitor monitor = new ActivityMonitor(
				MainActivity.class.getName(), null, false);

		// 設定
		getInstrumentation().addMonitor(monitor);
		runTestOnUiThread(new Runnable() {
			@Override
			public void run() {
				activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
			}
		});
		// 反映待ち
		getInstrumentation().waitForIdleSync();
		getInstrumentation().waitForMonitor(monitor);
		// 設定されていることを確認する
		assertEquals("Activity should be LANDSCAPE mode",
				Configuration.ORIENTATION_LANDSCAPE, activity.getResources()
						.getConfiguration().orientation);
		// データの復帰を確認する
		assertEquals(pos, ((Integer) f_mPos.get(activity)).intValue());
		res = (List<Map<String, Object>>) f_mMain.get(activity);
		assertEquals(size, res.size());
		for (int i = 0; i < size; i++) {
			assertEquals(i, res.get(i).get("index"));
			assertEquals("T", res.get(i).get("title"));
			assertEquals("V", res.get(i).get("value"));
			assertEquals(i * 16, res.get(i).get("count"));
			assertEquals(i * 8, res.get(i).get("zero"));
			assertEquals(i * 4, res.get(i).get("ok"));
			assertEquals(i * 2, res.get(i).get("ng"));
		}

		// 設定
		getInstrumentation().addMonitor(monitor);
		runTestOnUiThread(new Runnable() {
			@Override
			public void run() {
				activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
			}
		});
		// 反映待ち
		getInstrumentation().waitForIdleSync();
		getInstrumentation().waitForMonitor(monitor);
		// 設定されていることを確認する
		assertEquals("Activity should be PORTRAIT mode",
				Configuration.ORIENTATION_PORTRAIT, activity.getResources()
						.getConfiguration().orientation);
		// データの復帰を確認する
		assertEquals(pos, ((Integer) f_mPos.get(activity)).intValue());
		res = (List<Map<String, Object>>) f_mMain.get(activity);
		assertEquals(size, res.size());
		for (int i = 0; i < size; i++) {
			assertEquals(i, res.get(i).get("index"));
			assertEquals("T", res.get(i).get("title"));
			assertEquals("V", res.get(i).get("value"));
			assertEquals(i * 16, res.get(i).get("count"));
			assertEquals(i * 8, res.get(i).get("zero"));
			assertEquals(i * 4, res.get(i).get("ok"));
			assertEquals(i * 2, res.get(i).get("ng"));
		}
	}

}
