/*
 * Copyright (C) 2005-2006 Kouji Sugisawa. Ltd. All rights reserved.
 */

package jp.sourceforge.livez.lang;

import org.apache.commons.lang.StringUtils;

/**
 * EZweb の絵文字に関するユーティリティクラスです。<p>
 * 
 * @author 杉澤 浩二
 */
public final class EZwebEmojiUtils {

	private static final char BLANK = '\u0000';

	/**
	 * 絵文字一覧です。
	 */
	private static final String EMOJI_TABLE = "" + BLANK +
		// 1〜16
		"\uE481\uE482\uE483\uE52C\uE52D\uE52E\uE52F\uE530\uE531\uE532\uE533\uE4C1\uE511\uE579\uE486\uE487" +
		// 17〜32
		"\uE534\uE535\uE536\uE537\uE538\uE539\uE53A\uE53B\uE57A\uE53C\uE53D\uE53E\uE53F\uE540\uE541\uE542" +
		// 33〜48
		"\uE543\uE544\uE545\uE546\uE547\uE548\uE549\uE54A\uE54B\uE54C\uE54D\uE488\uE4BA\uE594\uE489\uE512" +
		// 49〜64
		"\uE560\uE4FA\uE595\uE4C2\uE513\uE54E\uE54F\uE561\uE57B\uE47C\uE562\uE48A\uE550\uE551\uE552\uE553" +
		// 65〜80
		"\uE4C3\uE554\uE563\uE4FB\uE48B\uE555\uE556\uE514\uE557\uE4DF\uE468\uE46C\uE476\uE4E0\uE58F\uE4FC" +
		// 81〜96
		"\uE558\uE559\uE49C\uE590\uE596\uE4FD\uE57C\uE55A\uE55B\uE573\uE49D\uE564\uE597\uE515\uE48C\uE4BB" +
		// 97〜112
		"\uE565\uE484\uE46A\uE566\uE567\uE568\uE569\uE516\uE56A\uE49E\uE48D\uE521\uE57D\uE517\uE57E\uE4AB" +
		// 113〜128
		"\uE4E4\uE57F\uE580\uE4FE\uE55C\uE55D\uE518\uE519\uE56B\uE49F\uE581\uE51A\uE4Ba\uE582\uE574\uE575" +
		// 129〜144
		"\uE51B\uE583\uE56C\uE55E\uE4CE\uE4E1\uE584\uE55F\uE56D\uE51C\uE585\uE4FF\uE500\uE56E\uE4A0\uE4CF" +
		// 145〜160
		"\uE51D\uE4AC\uE56F\uE4B2\uE4A1\uE586\uE591\uE587\uE592\uE593\uE51E\uE4AD\uE570\uE4A2\uE576\uE4C4" +
		// 161〜176
		"\uE588\uE589\uE501\uE58A\uE51F\uE520\uE48E\uE4B3\uE4B4\uE4C8\uE58B\uE4B5\uE58C\uE58D\uE58E\uE47D" +
		// 177〜192
		"\uE47E\uE47F\uE480\uE522\uE523\uE524\uE525\uE526\uE527\uE528\uE529\uE52A\uE52B\uE469\uE485\uE48F" +
		// 193〜208
		"\uE490\uE491\uE492\uE493\uE494\uE495\uE496\uE497\uE498\uE499\uE49A\uE49B\uE4A3\uE4A4\uE4A5\uE4A6" +
		// 209〜224
		"\uE4A7\uE4A8\uE4A9\uE4AA\uE571\uE572\uE4AE\uE4AF\uE4B0\uE46B\uE4B6\uE4B7\uE4B8\uE4B9\uE46D\uE4BC" +
		// 225〜240
		"\uE4BD\uE4BE\uE4BF\uE4C0\uE46E\uE46F\uE4C5\uE4C6\uE4C7\uE4C9\uE4CA\uE4CB\uE4CC\uE4CD\uE4D0\uE4D1" +
		// 241〜256
		"\uE4D2\uE4D3\uE4D4\uE4D5\uE4D6\uE470\uE4D7\uE4D8\uE4D9\uE4DA\uE4DB\uE4DC\uE4DD\uE4DE\uE4E2\uE4E3" +
		// 257〜272
		"\uE471\uE472\uE473\uE474\uE475\uE4E5\uE4E6\uE4E7\uE477\uE478\uE479\uE47A\uE47B\uE4E8\uE4E9\uE4EA" +
		// 273〜288
		"\uE4EB\uE4EC\uE4ED\uE4EE\uE4EF\uE4F0\uE4F1\uE4F2\uE4F3\uE4F4\uE4F5\uE4F6\uE4F7\uE4F8\uE4F9\uE502" +
		// 289〜304
		"\uE503\uE504\uE505\uE506\uE507\uE508\uE509\uE50A\uE50B\uE577\uE578\uE50C\uE50D\uE50E\uE50F\uE510" +
		// 305〜320
		"\uE598\uE599\uE59A\uE59B\uE59C\uE59D\uE59E\uE59F\uE5A0\uE5A1\uE5A2\uE5A3\uE5A4\uE5A5\uE5A6\uE5A7" +
		// 321〜336
		"\uE5A8\uE5A9\uE5AA\uE5AB\uE5AC\uE5AD\uE5AE\uE5AF\uE5B0\uE5B1\uE5B2\uE5B3\uE5B4\uE5B5\uE5B6\uE5B7" +
		// 337〜352
		"\uE5B8\uE5B9\uE5BA\uE5BB\uE5BC\uE5BD\uE5BE\uE5BF\uE5C0\uE5C1\uE5C2\uE5C3\uE5C4\uE5C5\uE5C6\uE5C7" +
		// 353〜368
		"\uE5C8\uE5C9\uE5CA\uE5CB\uE5CC\uE5CD\uE5CE\uE5CF\uE5D0\uE5D1\uE5D2\uE5D3\uE5D4\uE5D5\uE5D6\uE5D7" +
		// 369〜384
		"\uE5D8\uE5D9\uE5DA\uE5DB\uE5DC\uE5DD\uE5DE\uE5DF\uEA80\uEA81\uEA82\uEA83\uEA84\uEA85\uEA86\uEA87" +
		// 385〜400
		"\uEA88\uEA89\uEA8A\uEA8B\uEA8C\uEA8D\uEA8E\uEA8F\uEA90\uEA91\uEA92\uEA93\uEA94\uEA95\uEA96\uEA97" +
		// 401〜416
		"\uEA98\uEA99\uEA9A\uEA9B\uEA9C\uEA9D\uEA9E\uEA9F\uEAA0\uEAA1\uEAA2\uEAA3\uEAA4\uEAA5\uEAA6\uEAA7" +
		// 417〜432
		"\uEAA8\uEAA9\uEAAA\uEAAB\uEAAC\uEAAD\uEAAE\uEAAF\uEAB0\uEAB1\uEAB2\uEAB3\uEAB4\uEAB5\uEAB6\uEAB7" +
		// 433〜448
		"\uEAB8\uEAB9\uEABA\uEABB\uEABC\uEABD\uEABE\uEABF\uEAC0\uEAC1\uEAC2\uEAC3\uEAC4\uEAC5\uEAC6\uEAC7" +
		// 449〜464
		"\uEAC8\uEAC9\uEACA\uEACB\uEACC\uEACD\uEACE\uEACF\uEAD0\uEAD1\uEAD2\uEAD3\uEAD4\uEAD5\uEAD6\uEAD7" +
		// 465〜480
		"\uEAD8\uEAD9\uEADA\uEADB\uEADC\uEADD\uEADE\uEADF\uEAE0\uEAE1\uEAE2\uEAE3\uEAE4\uEAE5\uEAE6\uEAE7" +
		// 481〜496
		"\uEAE8\uEAE9\uEAEA\uEAEB\uEAEC\uEAED\uEAEE\uEAEF\uEAF0\uEAF1\uEAF2\uEAF3\uEAF4\uEAF5\uEAF6\uEAF7" +
		// 497〜512
		"\uEAF8\uEAF9\uEAFA\uEAFB\uEAFC\uEAFD\uEAFE\uEAFF\uEB00\uEB01\uEB02\uEB03\uEB04\uEB05\uEB06\uEB07" +
		// 513〜518
		"\uEB08\uEB09\uEB0A\uEB0B\uEB0C\uEB0D" + StringUtils.repeat(String.valueOf(BLANK), 700 - 518 - 1) +
		// 700〜715
		"\uEB0E\uEB0F\uEB10\uEB11\uEB12\uEB13\uEB14\uEB15\uEB16\uEB17\uEB18\uEB19\uEB1A\uEB1B\uEB1C\uEB1D" +
		// 716〜731
		"\uEB1E\uEB1F\uEB20\uEB21\uEB22\uEB23\uEB24\uEB25\uEB26\uEB27\uEB28\uEB29\uEB2A\uEB2B\uEB2C\uEB2D" +
		// 732〜747
		"\uEB2E\uEB2F\uEB30\uEB31\uEB32\uEB33\uEB34\uEB35\uEB36\uEB37\uEB38\uEB39\uEB3A\uEB3B\uEB3C\uEB3D" +
		// 748〜763
		"\uEB3E\uEB3F\uEB40\uEB41\uEB42\uEB43\uEB44\uEB45\uEB46\uEB47\uEB48\uEB49\uEB4A\uEB4B\uEB4C\uEB4D" +
		// 764〜779
		"\uEB4E\uEB4F\uEB50\uEB51\uEB52\uEB53\uEB54\uEB55\uEB56\uEB57\uEB58\uEB59\uEB5A\uEB5B\uEB5C\uEB5D" +
		// 780〜795
		"\uEB5E\uEB5F\uEB60\uEB61\uEB62\uEB63\uEB64\uEB65\uEB66\uEB67\uEB68\uEB69\uEB6A\uEB6B\uEB6C\uEB6D" +
		// 796〜811
		"\uEB6E\uEB6F\uEB70\uEB71\uEB72\uEB73\uEB74\uEB75\uEB76\uEB77\uEB78\uEB79\uEB7A\uEB7B\uEB7C\uEB7D" +
		// 812〜822
		"\uEB7E\uEB7F\uEB80\uEB81\uEB82\uEB83\uEB84\uEB85\uEB86\uEB87\uEB88";

