package com.example.wordbook;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.example.wordbook.common.Common;
import com.example.wordbook.common.DBAccess;
import com.example.wordbook.common.Message;

/**
 * 管理画面クラス
 */
public class ManageActivity extends Activity {

	/** TAG */
	private static final String TAG = ManageActivity.class.getSimpleName();

	/** インスタンス状態用整合性確認リストキー */
	private static final String IS_DATA = "manage";
	/** インスタンス状態用処理時間キー */
	private static final String IS_PROC = "proc";

	/** DB情報用項目数キー */
	private static final String DB_COUNT = "db_count";
	/** DB情報用未解答項目数キー */
	private static final String DB_ZERO = "db_zero";
	/** DB情報用正解数キー */
	private static final String DB_OK = "db_ok";
	/** DB情報用不正解数キー */
	private static final String DB_NG = "db_ng";

	/** 整合性確認リスト */
	private List<Map<String, Object>> mManage = new ArrayList<Map<String, Object>>();
	/** 処理時間 */
	private long mProc;

	/** ProgressBar */
	private ProgressBar mProg;
	/** TextView */
	private TextView mTimer;
	/** TableLayout */
	private TableLayout mTable;
	/** Button */
	private Button mButton;

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.d(TAG, "onCreate()");

		// レイアウト設定
		setContentView(R.layout.manage);

		// ProgressBar取得
		mProg = (ProgressBar) findViewById(R.id.progressBar);
		// TextView取得
		mTimer = (TextView) findViewById(R.id.timer);
		// TableLayout取得
		mTable = (TableLayout) findViewById(R.id.table);
		// Button取得
		mButton = (Button) findViewById(R.id.buttonFix);

