package org.maachang.comet.httpd.engine.script.js;

import java.text.SimpleDateFormat;
import java.util.Locale;

import org.apache.oro.text.perl.Perl5Util;

/**
 * 基本Validate.
 * 
 * @version 2007/08/24
 * @author masahito suzuki
 * @since MaachangComet 1.00
 */
public class BaseValidate {
    
    /**
     * 文字列チェック.
     * <BR><BR>
     * 文字列チェックを行います.
     * <BR>
     * @param int 対象タイプを設定します.
     * @param min 最小文字数を設定します.<BR>
     *            [null]の場合、指定なしです.
     * @param max 最大文字数を設定します.<BR>
     *            [null]の場合、指定なしです.
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateにマッチした条件が存在します.
     */
    public static final boolean isString( int type,Integer min,Integer max,String src ) {
        if( src == null || ( src = src.trim() ).length() <= 0 ) {
            src = "" ;
        }
        // 文字タイプチェック.
        if( checkType( src,type ) == false ) {
            return true ;
        }
        
        // 最小の長さチェック.
        if( minLength( src,min ) == false ) {
            return true ;
        }
        
        // 最大の長さチェック.
        if( maxLength( src,max ) == false ) {
            return true ;
        }
        return false ;
    }
    
    /**
     * 日付チェック.
     * <BR><BR>
     * 日付チェックを実行します.
     * <BR>
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateエラーです.
     * @exception Exception 例外.
     */
    public static final boolean isDate( String format,String src ) {
        if( src == null || ( src = src.trim() ).length() <= 0 ||
            format == null || ( format = format.trim() ).length() <= 0 ) {
            return true ;
        }
        boolean ret = false ;
        try {
            new SimpleDateFormat( format,Locale.JAPAN ).parse( src ) ;
        } catch( Exception e ) {
            ret = true ;
        }
        return ret ;
    }
    
    /**
     * 正規表現でチェック.
     * <BR><BR>
     * 正規表現でチェック処理を実行します.
     * <BR>
     * @param match 正規表現を設定します.
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateエラーです.
     */
    public static final boolean isMatch( String match,String src ) {
        return isPerl5Util_Match( match,src ) ;
    }
    
    /**
     * 郵便番号でチェック.
     * <BR><BR>
     * 郵便番号でチェック処理を実行します.
     * <BR>
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateエラーです.
     */
    public static final boolean isZip( String src ) {
        return isPerl5Util_Match( "/^\\d{3}\\-\\d{4}$/",src ) ;
    }
    
    /**
     * ISBN番号でチェック.
     * <BR><BR>
     * ISBN番号でチェック処理を実行します.
     * <BR>
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateエラーです.
     */
    public static final boolean isIsbn( String src ) {
        return isPerl5Util_Match( "/ISBN\\x20(?=.{13}$)\\d{1,5}([- ])\\d{1,7}\\1\\d{1,6}\\1(\\d|X)$/",src ) ;
    }
    
    /**
     * IPアドレスでチェック.
     * <BR><BR>
     * IPアドレスでチェック処理を実行します.
     * <BR>
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateエラーです.
     */
    public static final boolean isIpAddress( String src ) {
        return isPerl5Util_Match( "/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/",src ) ;
    }
    
    /**
     * URLでチェック.
     * <BR><BR>
     * URLでチェック処理を実行します.
     * <BR>
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateエラーです.
     */
    public static final boolean isUrl( String src ) {
        return isPerl5Util_Match( "/^(((ht|f)tp(s?))\\:\\/\\/)([0-9a-zA-Z\\-]+\\.)+[a-zA-Z]{2,6}(\\:[0-9]+)?(\\/\\S*)?$/",src ) ;
    }
    
    /**
     * Emailでチェック.
     * <BR><BR>
     * Emailでチェック処理を実行します.
     * <BR>
     * @param src チェック対象の条件を設定します.
     * @return boolean [true]の場合、Validateエラーです.
     */
    public static final boolean isEmail( String src ) {
        return isPerl5Util_Match( "/^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.([a-z]){2,4})$/",src ) ;
    }
    
    
    /**
     * カタカナ一覧.
     */
    private static final String KANA = "アィイウウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトド"+
        "ナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヲンー" ;
    
    /**
     * ひらがな一覧.
     */
    private static final String HIRA = "あぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとど"+
        "なにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんー" ;
    
    /**
     * チェックタイプ : 数字のみ.
     */
    private static final int ONLY_NUMBER = 0x00000001 ;
    
    /**
     * チェックタイプ : 英字のみ.
     */
    private static final int ONLY_ALPHABET = 0x00000002 ;
    