	/**
	 * インスタンス化できない事を強制します。<p>
	 */
	private EZwebEmojiUtils() {}

	/**
	 * 絵文字番号の最大番号を返します。<p>
	 * 
	 * @return 絵文字番号の最大番号
	 */
	public static int getMaxEmojiNumber() {
		return EMOJI_TABLE.length() - 1;
	}

	/**
	 * 指定された文字に対応する絵文字番号を返します。<p>
	 * 対応する絵文字番号が見つからない場合は、<code>-1</code> が返されます。
	 * 
	 * @param c 文字
	 * @return 対応する絵文字番号。見つからない場合は <code>-1</code>
	 */
	public static int toEmojiNumber(final char c) {
		if (c == BLANK)
			return -1;

		return EMOJI_TABLE.indexOf(c);
	}

	/**
	 * 指定された絵文字番号に対応する絵文字を返します。<p>
	 * 
	 * @param n 絵文字番号
	 * @return 絵文字
	 * @throws IllegalArgumentException 絵文字番号の値が不正な場合
	 */
	public static char toChar(final int n) throws IllegalArgumentException {
		try {
			char c = EMOJI_TABLE.charAt(n);

			if (c == BLANK)
				throw new IllegalArgumentException("EZweb icon number " + n + " is not found.");

			return c;
		} catch (IndexOutOfBoundsException e) {
			throw new IllegalArgumentException("EZweb icon number " + n + " is not found.", e);
		}
	}