		// イベントリスナ設定
		mButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				// 情報修正
				fixData();
			}
		});

		// 状態復帰
		if (savedInstanceState != null) {
			mManage = (List<Map<String, Object>>) savedInstanceState
					.getSerializable(IS_DATA);
			mProc = savedInstanceState.getLong(IS_PROC);
			if (mManage.size() > 0) {
				// 情報表示
				showData();
			} else {
				// 情報取得＆表示
				checkData();
			}
		} else {
			// 情報取得＆表示
			checkData();
		}
		Log.d(TAG, "data=" + mManage.size());
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.app.Activity#onResume()
	 */
	@Override
	protected void onResume() {
		super.onResume();
		Log.d(TAG, "onResume()");
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.app.Activity#onPause()
	 */
	@Override
	protected void onPause() {
		super.onPause();
		Log.d(TAG, "onPause()");

		// タスク動作時はキャンセル
		if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
			Log.w(TAG, "onPause()=RUNNING");
			// キャンセル
			mTask.cancel(true);
		}
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
	 */
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		Log.d(TAG, "onSaveInstanceState()");

		// 状態保存
		outState.putSerializable(IS_DATA, (Serializable) mManage);
		outState.putSerializable(IS_PROC, mProc);
	}

	/**
	 * 配列データ取得
	 * 
	 * @param item
	 *            マップデータ
	 * @return 配列データ
	 */
	private String[] getData(Map<String, Object> item) {
		String[] str = { "", "", "", "", "", "", "", "", "", "" };

		str[0] = (item.get(Common.WORDBOOK_INDEX) == null ? "" : item
				.get(Common.WORDBOOK_INDEX)).toString();
		str[1] = (item.get(Common.WORDBOOK_COUNT) == null ? "" : item
				.get(Common.WORDBOOK_COUNT)).toString();
		str[2] = (item.get(DB_COUNT) == null ? "" : item.get(DB_COUNT))
				.toString();
		str[3] = (item.get(Common.WORDBOOK_ZERO) == null ? "" : item
				.get(Common.WORDBOOK_ZERO)).toString();
		str[4] = (item.get(DB_ZERO) == null ? "" : item.get(DB_ZERO))
				.toString();
		str[5] = (item.get(Common.WORDBOOK_OK) == null ? "" : item
				.get(Common.WORDBOOK_OK)).toString();
		str[6] = (item.get(DB_OK) == null ? "" : item.get(DB_OK)).toString();
		str[7] = (item.get(Common.WORDBOOK_NG) == null ? "" : item
				.get(Common.WORDBOOK_NG)).toString();
		str[8] = (item.get(DB_NG) == null ? "" : item.get(DB_NG)).toString();
		str[9] = (item.get(Common.WORDBOOK_TITLE) == null ? "" : item
				.get(Common.WORDBOOK_TITLE)).toString();

		return str;
	}

	/**
	 * ヘッダ表示
	 * 
	 * @param pos
	 *            表示位置
	 */
	private void showHeader(int pos) {
		// ヘッダ背景色
		int back = getResources().getColor(R.color.silver);
		// ヘッダ文字列
		String[] head = { "No", "", "C", "", "Z", "", "OK", "", "NG", "" };

		getLayoutInflater().inflate(R.layout.row_manage, mTable);
		TableRow row = (TableRow) mTable.getChildAt(pos);
		for (int i = 0; i < head.length; i++) {
			row.getChildAt(i).setBackgroundColor(back);
			((TextView) row.getChildAt(i)).setText(head[i]);
		}
	}

	/**
	 * 情報表示
	 */
	private void showData() {
		// 表示位置
		int pos = 0;
		// 通常背景色（奇数列）
		int def0 = Color.WHITE;
		// 通常背景色（偶数列）
		int def1 = getResources().getColor(R.color.silver_sub);
		// エラー背景色
		int err = getResources().getColor(R.color.red_sub);

		// 初期化
		mTable.removeAllViews();
		if (mManage.size() > 0) {
			// ヘッダ表示
			showHeader(pos++);
			// 処理時間表示
			mTimer.setText(mProc + " (ms)");
		}

		Iterator<Map<String, Object>> itr = mManage.iterator();
		while (itr.hasNext()) {
			Map<String, Object> item = itr.next();
			String[] str = getData(item);
			getLayoutInflater().inflate(R.layout.row_manage, mTable);
			TableRow row = (TableRow) mTable.getChildAt(pos++);

			// 情報値設定
			for (int i = 0; i < str.length; i++) {
				row.getChildAt(i).setBackgroundColor(i % 2 == 0 ? def1 : def0);
				((TextView) (row.getChildAt(i))).setText(str[i]);
			}
			// 背景色設定
			if (!str[1].equals(str[2])) {
				row.getChildAt(1).setBackgroundColor(err);
			}
			if (!str[3].equals(str[4])) {
				row.getChildAt(3).setBackgroundColor(err);
			}
			if (!str[5].equals(str[6])) {
				row.getChildAt(5).setBackgroundColor(err);
			}
			if (!str[7].equals(str[8])) {
				row.getChildAt(7).setBackgroundColor(err);
			}
		}
	}

	/**
	 * 情報修正
	 */
	private void fixData() {

		Iterator<Map<String, Object>> itr = mManage.iterator();
		while (itr.hasNext()) {
			Map<String, Object> item = itr.next();
			String[] str = getData(item);
			boolean fix = false;

			// 情報値比較
			if (!str[1].equals(str[2])) {
				fix = true;
			}
			if (!str[3].equals(str[4])) {
				fix = true;
			}
			if (!str[5].equals(str[6])) {
				fix = true;
			}
			if (!str[7].equals(str[8])) {
				fix = true;
			}
			// 情報値修正
			if (fix) {
				int index = str[0].equals("") ? 0 : Integer.parseInt(str[0]);
				// DB情報値変換
				int[] info = { 0, 0, 0, 0 };
				info[0] = str[2].equals("") ? 0 : Integer.parseInt(str[2]);
				info[1] = str[4].equals("") ? 0 : Integer.parseInt(str[4]);
				info[2] = str[6].equals("") ? 0 : Integer.parseInt(str[6]);
				info[3] = str[8].equals("") ? 0 : Integer.parseInt(str[8]);
				// count>0の場合はデータ有り
				if (info[0] > 0) {
					// 設定ファイル情報更新
					Common.modWordbookPref(getApplicationContext(), index,
							null, info, -1);
					item.put(Common.WORDBOOK_COUNT, info[0]);
					item.put(Common.WORDBOOK_ZERO, info[1]);
					item.put(Common.WORDBOOK_OK, info[2]);
					item.put(Common.WORDBOOK_NG, info[3]);
				} else {
					// 設定ファイル情報削除
					Common.delWordbookPref(getApplicationContext(), index);
					itr.remove();
				}
			}
		}

		// 情報表示
		showData();
	}

	/** 整合性確認タスク */
	private AsyncTask<Void, Integer, List<Map<String, Object>>> mTask = null;

	/**
	 * 整合性確認タスク呼び出し
	 */
	private void checkData() {

		// 整合性確認タスク動作時は処理無し
		if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
			Log.w(TAG, "checkData()=RUNNING");
			return;
		}

		// 整合性確認タスク実行
		mTask = new AsyncTask<Void, Integer, List<Map<String, Object>>>() {
			private long st;

			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				Log.d(TAG, "onPreExecute()");

				// 無効化
				mButton.setEnabled(false);
				// 最大値設定
				mProg.setMax(Common.PREF_MAX_SIZE);
				// 初期値設定
				mProg.setProgress(0);
				// プログレスバー表示
				mProg.setVisibility(View.VISIBLE);

				// 処理開始時間
				st = System.currentTimeMillis();
			}

			@Override
			protected void onPostExecute(List<Map<String, Object>> result) {

				// 処理終了時間
				mProc = System.currentTimeMillis() - st;

				if (result.size() > 0) {
					// 情報更新
					mManage.clear();
					mManage.addAll(result);
					// 情報表示
					showData();
				} else {
					// エラー表示
					Message.show(getApplicationContext(),
							Message.ID.DATA_NOT_FOUND);
					// 表示クリア
					mTimer.setText("");
				}

				// プログレスバー非表示
				mProg.setVisibility(View.GONE);
				// 有効化
				mButton.setEnabled(true);

				Log.d(TAG, "onPostExecute()=" + result.size());
				super.onPostExecute(result);
			}

			@Override
			protected void onProgressUpdate(Integer... values) {
				super.onProgressUpdate(values);

				// 現在値設定
				mProg.setProgress(values[0]);
			}

			@Override
			protected List<Map<String, Object>> doInBackground(Void... params) {
				Log.d(TAG, "doInBackground()");

				// 取得結果
				List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
				// 設定ファイル情報
				List<Map<String, Object>> pref = Common
						.getWordbookPrefList(getApplicationContext());

				for (int i = 1; i <= Common.PREF_MAX_SIZE; i++) {
					Map<String, Object> item = new HashMap<String, Object>();
					// 設定ファイル情報確認
					for (Map<String, Object> temp : pref) {
						// indexが一致する場合は該当データ
						if (temp.get(Common.WORDBOOK_INDEX).equals(i)) {
							item.put(Common.WORDBOOK_COUNT,
									temp.get(Common.WORDBOOK_COUNT));
							item.put(Common.WORDBOOK_ZERO,
									temp.get(Common.WORDBOOK_ZERO));
							item.put(Common.WORDBOOK_OK,
									temp.get(Common.WORDBOOK_OK));
							item.put(Common.WORDBOOK_NG,
									temp.get(Common.WORDBOOK_NG));
							item.put(Common.WORDBOOK_TITLE,
									temp.get(Common.WORDBOOK_TITLE));
							break;
						}
					}
					// 単語帳DB情報取得
					int[] db = DBAccess.getDBInfo(getApplicationContext(), i);
					// count>0の場合はデータ有り
					if (db[0] > 0) {
						item.put(DB_COUNT, db[0]);
						item.put(DB_ZERO, db[1]);
						item.put(DB_OK, db[2]);
						item.put(DB_NG, db[3]);
					}
					// データが有る場合は取得結果に追加
					if (item.size() > 0) {
						item.put(Common.WORDBOOK_INDEX, i);
						result.add(item);
					}

					// キャンセル
					if (isCancelled()) {
						return result;
					}
					// プログレスバー更新
					publishProgress(i);
				}

				return result;
			};
		}.execute();

	}

}
