package jp.sf.amateras.functions;

import java.util.Arrays;
import java.util.Date;

import jp.sf.amateras.functions.utils.DateUtils;
import jp.sf.amateras.functions.utils.NumberUtil;
import jp.sf.amateras.functions.utils.StringUtils;

/**
 * JSPで利用可能な標準的なEL関数を提供します。
 *
 * @author Naoki Takezoe
 */
public class Functions {

	/**
	 * 指定した文字列に含まれるHTMLタグをエスケープします。
	 *
	 * @param input 変換対象のオブジェクト
	 * @return 変換後の文字列。引数<code>value</code>が<code>null</code>の場合は空文字列
	 * @see StringUtils#escapeHtml(String)
	 */
	public static String h(Object input){
        if (input == null) {
            return "";
        }
        String str = "";
        if (input.getClass().isArray()) {
            Class<?> clazz = input.getClass().getComponentType();
            if (clazz == String.class) {
                str = Arrays.toString((Object[]) input);
            } else if (clazz == boolean.class) {
                str = Arrays.toString((boolean[]) input);
            } else if (clazz == int.class) {
                str = Arrays.toString((int[]) input);
            } else if (clazz == long.class) {
                str = Arrays.toString((long[]) input);
            } else if (clazz == byte.class) {
                str = Arrays.toString((byte[]) input);
            } else if (clazz == short.class) {
                str = Arrays.toString((short[]) input);
            } else if (clazz == float.class) {
                str = Arrays.toString((float[]) input);
            } else if (clazz == double.class) {
                str = Arrays.toString((double[]) input);
            } else if (clazz == char.class) {
                str = Arrays.toString((char[]) input);
            } else {
                str = Arrays.toString((Object[]) input);
            }
        } else {
            str = input.toString();
        }
        return StringUtils.escapeHtml(str);
    }

	/**
	 * 指定した文字列をURLエンコードします。
	 *
	 * @param value 変換対象の文字列
	 * @return 変換後の文字列。引数<code>value</code>が<code>null</code>の場合は空文字列
	 * @see StringUtils#urlEncode(String)
	 */
	public static String u(String value){
		// TODO リクエストの文字コードから取得するべき？
		return StringUtils.urlEncode(value);
	}

	/**
	 * 指定した文字列の改行を&lt;br&gt;タグに変換します。
	 *
	 * @param value 変換対象の文字列
	 * @return 変換後の文字列。引数<code>value</code>が<code>null</code>の場合は空文字列
	 * @see StringUtils#convertLineSeparator(String)
	 */
	public static String br(String value){
		return StringUtils.convertLineSeparator(value);
	}

	/**
	 * 指定した文字列に含まれるタブや半角スペースを&amp;nbsp;に変換します。
	 * <p>
	 * 連続した半角スペースの最初の1つめは&amp;nbsp;に変換しません。
	 * また、タブ文字は半角スペース4つ分の空白に変換します。
	 *
	 * @param value 変換対象の文字列
	 * @return 変換後の文字列。引数<code>value</code>が<code>null</code>の場合は空文字列
	 * @see StringUtils#convertWhitespace(String)
	 */
	public static String nbsp(String value){
		return StringUtils.convertWhitespace(value);
	}

	/**
	 * 文字列を*（アスタリスク）に変換します。
	 *
	 * @param value 変換対象の文字列
	 * @return 変換後の文字列。引数<code>value</code>が<code>null</code>の場合は空文字列
	 * @see StringUtils#mask(String, char)
	 */
	public static String mask(String value){
		return StringUtils.mask(value, '*');
	}

	/**
	 * <code>java.util.Date</code>オブジェクトを日付形式にフォーマットします。
	 *
	 * @param date 変換対象の<code>java.util.Date</code>オブジェクト
	 * @return 日付形式にフォーマットされた文字列。引数<code>date</code>が<code>null</code>の場合は空文字列
	 * @see DateUtils#formatDate(Date)
	 */
	public static String date(Date date){
		return DateUtils.formatDate(date);
	}

	/**
	 * <code>java.util.Date</code>オブジェクトを日時形式にフォーマットします。
	 *
	 * @param date 変換対象の<code>java.util.Date</code>オブジェクト
	 * @return 日時形式にフォーマットされた文字列。引数<code>date</code>が<code>null</code>の場合は空文字列
	 * @see DateUtils#formatDatetime(Date)
	 */
	public static String datetime(Date date){
		return DateUtils.formatDatetime(date);
	}

	/**
	 * <code>java.util.Date</code>オブジェクトを時間形式にフォーマットします。
	 *
	 * @param date 変換対象の<code>java.util.Date</code>オブジェクト
	 * @return 時間形式にフォーマットされた文字列。引数<code>date</code>が<code>null</code>の場合は空文字列
	 * @see DateUtils#formatTime(Date)
	 */
	public static String time(Date date){
		return DateUtils.formatTime(date);
	}

	/**
	 * 数値を指定したパターンでフォーマットします。
	 *
	 * @param number フォーマット対象の数値
	 * @param pattern <code>java.text.DecimalFormat</code>で指定可能なパターン
	 * @return フォーマットされた文字列。引数<code>number</code>が<code>null</code>の場合は空文字列
	 * @see NumberUtil#formatNumber(Object, String)
	 */
	public static String number(Object number, String pattern){
		return NumberUtil.formatNumber(number, pattern);
	}

	/**
	 * 文字列の先頭から指定文字数までを切り出します。
	 *
	 * @param value 文字列
	 * @param length 切り出す文字数
	 * @return 切り出された文字列。引数<code>value</code>が<code>null</code>の場合は空文字列
	 * @see StringUtils#cut(String, int)
	 */
	public static String cut(String value, int length){
		return StringUtils.cut(value, length);
	}

	/**
	 * 文字列に含まれるURLをリンクに変換します。
	 *
	 * @param value 変換対象の文字列
	 * @return 変換後の文字列。引数<code>value</code>が<code>null</code>の場合は空文字列
	 * @see StringUtils#convertURL(String)
	 */
	public static String link(String value){
		return StringUtils.convertURL(value);
	}

}