	/**
	 * 指定された絵文字番号に対応する絵文字を返します。<p>
	 * 
	 * @param n 絵文字番号
	 * @return 絵文字
	 * @throws IllegalArgumentException 絵文字番号の値が不正な場合
	 */
	public static String toString(final int n) throws IllegalArgumentException {
		return String.valueOf(toChar(n));
	}

	/**
	 * 指定された文字が EZweb 絵文字かどうかを返します。<p>
	 * 
	 * @param c 文字
	 * @return 絵文字の場合 true を、それ以外の場合 false を返します。
	 */
	public static boolean isEmoji(final char c) {
		return toEmojiNumber(c) > -1;
	}

	/**
	 * 指定された文字列中に EZweb 絵文字が存在するかどうかを返します。<p>
	 * 
	 * @param s 文字列
	 * @return EZweb 絵文字が存在する場合 true を、それ以外の場合 false を返します。
	 */
	public static boolean isEmoji(final String s) {
		if (s == null)
			return false;

		for (int i = 0; i < s.length(); i++) {
			if (isEmoji(s.charAt(i)))
				return true;
		}

		return false;
	}

	/**
	 * 指定された文字列から EZweb 絵文字を削除して返します。<p>
	 * 指定された文字列が <code>null</code> の場合は、<code>null</code> を返します。
	 * 
	 * @param s 文字列
	 * @return EZweb 絵文字が削除された文字列。又は null
	 */
	public static String removeEmoji(final String s) {
		if (s == null)
			return null;

		StringBuilder result = new StringBuilder(s.length());

		for (int i = 0; i < s.length(); i++) {
			final char c = s.charAt(i);
			if (!isEmoji(c))
				result.append(c);
		}

		return result.toString();
	}

	public static int toEmojiNumber(final String s) throws IllegalArgumentException {
		if (StringUtils.isEmpty(s))
			throw new IllegalArgumentException();

		return toEmojiNumber(s.charAt(0));
	}

	/**
	 * ユーザによる入力が可能な絵文字の絵文字番号です。<p>
	 */
	private static final String ALLOW_INPUT = "" +
		EMOJI_TABLE.charAt(1) +
		EMOJI_TABLE.charAt(2) +
		EMOJI_TABLE.charAt(3) +

		EMOJI_TABLE.charAt(12) +
		EMOJI_TABLE.charAt(13) +

		EMOJI_TABLE.charAt(15) +
		EMOJI_TABLE.charAt(16) +

		EMOJI_TABLE.charAt(29) +
		EMOJI_TABLE.charAt(30) +

		EMOJI_TABLE.charAt(42) +
		EMOJI_TABLE.charAt(43) +
		EMOJI_TABLE.charAt(44) +
		EMOJI_TABLE.charAt(45) +
		EMOJI_TABLE.charAt(46) +
		EMOJI_TABLE.charAt(47) +
		EMOJI_TABLE.charAt(48) +

		EMOJI_TABLE.charAt(50) +
		EMOJI_TABLE.charAt(51) +
		EMOJI_TABLE.charAt(52) +
		EMOJI_TABLE.charAt(53) +

		EMOJI_TABLE.charAt(58) +

		EMOJI_TABLE.charAt(60) +
		EMOJI_TABLE.charAt(61) +

		EMOJI_TABLE.charAt(63) +
		EMOJI_TABLE.charAt(64) +
		EMOJI_TABLE.charAt(65) +

		EMOJI_TABLE.charAt(68) +
		EMOJI_TABLE.charAt(69) +
		EMOJI_TABLE.charAt(70) +
		EMOJI_TABLE.charAt(71) +
		EMOJI_TABLE.charAt(72) +

		EMOJI_TABLE.charAt(74) +
		EMOJI_TABLE.charAt(75) +
		EMOJI_TABLE.charAt(76) +
		EMOJI_TABLE.charAt(77) +
		EMOJI_TABLE.charAt(78) +

