package com.kurukurupapa.tryandroid.fw.util;

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

import android.content.Context;

import com.kurukurupapa.tryandroid.fw.FwException;

public class RUtil {

	public static Class<?> getRIdClass(Class<?> rClass) {
		return getRNestedClass(rClass, "id");
	}

	public static Class<?> getRLayoutClass(Class<?> rClass) {
		return getRNestedClass(rClass, "layout");
	}

	public static Class<?> getRXmlClass(Class<?> rClass) {
		return getRNestedClass(rClass, "xml");
	}

	public static Class<?> getRClass(Context context) {
		String className = context.getPackageName() + ".R";
		Class<?> cls = null;
		try {
			cls = Class.forName(className);
		} catch (ClassNotFoundException e) {
			throw new FwException("className=" + className, e);
		}
		return cls;
	}

	private static Class<?> getRNestedClass(Class<?> rClass,
			String rNestedClassName) {
		Class<?> rNestedClass = null;
		try {
			rNestedClass = Class.forName(rClass.getName() + "$"
					+ rNestedClassName);
		} catch (ClassNotFoundException e) {
			throw new FwException("rClass=" + rClass.getName()
					+ ", rNestedClassName=" + rNestedClassName, e);
		}
		return rNestedClass;
	}

	/**
	 * リソースIDを取得する。
	 *
	 * @param rNestedClass
	 *            対象リソースIDを持っているRクラスの入れ子クラス（例：R.id.class, R.layout.classなど）
	 * @param idName
	 *            リソースIDの文字列名
	 * @return リソースID
	 */
	public static int getResourceId(Class<?> rNestedClass, String idName) {
		Integer resourceId = getResourceIdOrNull(rNestedClass, idName);
		if (resourceId == null) {
			throw new FwException("リソースIDが見つかりませんでした。rNestedClass="
					+ rNestedClass.getName() + ", idName=" + idName);
		}
		return resourceId.intValue();
	}

	/**
	 * リソースIDを取得する。
	 *
	 * @param context
	 * @param nestedClassName
	 *            対象リソースIDを持っているRクラスの入れ子クラス名（例："id","layout"など）
	 * @param idName
	 *            リソースIDの文字列名
	 * @return リソースID
	 */
	public static int getResourceId(Context context, String nestedClassName,
			String idName) {
		return getResourceId(
				getRNestedClass(getRClass(context), nestedClassName), idName);
	}

	/**
	 * リソースIDを取得する。
	 *
	 * @param context
	 * @param nestedClassName
	 *            対象リソースIDを持っているRクラスの入れ子クラス名（例："id","layout"など）
	 * @param idName
	 *            リソースIDの文字列名
	 * @return リソースID
	 */
	public static Integer getResourceIdOrNull(Context context,
			String nestedClassName, String idName) {
		Integer id;
		try {
			id = getResourceIdOrNull(
					getRNestedClass(getRClass(context), nestedClassName),
					idName);
		} catch (RuntimeException e) {
			id = null;
		}
		return id;
	}

	public static Integer getResourceIdOrNull(Class<?> rNestedClass,
			String idName) {
		// 存在チェック
		if (!ReflectionUtil.containField(rNestedClass, idName)) {
			return null;
		}
		// 値取得
		return Integer.valueOf(ReflectionUtil.getStaticFieldValue(rNestedClass,
				idName).toString());
	}

	/**
	 * 正規表現に一致するリソースIDを取得する。
	 *
	 * @param obj
	 *            対象リソースIDを持っているオブジェクト（例：new R.id(), new R.id(), など）
	 * @param name
	 *            リソースIDの正規表現文字列名
	 * @return リソースID配列
	 */
	public static int[] findResourceIds(Object obj, String regex) {
		List<Integer> list = new ArrayList<Integer>();
		for (Field e : ReflectionUtil.findFields(obj, regex)) {
			list.add(ReflectionUtil.getIntFieldValue(obj, e));
		}
		return FwUtil.toPrimitiveArray(list);
	}

	// public static String getResourceName(Object obj, int id) {
	// try {
	// List<String> list = ReflectionUtil.findIntFieldName(obj, id);
	// if (list.size() == 1) {
	// return list.get(0);
	// }
	// } catch (Exception ex) {
	// LogUtil.w("obj=" + obj.getClass().getName() + ",id=" + id, ex);
	// }
	// return null;
	// }
}
