package org.maachang.mimdb.core.util ;

import java.io.IOException;

/**
 * 文字変換系.
 * 
 * @version 2013/11/07
 * @author masahito suzuki
 * @since MasterInMemDB 1.00
 */
public final class StringUtils {
    private StringUtils() {}
    
    /**
     * 文字列から、Boolean型に変換.
     * @param s 対象の文字列を設定します.
     * @return boolean Boolean型が返されます.
     * @exception Exception 例外.
     */
    public static final boolean parseBoolean( String s ) throws Exception {
        if( s == null || s.length() <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        if( s.length() == 4 ) {
            if( "true" == s || "true".equals( s ) ) {
                return true ;
            }
        }
        else if( s.length() == 5 ) {
            if( "false" == s || "false".equals( s ) ) {
                return false ;
            }
        }
        throw new IOException( "Boolean変換に失敗しました:"+s ) ;
    }
    
    /**
     * 文字列から、int型数値に変換.
     * @param num 対象の文字列を設定します.
     * @return int int型で変換された数値が返されます.
     * @exception Exception 例外.
     */
    public static final int parseInt( String num ) throws Exception {
        int len ;
        if( num == null || ( len = num.length() ) <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        int ret = 0 ;
        int v = 1 ;
        int end = 0 ;
        char c ;
        int dot ;
        if( num.charAt( 0 ) == '-' ) {
            end = 1 ;
        }
        if( ( dot = num.indexOf( "." ) ) != -1 ) {
            len = dot ;
        }
        for( int i = len-1 ; i >= end ; i -- ) {
            c = num.charAt( i ) ;
            if( c >= '0' && c <= '9' ) {
                ret += ( v * (int)( c - '0' ) ) ;
                v *= 10 ;
            }
            else {
                throw new IOException( "数値変換に失敗しました:"+num ) ;
            }
        }
        if( end == 1 ) {
            return ret * -1 ;
        }
        return ret ;
    }
    
    /**
     * 文字列から、long型数値に変換.
     * @param num 対象の文字列を設定します.
     * @return long long型で変換された数値が返されます.
     * @exception Exception 例外.
     */
    public static final long parseLong( String num ) throws Exception {
        int len ;
        if( num == null || ( len = num.length() ) <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        long ret = 0L ;
        long v = 1L ;
        int end = 0 ;
        char c ;
        int dot ;
        if( num.charAt( 0 ) == '-' ) {
            end = 1 ;
        }
        if( ( dot = num.indexOf( "." ) ) != -1 ) {
            len = dot ;
        }
        for( int i = len-1 ; i >= end ; i -- ) {
            c = num.charAt( i ) ;
            if( c >= '0' && c <= '9' ) {
                ret += ( v * (long)( c - '0' ) ) ;
                v *= 10L ;
            }
            else {
                throw new IOException( "数値変換に失敗しました:"+num ) ;
            }
        }
        if( end == 1 ) {
            return ret * -1L ;
        }
        return ret ;
    }
    
    /**
     * 文字列から、double型数値に変換.
     * @param num 対象の文字列を設定します.
     * @return double double型で変換された数値が返されます.
     * @exception Exception 例外.
     */
    public static final double parseDouble( String num ) throws Exception {
        int len ;
        if( num == null || ( len = num.length() ) <= 0 ) {
            throw new IllegalArgumentException( "文字列は空です" ) ;
        }
        double ret = 0d ;
        double v = 1d ;
        int end = 0 ;
        char c ;
        int dot ;
        if( num.charAt( 0 ) == '-' ) {
            end = 1 ;
        }
        if( ( dot = num.indexOf( "." ) ) == -1 ) {
            for( int i = len-1 ; i >= end ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    ret += ( v * (double)( c - '0' ) ) ;
                    v *= 10d ;
                }
                else {
                    throw new IOException( "数値変換に失敗しました:"+num ) ;
                }
            }
            if( end == 1 ) {
                return ret * -1d ;
            }
            return ret ;
        }
        else {
            for( int i = dot-1 ; i >= end ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    ret += ( v * (double)( c - '0' ) ) ;
                    v *= 10d ;
                }
                else {
                    throw new IOException( "数値変換に失敗しました:"+num ) ;
                }
            }
            double dret = 0d ;
            v = 1d ;
            for( int i = len-1 ; i > dot ; i -- ) {
                c = num.charAt( i ) ;
                if( c >= '0' && c <= '9' ) {
                    dret += ( v * (double)( c - '0' ) ) ;
                    v *= 10d ;
                }
                else {
                    throw new IOException( "数値変換に失敗しました:"+num ) ;
                }
            }
            if( end == 1 ) {
                ret = ( ret + ( dret / v ) ) * -1d ;
            }
            else {
                ret += ( dret / v ) ;
            }
            return ret ;
        }
    }
    
    /**
     * 文字情報の置き換え.
     * @param src 置き換え元の文字列を設定します.
     * @param s 置き換え文字条件を設定します.
     * @param d 置き換え先の文字条件を設定します.
     * @return String 文字列が返却されます.
     */
    public static final String changeString( String src,String s,String d ) {
        int j,k ;
        int len = src.length() ;
        char t = s.charAt( 0 ) ;
        int lenS = s.length() ;
        StringBuilder buf = new StringBuilder( len ) ;
        for( int i = 0 ; i < len ; i ++ ) {
            if( src.charAt( i ) == t ) {
                j = i ; k = 0 ;
                while( ++ k < lenS && ++ j < len && src.charAt( j ) == s.charAt( k ) ) ;
                if( k >= lenS ) {
                    buf.append( d ) ;
                    i += (lenS-1) ;
                }
                else {
                    buf.append( t ) ;
                }
            }
            else {
                buf.append( src.charAt( i ) ) ;
            }
        }
        return buf.toString() ;
    }
}