		EMOJI_TABLE.charAt(80) +

		EMOJI_TABLE.charAt(83) +

		EMOJI_TABLE.charAt(85) +
		EMOJI_TABLE.charAt(86) +

		EMOJI_TABLE.charAt(90) +
		EMOJI_TABLE.charAt(91) +

		EMOJI_TABLE.charAt(93) +
		EMOJI_TABLE.charAt(94) +
		EMOJI_TABLE.charAt(95) +
		EMOJI_TABLE.charAt(96) +

		EMOJI_TABLE.charAt(98) +
		EMOJI_TABLE.charAt(99) +

		EMOJI_TABLE.charAt(104) +

		EMOJI_TABLE.charAt(106) +
		EMOJI_TABLE.charAt(107) +
		EMOJI_TABLE.charAt(108) +

		EMOJI_TABLE.charAt(110) +

		EMOJI_TABLE.charAt(112) +
		EMOJI_TABLE.charAt(113) +

		EMOJI_TABLE.charAt(115) +
		EMOJI_TABLE.charAt(116) +

		EMOJI_TABLE.charAt(119) +
		EMOJI_TABLE.charAt(120) +

		EMOJI_TABLE.charAt(122) +

		EMOJI_TABLE.charAt(124) +
		EMOJI_TABLE.charAt(125) +
		EMOJI_TABLE.charAt(126) +

		EMOJI_TABLE.charAt(129) +

		EMOJI_TABLE.charAt(133) +
		EMOJI_TABLE.charAt(134) +

		EMOJI_TABLE.charAt(138) +

		EMOJI_TABLE.charAt(140) +
		EMOJI_TABLE.charAt(141) +

		EMOJI_TABLE.charAt(143) +
		EMOJI_TABLE.charAt(144) +
		EMOJI_TABLE.charAt(145) +
		EMOJI_TABLE.charAt(146) +

		EMOJI_TABLE.charAt(148) +
		EMOJI_TABLE.charAt(149) +

		EMOJI_TABLE.charAt(151) +

		EMOJI_TABLE.charAt(156) +

		EMOJI_TABLE.charAt(158) +

		EMOJI_TABLE.charAt(160) +
		EMOJI_TABLE.charAt(161) +

		EMOJI_TABLE.charAt(163) +

		EMOJI_TABLE.charAt(165) +
		EMOJI_TABLE.charAt(166) +
		EMOJI_TABLE.charAt(167) +
		EMOJI_TABLE.charAt(168) +
		EMOJI_TABLE.charAt(169) +
		EMOJI_TABLE.charAt(170) +

		EMOJI_TABLE.charAt(172) +

		EMOJI_TABLE.charAt(176) +
		EMOJI_TABLE.charAt(177) +
		EMOJI_TABLE.charAt(178) +
		EMOJI_TABLE.charAt(179) +

