package org.maachang.util;

/**
 * URLEncode.
 * 
 * @version 2007/10/18
 * @author masahito suzuki
 * @since MaachangProxy 1.00
 */
public class URLEncode {

    /**
     * デフォルトキャラクタセット.
     */
    private static final String DEFAULT_CHARSET = "UTF8";

    /**
     * URLエンコード. <BR>
     * <BR>
     * URLをエンコードします.<BR>
     * この処理はマルチバイト系の文字情報をエンコードします. <BR>
     * 
     * @param url
     *            対象のURLを設定します.
     * @return String
     *            エンコードされた文字列が返されます.
     */
    public static final String convert(String url) {
        return convert(url, null);
    }

    /**
     * URLエンコード. <BR>
     * <BR>
     * URLをエンコードします.<BR>
     * この処理はマルチバイト系の文字情報をエンコードします. <BR>
     * 
     * @param url
     *            対象のURLを設定します.
     * @param charset
     *            対象のキャラクタセットを設定します.
     * @return String
     *            エンコードされた文字列が返されます.
     */
    public static final String convert(String url, String charset) {

        if (url == null || (url = url.trim()).length() <= 0) {
            return null;
        }
        if (charset == null || (charset = charset.trim()).length() <= 0) {
            charset = DEFAULT_CHARSET;
        }

        String ret = url;

        try {

            boolean paramFlg = false;
            int len = url.length();
            StringBuffer buf = new StringBuffer(len);
            int offset = 0;

            if (url.startsWith("http") == true) {
                if ((offset = url.indexOf("://")) != -1) {
                    offset += 3;
                    buf.append(url.substring(0, offset));
                }
            }

            for (int i = offset; i < len; i++) {
                char c = url.charAt(i);

                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                        || (c >= '0' && c <= '9') || (c == '.') || (c == '-')
                        || (c == '*') || (c == '_') || (c == '&') || (c == '=')
                        || (c == ' ' && paramFlg == true)
                        || ((c == '/' || c == '?' || c == '~' ) && paramFlg == false)) {
                    if (c == '?') {
                        paramFlg = true;
                    }
                    if (c == ' ') {
                        buf.append("+");
                    } else {
                        buf.append(c);
                    }
                } else {
                    byte[] b = new String(new char[] { c }).getBytes(charset);
                    int lenJ = b.length;
                    for (int j = 0; j < lenJ; j++) {
                        String hex = Integer.toHexString(
                                ((int) b[j]) & 0x000000ff).toUpperCase();
                        hex = "00".substring( hex.length() ) + hex ;
                        buf.append("%");
                        buf.append(hex);
                    }
                }
            }

            ret = buf.toString();
            buf = null;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return ret;

    }

}
