package com.example.wordbook;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.app.Instrumentation.ActivityMonitor;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.test.ActivityInstrumentationTestCase2;

import com.example.wordbook.common.Common;
import com.example.wordbook.common.Data;
import com.example.wordbook.common.DataManager;

/**
 * 四択画面テストクラス
 */
public class ChoiceActivityTest extends
		ActivityInstrumentationTestCase2<ChoiceActivity> {

	/**
	 * コンストラクタ
	 */
	public ChoiceActivityTest() {
		super(ChoiceActivity.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();
	}

	/**
	 * パラメータを与えた場合は起動することを確認する
	 * 
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	public void testLaunch_succeed() throws NoSuchFieldException,
			IllegalAccessException {
		// パラメータ準備
		int index = 1;
		int count = 2;
		Intent intent = new Intent();
		intent.putExtra(Common.INTENT_INDEX, index);
		intent.putExtra(Common.INTENT_COUNT, count);
		setActivityIntent(intent);
		ChoiceActivity activity = getActivity();

		// 作成できることを確認する
		assertNotNull("Activity should launch successfully.", activity);
		// 終了しないことを確認する
		assertFalse("Activity should not be finishing.", activity.isFinishing());

		// クラスオブジェクト取得
		Class<? extends ChoiceActivity> c = activity.getClass();
		// メンバ変数取得
		Field f_index = c.getDeclaredField("mIndex");
		Field f_count = c.getDeclaredField("mCount");
		// アクセス権限追加
		f_index.setAccessible(true);
		f_count.setAccessible(true);

		// 設定されていることを確認する
		assertEquals(index, ((Integer) f_index.get(activity)).intValue());
		assertEquals(count, ((Integer) f_count.get(activity)).intValue());
	}

	/**
	 * パラメータを与えない場合は終了することを確認する
	 */
	public void testLaunch_failed() {
		ChoiceActivity activity = getActivity();

		// 作成できることを確認する
		assertNotNull("Activity should launch successfully.", activity);
		// 終了することを確認する
		assertTrue("Activity should be finishing.", activity.isFinishing());
	}

	/**
	 * オリエンテーション時の動作を確認する
	 * 
	 * @throws Throwable
	 */
	public void testOrientation() throws Throwable {
		// パラメータ準備
		int index = 1;
		int count = 2;
		Intent intent = new Intent();
		intent.putExtra(Common.INTENT_INDEX, index);
		intent.putExtra(Common.INTENT_COUNT, count);
		setActivityIntent(intent);
		final ChoiceActivity activity = getActivity();

		// クラスオブジェクト取得
		Class<? extends ChoiceActivity> c = activity.getClass();
		// メンバ変数取得
		Field f_index = c.getDeclaredField("mIndex");
		Field f_count = c.getDeclaredField("mCount");
		Field f_mDM = c.getDeclaredField("mDM");
		// アクセス権限追加
		f_index.setAccessible(true);
		f_count.setAccessible(true);
		f_mDM.setAccessible(true);
		// 初期状態
		int base = 3;
		int size = 4;
		List<Data> list = new ArrayList<Data>();
		for (int i = 0; i < size; i++) {
			list.add(new Data(i, 0, 0, 0, 0, 0, "Q", "A", "D1", "D2"));
		}
		DataManager dm = new DataManager();
		dm.init(base);
		dm.addTempList(list);
		dm.setNextPage();
		f_mDM.set(activity, dm);

		DataManager res;
		ActivityMonitor monitor = new ActivityMonitor(
				ChoiceActivity.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(index, ((Integer) f_index.get(activity)).intValue());
		assertEquals(count, ((Integer) f_count.get(activity)).intValue());
		res = (DataManager) f_mDM.get(activity);
		assertEquals(base, res.getBasePos());
		assertEquals(size, res.getDataList().size());
		for (int i = 0; i < size; i++) {
			assertEquals(i, res.getData().num);
			res.setNextPos();
		}

		// 位置は初期化すること
		res.setZeroPos();

		// 設定
		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(index, ((Integer) f_index.get(activity)).intValue());
		assertEquals(count, ((Integer) f_count.get(activity)).intValue());
		res = (DataManager) f_mDM.get(activity);
		assertEquals(base, res.getBasePos());
		assertEquals(size, res.getDataList().size());
		for (int i = 0; i < size; i++) {
			assertEquals(i, res.getData().num);
			res.setNextPos();
		}
	}

}