		EMOJI_TABLE.charAt(190) +
		EMOJI_TABLE.charAt(191) +
		EMOJI_TABLE.charAt(192) +
		EMOJI_TABLE.charAt(193) +
		EMOJI_TABLE.charAt(194) +
		EMOJI_TABLE.charAt(195) +
		EMOJI_TABLE.charAt(196) +
		EMOJI_TABLE.charAt(197) +
		EMOJI_TABLE.charAt(198) +
		EMOJI_TABLE.charAt(199) +
		EMOJI_TABLE.charAt(200) +
		EMOJI_TABLE.charAt(201) +
		EMOJI_TABLE.charAt(202) +
		EMOJI_TABLE.charAt(203) +
		EMOJI_TABLE.charAt(204) +
		EMOJI_TABLE.charAt(205) +
		EMOJI_TABLE.charAt(206) +
		EMOJI_TABLE.charAt(207) +
		EMOJI_TABLE.charAt(208) +
		EMOJI_TABLE.charAt(209) +
		EMOJI_TABLE.charAt(210) +
		EMOJI_TABLE.charAt(211) +
		EMOJI_TABLE.charAt(212) +
		EMOJI_TABLE.charAt(213) +
		EMOJI_TABLE.charAt(214) +
		EMOJI_TABLE.charAt(215) +
		EMOJI_TABLE.charAt(216) +
		EMOJI_TABLE.charAt(217) +
		EMOJI_TABLE.charAt(218) +
		EMOJI_TABLE.charAt(219) +
		EMOJI_TABLE.charAt(220) +
		EMOJI_TABLE.charAt(221) +
		EMOJI_TABLE.charAt(222) +
		EMOJI_TABLE.charAt(223) +
		EMOJI_TABLE.charAt(224) +
		EMOJI_TABLE.charAt(225) +
		EMOJI_TABLE.charAt(226) +
		EMOJI_TABLE.charAt(227) +
		EMOJI_TABLE.charAt(228) +
		EMOJI_TABLE.charAt(229) +
		EMOJI_TABLE.charAt(230) +
		EMOJI_TABLE.charAt(231) +
		EMOJI_TABLE.charAt(232) +
		EMOJI_TABLE.charAt(233) +
		EMOJI_TABLE.charAt(234) +
		EMOJI_TABLE.charAt(235) +
		EMOJI_TABLE.charAt(236) +
		EMOJI_TABLE.charAt(237) +
		EMOJI_TABLE.charAt(238) +
		EMOJI_TABLE.charAt(239) +
		EMOJI_TABLE.charAt(240) +
		EMOJI_TABLE.charAt(241) +
		EMOJI_TABLE.charAt(242) +
		EMOJI_TABLE.charAt(243) +
		EMOJI_TABLE.charAt(244) +
		EMOJI_TABLE.charAt(245) +
		EMOJI_TABLE.charAt(246) +
		EMOJI_TABLE.charAt(247) +
		EMOJI_TABLE.charAt(248) +
		EMOJI_TABLE.charAt(249) +
		EMOJI_TABLE.charAt(250) +
		EMOJI_TABLE.charAt(251) +
		EMOJI_TABLE.charAt(252) +
		EMOJI_TABLE.charAt(253) +
		EMOJI_TABLE.charAt(254) +
		EMOJI_TABLE.charAt(255) +
		EMOJI_TABLE.charAt(256) +
		EMOJI_TABLE.charAt(257) +
		EMOJI_TABLE.charAt(258) +
		EMOJI_TABLE.charAt(259) +
		EMOJI_TABLE.charAt(260) +
		EMOJI_TABLE.charAt(261) +
		EMOJI_TABLE.charAt(262) +
		EMOJI_TABLE.charAt(263) +
		EMOJI_TABLE.charAt(264) +
		EMOJI_TABLE.charAt(265) +
		EMOJI_TABLE.charAt(266) +
		EMOJI_TABLE.charAt(267) +
		EMOJI_TABLE.charAt(268) +
		EMOJI_TABLE.charAt(269) +
		EMOJI_TABLE.charAt(270) +
		EMOJI_TABLE.charAt(271) +
		EMOJI_TABLE.charAt(272) +
		EMOJI_TABLE.charAt(273) +
		EMOJI_TABLE.charAt(274) +
		EMOJI_TABLE.charAt(275) +
		EMOJI_TABLE.charAt(276) +
		EMOJI_TABLE.charAt(277) +
		EMOJI_TABLE.charAt(278) +
		EMOJI_TABLE.charAt(279) +
		EMOJI_TABLE.charAt(280) +
		EMOJI_TABLE.charAt(281) +
		EMOJI_TABLE.charAt(282) +
		EMOJI_TABLE.charAt(283) +
		EMOJI_TABLE.charAt(284) +
		EMOJI_TABLE.charAt(285) +
		EMOJI_TABLE.charAt(286) +
		EMOJI_TABLE.charAt(287) +
		EMOJI_TABLE.charAt(288) +
		EMOJI_TABLE.charAt(289) +
		EMOJI_TABLE.charAt(290) +
		EMOJI_TABLE.charAt(291) +
		EMOJI_TABLE.charAt(292) +
		EMOJI_TABLE.charAt(293) +
		EMOJI_TABLE.charAt(294) +
		EMOJI_TABLE.charAt(295) +
		EMOJI_TABLE.charAt(296) +
		EMOJI_TABLE.charAt(297) +

		EMOJI_TABLE.charAt(300) +
		EMOJI_TABLE.charAt(301) +
		EMOJI_TABLE.charAt(302) +
		EMOJI_TABLE.charAt(303) +
		EMOJI_TABLE.charAt(304) +

		EMOJI_TABLE.charAt(306) +
		EMOJI_TABLE.charAt(307) +

		EMOJI_TABLE.charAt(309) +

		EMOJI_TABLE.charAt(312) +
		EMOJI_TABLE.charAt(313) +
		EMOJI_TABLE.charAt(314) +
		EMOJI_TABLE.charAt(315) +
		EMOJI_TABLE.charAt(316) +
		EMOJI_TABLE.charAt(317) +
		EMOJI_TABLE.charAt(318) +
		EMOJI_TABLE.charAt(319) +
		EMOJI_TABLE.charAt(320) +

		EMOJI_TABLE.charAt(328) +
		EMOJI_TABLE.charAt(329) +
		EMOJI_TABLE.charAt(330) +
		EMOJI_TABLE.charAt(331) +
		EMOJI_TABLE.charAt(332) +
		EMOJI_TABLE.charAt(333) +
		EMOJI_TABLE.charAt(334) +
		EMOJI_TABLE.charAt(335) +
		EMOJI_TABLE.charAt(336) +
		EMOJI_TABLE.charAt(337) +

		EMOJI_TABLE.charAt(339) +
		EMOJI_TABLE.charAt(340) +
		EMOJI_TABLE.charAt(341) +
		EMOJI_TABLE.charAt(342) +
		EMOJI_TABLE.charAt(343) +
		EMOJI_TABLE.charAt(344) +
		EMOJI_TABLE.charAt(345) +
		EMOJI_TABLE.charAt(346) +
		EMOJI_TABLE.charAt(347) +
		EMOJI_TABLE.charAt(348) +
		EMOJI_TABLE.charAt(349) +
		EMOJI_TABLE.charAt(350) +
		EMOJI_TABLE.charAt(351) +
		EMOJI_TABLE.charAt(352) +
		EMOJI_TABLE.charAt(353) +
		EMOJI_TABLE.charAt(354) +
		EMOJI_TABLE.charAt(355) +
		EMOJI_TABLE.charAt(356) +
		EMOJI_TABLE.charAt(357) +
		EMOJI_TABLE.charAt(358) +
		EMOJI_TABLE.charAt(359) +
		EMOJI_TABLE.charAt(360) +
		EMOJI_TABLE.charAt(361) +
		EMOJI_TABLE.charAt(362) +
		EMOJI_TABLE.charAt(363) +
		EMOJI_TABLE.charAt(364) +
		EMOJI_TABLE.charAt(365) +