    /**
     * チェックタイプ : Asciiのみ.
     */
    private static final int ONLY_ASCII = 0x00000004 ;
    
    /**
     * チェックタイプ : カナのみ.
     */
    private static final int ONLY_KANA = 0x00000008 ;
    
    /**
     * チェックタイプ : ひらがなのみ.
     */
    private static final int ONLY_HIRA = 0x00000010 ;
    
    /**
     * タイプ判別.
     */
    private static boolean checkType( String chkString,int type ) {
        boolean chk = false ;
        if( ( type & ONLY_NUMBER ) != 0 ) {
            int len = chkString.length() ;
            int cnt = 0 ;
            StringBuilder buf = new StringBuilder() ;
            for( int i = 0 ; i < len ; i ++ ) {
                char c = chkString.charAt( i ) ;
                if( ( c >= '0' && c <= '9' ) == false ) {
                    if( cnt == 0 ) {
                        if( i == 0 && c == '-' ) {
                            cnt = -1 ;
                        }
                        else {
                            buf.append( chkString.charAt( i ) ) ;
                        }
                    }
                    else if( cnt != 0 && c != '.' ) {
                        buf.append( chkString.charAt( i ) ) ;
                    }
                }
                cnt ++ ;
            }
            chk = true ;
            chkString = buf.toString() ;
        }
        if( ( type & ONLY_ALPHABET ) != 0 ) {
            int len = chkString.length() ;
            StringBuilder buf = new StringBuilder() ;
            for( int i = 0 ; i < len ; i ++ ) {
                char c = chkString.charAt( i ) ;
                if( ( ( c >= 'a' && c <= 'z' ) ||
                    ( c >= 'A' && c <= 'Z' ) ) == false ) {
                    buf.append( chkString.charAt( i ) ) ;
                }
            }
            chk = true ;
            chkString = buf.toString() ;
        }
        if( ( type & ONLY_ASCII ) != 0 ) {
            int len = chkString.length() ;
            StringBuilder buf = new StringBuilder() ;
            for( int i = 0 ; i < len ; i ++ ) {
                char c = chkString.charAt( i ) ;
                if( c > ( char )0x00ff ) {
                    buf.append( chkString.charAt( i ) ) ;
                }
            }
            chk = true ;
            chkString = buf.toString() ;
        }
        if( ( type & ONLY_KANA ) != 0 ) {
            int len = chkString.length() ;
            StringBuilder buf = new StringBuilder() ;
            for( int i = 0 ; i < len ; i ++ ) {
                String c = chkString.substring( i,i+1 ) ;
                if( KANA.indexOf( c ) == -1 ) {
                    buf.append( chkString.charAt( i ) ) ;
                }
            }
            chk = true ;
            chkString = buf.toString() ;
        }
        if( ( type & ONLY_HIRA ) != 0 ) {
            int len = chkString.length() ;
            StringBuilder buf = new StringBuilder() ;
            for( int i = 0 ; i < len ; i ++ ) {
                String c = chkString.substring( i,i+1 ) ;
                if( HIRA.indexOf( c ) == -1 ) {
                    buf.append( chkString.charAt( i ) ) ;
                }
            }
            chk = true ;
            chkString = buf.toString() ;
        }
        if( chk == true && chkString.length() > 0 ) {
            return false ;
        }
        return true ;
    }
    
    /**
     * 長さ最小値チェック.
     */
    private static boolean minLength( String chkString,Integer min ) {
        if( min == null ) {
            return true ;
        }
        int len = -1 ;
        try {
            len = min.intValue() ;
        } catch( Exception e ) {
            len = -1 ;
        }
        if( len == -1 ) {
            return true ;
        }
        if( chkString.length() > len ) {
            return true ;
        }
        return false ;
    }
    
    /**
     * 長さ最大値チェック.
     */
    private static boolean maxLength( String chkString,Integer max ) {
        if( max == null ) {
            return true ;
        }
        int len = -1 ;
        try {
            len = max.intValue() ;
        } catch( Exception e ) {
            len = -1 ;
        }
        if( len == -1 ) {
            return true ;
        }
        if( chkString.length() < len ) {
            return true ;
        }
        return false ;
    }
    
    /**
     * 正規表現チェック.
     */
    private static boolean isPerl5Util_Match( String match,String src ) {
        try {
            if( match == null || match.length() <= 0 ) {
                return true ;
            }
            if( src == null || ( src = src.trim() ).length() <= 0 ) {
                return true ;
            }
            boolean ret = ( new Perl5Util().match( match,src ) ) ;
            if( ret == true ) {
                return false ;
            }
            return true ;
        } catch( Exception e ) {
            return true ;
        }
    }
}

