package com.tryandroid.etc;

import java.util.Collections;
import java.util.List;

import com.kurukurupapa.tryandroid.fw.util.ActivityUtil;
import com.kurukurupapa.tryandroid.fw.util.LogUtil;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Spinner;

public class AppListActivity extends Activity implements
		OnItemSelectedListener, OnItemClickListener {
	public Spinner modeSpinner;
	public ListView listView;

	private static final int MODE_INSTALL = 0;
	private static final int MODE_RUNNING_APP = 1;
	private static final int MODE_RUNNING_SERVICE = 2;
	private static final int MODE_RUNNING_TASK = 3;

	private List<?> list;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		LogUtil.called();

		ActivityUtil.initializeActivity(this);
		modeSpinner.setOnItemSelectedListener(this);
		modeSpinner.setSelection(1);
		listView.setOnItemClickListener(this);
		updateContent();
	}

	private void updateContent() {
		int position = modeSpinner.getSelectedItemPosition();
		LogUtil.d("position=" + position);

		switch (position) {
		// インストール済みアプリの場合
		case MODE_INSTALL:
			updateInstalledApp();
			break;

		// 実行中アプリの場合
		case MODE_RUNNING_APP:
			updateRunningApp();
			break;

		// 実行中サービスの場合
		case MODE_RUNNING_SERVICE:
			updateRunningService();
			break;

		// 実行中タスクの場合
		case MODE_RUNNING_TASK:
			updateRunningTask();
			break;
		}
	}

	private void updateInstalledApp() {
		// インテント作成
		Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
		mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

		// アプリ一覧取得
		PackageManager pm = getPackageManager();
		List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(
				mainIntent, 0);
		list = resolveInfoList;
		Collections.sort(resolveInfoList,
				new ResolveInfo.DisplayNameComparator(pm));

		// レイアウト用アダプター作成
		ListAdapter adapter = new ResolveInfoListAdapter(this, resolveInfoList);
		listView.setAdapter(adapter);
	}

	private void updateRunningApp() {
		ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

		List<RunningAppProcessInfo> processInfoList = am
				.getRunningAppProcesses();
		list = processInfoList;

		ListAdapter adapter = new RunningAppProcessInfoListAdapter(this,
				processInfoList);
		listView.setAdapter(adapter);
	}

	private void updateRunningService() {
		ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

		List<RunningServiceInfo> serviceInfoList = am.getRunningServices(100);
		list = serviceInfoList;

		ListAdapter adapter = new RunningServiceInfoListAdapter(this,
				serviceInfoList);
		listView.setAdapter(adapter);
	}

	private void updateRunningTask() {
		ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

		// AndroidMarket.xmlに"android.permission.GET_TASKS"権限が必要
		List<RunningTaskInfo> taskInfoList = am.getRunningTasks(100);
		list = taskInfoList;

		ListAdapter adapter = new RunningTaskInfoListAdapter(this, taskInfoList);
		listView.setAdapter(adapter);
	}

	@Override
	public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
			long arg3) {
		LogUtil.called();

		if (arg0 == modeSpinner) {
			updateContent();
		}
	}

	@Override
	public void onNothingSelected(AdapterView<?> arg0) {
		LogUtil.called();
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position,
			long id) {
		LogUtil.called();

		if (arg0 == listView) {
			int mode = modeSpinner.getSelectedItemPosition();
			LogUtil.d("mode=" + position);

			switch (mode) {
			// インストール済みアプリの場合
			case MODE_INSTALL:
				startInstalledApp((ResolveInfo) list.get(position));
				break;

			// 実行中アプリの場合
			case MODE_RUNNING_APP:
				startRunningApp((RunningAppProcessInfo) list.get(position));
				break;

			// 実行中サービスの場合
			case MODE_RUNNING_SERVICE:
				startRunningServiceInfo((RunningServiceInfo) list.get(position));
				break;

			// 実行中タスクの場合
			case MODE_RUNNING_TASK:
				startRunningTask((RunningTaskInfo) list.get(position));
				break;
			}
		}
	}

	private void startInstalledApp(ResolveInfo resolveInfo) {
		startActivity(resolveInfo.activityInfo.packageName,
				resolveInfo.activityInfo.name);
	}

	private void startRunningApp(RunningAppProcessInfo processInfo) {
		PackageManager pm = getPackageManager();

		try {
			// ApplicationInfo appInfo = pm.getApplicationInfo(
			// processInfo.processName, 0);

			// NG
			// startActivity(appInfo.packageName, appInfo.className);

			// NG
			// ActivityInfo activityInfo = pm.getActivityInfo(new ComponentName(
			// appInfo.packageName, appInfo.className), 0);
			// startActivity(activityInfo.packageName, activityInfo.name);

			// NG
			// ActivityInfo activityInfo = pm.getActivityInfo(new ComponentName(
			// appInfo.packageName, appInfo.className), 0);
			// Intent intent = pm
			// .getLaunchIntentForPackage(activityInfo.packageName);
			// startActivity(intent);

			// OK
			// processNameは、packageNameと同じようなので、引数に設定。
			Intent intent = pm
					.getLaunchIntentForPackage(processInfo.processName);
			startActivity(intent);

			// } catch (NameNotFoundException e) {
			// ActivityUtil.showDialog(this, "実行中アプリ情報の取得失敗", e.getMessage());
		} catch (Exception e) {
			ActivityUtil.showDialog(this, "実行中アプリ情報の取得失敗", e.getMessage());
		}
	}

	private void startRunningServiceInfo(RunningServiceInfo serviceInfo) {
		startActivity(serviceInfo.service.getPackageName(),
				serviceInfo.service.getClassName());
	}

	private void startRunningTask(RunningTaskInfo taskInfo) {
		startActivity(taskInfo.topActivity.getPackageName(),
				taskInfo.topActivity.getClassName());
	}

	private void startActivity(String packageName, String className) {
		try {
			Intent intent = new Intent();
			intent.setClassName(packageName, className);
			startActivity(intent);
		} catch (ActivityNotFoundException e) {
			ActivityUtil.showDialog(this, "起動失敗", "packageName=" + packageName
					+ "\nclassName=" + className + "\ne=" + e.getMessage());
		} catch (Exception e) {
			ActivityUtil.showDialog(this, "起動失敗", "packageName=" + packageName
					+ "\nclassName=" + className + "\ne=" + e.getMessage());
		}
	}
}