		EMOJI_TABLE.charAt(368) +
		EMOJI_TABLE.charAt(369) +
		EMOJI_TABLE.charAt(370) +
		EMOJI_TABLE.charAt(371) +
		EMOJI_TABLE.charAt(372) +
		EMOJI_TABLE.charAt(373) +
		EMOJI_TABLE.charAt(374) +
		EMOJI_TABLE.charAt(375) +
		EMOJI_TABLE.charAt(376) +
		EMOJI_TABLE.charAt(377) +
		EMOJI_TABLE.charAt(378) +
		EMOJI_TABLE.charAt(379) +
		EMOJI_TABLE.charAt(380) +
		EMOJI_TABLE.charAt(381) +
		EMOJI_TABLE.charAt(382) +
		EMOJI_TABLE.charAt(383) +

		EMOJI_TABLE.charAt(386) +
		EMOJI_TABLE.charAt(387) +
		EMOJI_TABLE.charAt(388) +
		EMOJI_TABLE.charAt(389) +
		EMOJI_TABLE.charAt(390) +
		EMOJI_TABLE.charAt(391) +
		EMOJI_TABLE.charAt(392) +
		EMOJI_TABLE.charAt(393) +
		EMOJI_TABLE.charAt(394) +
		EMOJI_TABLE.charAt(395) +
		EMOJI_TABLE.charAt(396) +
		EMOJI_TABLE.charAt(397) +
		EMOJI_TABLE.charAt(398) +
		EMOJI_TABLE.charAt(399) +
		EMOJI_TABLE.charAt(400) +
		EMOJI_TABLE.charAt(401) +
		EMOJI_TABLE.charAt(402) +
		EMOJI_TABLE.charAt(403) +
		EMOJI_TABLE.charAt(404) +
		EMOJI_TABLE.charAt(405) +
		EMOJI_TABLE.charAt(406) +
		EMOJI_TABLE.charAt(407) +
		EMOJI_TABLE.charAt(408) +
		EMOJI_TABLE.charAt(409) +
		EMOJI_TABLE.charAt(410) +
		EMOJI_TABLE.charAt(411) +
		EMOJI_TABLE.charAt(412) +
		EMOJI_TABLE.charAt(413) +
		EMOJI_TABLE.charAt(414) +
		EMOJI_TABLE.charAt(415) +
		EMOJI_TABLE.charAt(416) +
		EMOJI_TABLE.charAt(417) +
		EMOJI_TABLE.charAt(418) +
		EMOJI_TABLE.charAt(419) +
		EMOJI_TABLE.charAt(420) +
		EMOJI_TABLE.charAt(421) +
		EMOJI_TABLE.charAt(422) +
		EMOJI_TABLE.charAt(423) +
		EMOJI_TABLE.charAt(424) +
		EMOJI_TABLE.charAt(425) +
		EMOJI_TABLE.charAt(426) +
		EMOJI_TABLE.charAt(427) +
		EMOJI_TABLE.charAt(428) +
		EMOJI_TABLE.charAt(429) +
		EMOJI_TABLE.charAt(430) +
		EMOJI_TABLE.charAt(431) +
		EMOJI_TABLE.charAt(432) +
		EMOJI_TABLE.charAt(433) +
		EMOJI_TABLE.charAt(434) +
		EMOJI_TABLE.charAt(435) +
		EMOJI_TABLE.charAt(436) +
		EMOJI_TABLE.charAt(437) +
		EMOJI_TABLE.charAt(438) +
		EMOJI_TABLE.charAt(439) +
		EMOJI_TABLE.charAt(440) +
		EMOJI_TABLE.charAt(441) +
		EMOJI_TABLE.charAt(442) +
		EMOJI_TABLE.charAt(443) +
		EMOJI_TABLE.charAt(444) +
		EMOJI_TABLE.charAt(445) +
		EMOJI_TABLE.charAt(446) +
		EMOJI_TABLE.charAt(447) +
		EMOJI_TABLE.charAt(448) +
		EMOJI_TABLE.charAt(449) +
		EMOJI_TABLE.charAt(450) +
		EMOJI_TABLE.charAt(451) +
		EMOJI_TABLE.charAt(452) +
		EMOJI_TABLE.charAt(453) +
		EMOJI_TABLE.charAt(454) +
		EMOJI_TABLE.charAt(455) +
		EMOJI_TABLE.charAt(456) +
		EMOJI_TABLE.charAt(457) +
		EMOJI_TABLE.charAt(458) +
		EMOJI_TABLE.charAt(459) +
		EMOJI_TABLE.charAt(460) +
		EMOJI_TABLE.charAt(461) +
		EMOJI_TABLE.charAt(462) +
		EMOJI_TABLE.charAt(463) +
		EMOJI_TABLE.charAt(464) +
		EMOJI_TABLE.charAt(465) +
		EMOJI_TABLE.charAt(466) +
		EMOJI_TABLE.charAt(467) +
		EMOJI_TABLE.charAt(468) +
		EMOJI_TABLE.charAt(469) +
		EMOJI_TABLE.charAt(470) +
		EMOJI_TABLE.charAt(471) +
		EMOJI_TABLE.charAt(472) +
		EMOJI_TABLE.charAt(473) +
		EMOJI_TABLE.charAt(474) +
		EMOJI_TABLE.charAt(475) +
		EMOJI_TABLE.charAt(476) +
		EMOJI_TABLE.charAt(477) +
		EMOJI_TABLE.charAt(478) +
		EMOJI_TABLE.charAt(479) +
		EMOJI_TABLE.charAt(480) +
		EMOJI_TABLE.charAt(481) +
		EMOJI_TABLE.charAt(482) +
		EMOJI_TABLE.charAt(483) +
		EMOJI_TABLE.charAt(484) +
		EMOJI_TABLE.charAt(485) +
		EMOJI_TABLE.charAt(486) +
		EMOJI_TABLE.charAt(487) +
		EMOJI_TABLE.charAt(488) +
		EMOJI_TABLE.charAt(489) +
		EMOJI_TABLE.charAt(490) +
		EMOJI_TABLE.charAt(491) +
		EMOJI_TABLE.charAt(492) +
		EMOJI_TABLE.charAt(493) +

		EMOJI_TABLE.charAt(495) +
		EMOJI_TABLE.charAt(496) +
		EMOJI_TABLE.charAt(497) +

		EMOJI_TABLE.charAt(499) +

		EMOJI_TABLE.charAt(513) +

		EMOJI_TABLE.charAt(700) +
		EMOJI_TABLE.charAt(701) +
		EMOJI_TABLE.charAt(702) +
		EMOJI_TABLE.charAt(703) +
		EMOJI_TABLE.charAt(704) +

		EMOJI_TABLE.charAt(708) +
		EMOJI_TABLE.charAt(709) +
		EMOJI_TABLE.charAt(710) +
		EMOJI_TABLE.charAt(711) +
		EMOJI_TABLE.charAt(712) +
		EMOJI_TABLE.charAt(713) +
		EMOJI_TABLE.charAt(714) +
		EMOJI_TABLE.charAt(715) +
		EMOJI_TABLE.charAt(716) +
		EMOJI_TABLE.charAt(717) +
		EMOJI_TABLE.charAt(718) +
		EMOJI_TABLE.charAt(719) +
		EMOJI_TABLE.charAt(720) +
		EMOJI_TABLE.charAt(721) +
		EMOJI_TABLE.charAt(722) +
		EMOJI_TABLE.charAt(723) +

		EMOJI_TABLE.charAt(728) +
		EMOJI_TABLE.charAt(729) +

		EMOJI_TABLE.charAt(731) +
		EMOJI_TABLE.charAt(732) +
		EMOJI_TABLE.charAt(733) +
		EMOJI_TABLE.charAt(734) +
		EMOJI_TABLE.charAt(735) +
		EMOJI_TABLE.charAt(736) +
		EMOJI_TABLE.charAt(737) +
		EMOJI_TABLE.charAt(738) +
		EMOJI_TABLE.charAt(739) +
		EMOJI_TABLE.charAt(740) +
		EMOJI_TABLE.charAt(741) +
		EMOJI_TABLE.charAt(742) +
		EMOJI_TABLE.charAt(743) +
		EMOJI_TABLE.charAt(744) +
		EMOJI_TABLE.charAt(745) +
		EMOJI_TABLE.charAt(746) +
		EMOJI_TABLE.charAt(747) +
		EMOJI_TABLE.charAt(748) +
		EMOJI_TABLE.charAt(749) +
		EMOJI_TABLE.charAt(750) +
		EMOJI_TABLE.charAt(751) +
		EMOJI_TABLE.charAt(752) +
		EMOJI_TABLE.charAt(753) +
		EMOJI_TABLE.charAt(754) +
		EMOJI_TABLE.charAt(755) +
		EMOJI_TABLE.charAt(756) +
		EMOJI_TABLE.charAt(757) +
		EMOJI_TABLE.charAt(758) +
		EMOJI_TABLE.charAt(759) +
		EMOJI_TABLE.charAt(760) +
		EMOJI_TABLE.charAt(761) +
		EMOJI_TABLE.charAt(762) +
		EMOJI_TABLE.charAt(763) +
		EMOJI_TABLE.charAt(764) +
		EMOJI_TABLE.charAt(765) +
		EMOJI_TABLE.charAt(766) +
		EMOJI_TABLE.charAt(767) +
		EMOJI_TABLE.charAt(768) +
		EMOJI_TABLE.charAt(769) +
		EMOJI_TABLE.charAt(770) +
		EMOJI_TABLE.charAt(771) +
		EMOJI_TABLE.charAt(772) +
		EMOJI_TABLE.charAt(773) +
		EMOJI_TABLE.charAt(774) +
		EMOJI_TABLE.charAt(775) +
		EMOJI_TABLE.charAt(776) +
		EMOJI_TABLE.charAt(777) +
		EMOJI_TABLE.charAt(778) +
		EMOJI_TABLE.charAt(779) +
		EMOJI_TABLE.charAt(780) +
		EMOJI_TABLE.charAt(781) +
		EMOJI_TABLE.charAt(782) +
		EMOJI_TABLE.charAt(783) +
		EMOJI_TABLE.charAt(784) +
		EMOJI_TABLE.charAt(785) +
		EMOJI_TABLE.charAt(786) +
		EMOJI_TABLE.charAt(787) +
		EMOJI_TABLE.charAt(788) +
		EMOJI_TABLE.charAt(789) +
		EMOJI_TABLE.charAt(790) +
		EMOJI_TABLE.charAt(791) +
		EMOJI_TABLE.charAt(792) +
		EMOJI_TABLE.charAt(793) +
		EMOJI_TABLE.charAt(794) +
		EMOJI_TABLE.charAt(795) +
		EMOJI_TABLE.charAt(796) +
		EMOJI_TABLE.charAt(797) +
		EMOJI_TABLE.charAt(798) +
		EMOJI_TABLE.charAt(799) +
		EMOJI_TABLE.charAt(800) +
		EMOJI_TABLE.charAt(801) +
		EMOJI_TABLE.charAt(802) +
		EMOJI_TABLE.charAt(803) +
		EMOJI_TABLE.charAt(804) +
		EMOJI_TABLE.charAt(805) +
		EMOJI_TABLE.charAt(806) +
		EMOJI_TABLE.charAt(807) +
		EMOJI_TABLE.charAt(808) +
		EMOJI_TABLE.charAt(809) +
		EMOJI_TABLE.charAt(810) +
		EMOJI_TABLE.charAt(811) +
		EMOJI_TABLE.charAt(812) +
		EMOJI_TABLE.charAt(813) +
		EMOJI_TABLE.charAt(814) +
		EMOJI_TABLE.charAt(815) +
		EMOJI_TABLE.charAt(816) +
		EMOJI_TABLE.charAt(817) +

		EMOJI_TABLE.charAt(819) +
		EMOJI_TABLE.charAt(820) +
		EMOJI_TABLE.charAt(821) +
		EMOJI_TABLE.charAt(822);

	/**
	 * 指定された絵文字がユーザが入力可能な絵文字かどうかを返します。<p>
	 * 
	 * @param c 絵文字
	 * @return 入力可能な場合は true それ以外の場合は false
	 */
	public static boolean isAllowInput(final char c) {
		return ALLOW_INPUT.indexOf(c) > -1;
	}

	/**
	 * 指定された絵文字がユーザが入力可能な絵文字かどうかを返します。<p>
	 * 
	 * @param n 絵文字番号
	 * @return 入力可能な場合は true それ以外の場合は false
	 * @throws IllegalArgumentException 絵文字番号の値が不正な場合
	 */
	public static boolean isAllowInput(final int n) throws IllegalArgumentException {
		return isAllowInput(toChar(n));
	}

	/**
	 * 指定された絵文字がユーザが入力不可能な絵文字かどうかを返します。<p>
	 * 
	 * @param c 絵文字
	 * @return 入力不可能な場合は true それ以外の場合は false
	 */
	public static boolean isDenyInput(final char c) {
		return isEmoji(c) && !isAllowInput(c);
	}

	/**
	 * 指定された絵文字がユーザが入力不可能な絵文字かどうかを返します。<p>
	 * 
	 * @param n 絵文字番号
	 * @return 入力不可能な場合は true それ以外の場合は false
	 * @throws IllegalArgumentException 絵文字番号の値が不正な場合
	 */
	public static boolean isDenyInput(final int n) throws IllegalArgumentException {
		return isDenyInput(toChar(n));
	}

	/**
	 * 指定された絵文字番号から HDML の絵文字用タグを作成して返します。<p>
	 * 
	 * @param n 絵文字番号
	 * @return HDML の絵文字用タグ
	 */
	public static String renderHdmlTag(final int n) {
		StringBuilder results = new StringBuilder(16);
		results.append("<img icon=\"");
		results.append(n);
		results.append("\">");
		return results.toString();
	}

	/**
	 * 指定された絵文字から HDML の絵文字用タグを作成して返します。<p>
	 * 
	 * @param c 絵文字
	 * @return HDML の絵文字用タグ
	 */
	public static String renderHdmlTag(final char c) {
		return renderHdmlTag(toEmojiNumber(c));
	}

	/**
	 * 指定された絵文字番号から XHTML Basic の絵文字用タグを作成して返します。<p>
	 * 
	 * @param n 絵文字番号
	 * @return XHTML Basic の絵文字用タグ
	 */
	public static String renderXhtmlTag(final int n) {
		StringBuilder results = new StringBuilder(20);
		results.append("<img localsrc=\"");
		results.append(n);
		results.append("\" />");
		return results.toString();
	}

	/**
	 * 指定された絵文字から XHTML Basic の絵文字用タグを作成して返します。<p>
	 * 
	 * @param c 絵文字
	 * @return XHTML Basic の絵文字用タグ
	 */
	public static String renderXhtmlTag(final char c) {
		return renderXhtmlTag(toEmojiNumber(c));
	}

}
