package org.maachang.rimdb.index.string ;

import java.lang.reflect.Array;
import java.util.List;

import org.maachang.rimdb.index.InPointer;
import org.maachang.rimdb.util.ConvertUtil;
import org.maachang.rimdb.util.OList;

/**
 * String(IString)複数一致ポインタ.
 * 
 * @version 2014/06/29
 * @author  masahito suzuki
 * @since   rimdb-1.00
 */
@SuppressWarnings("unchecked")
public final class StringIn extends InPointer<IString> {
    protected StringIn(){}
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     */
    public StringIn( StringIndex index ) {
        this.type = TYPE_IN ;
        this.columnName = index.getColumnName() ;
    }
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public StringIn( StringIndex index,OList<IString> word ) {
        this( index ) ;
        set( word ) ;
    }
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public StringIn( StringIndex index,String... word ) {
        this( index ) ;
        set( word ) ;
    }
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public StringIn( StringIndex index,IString... word ) {
        this( index ) ;
        set( word ) ;
    }
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public StringIn( StringIndex index,Object word ) {
        this( index ) ;
        set( word ) ;
    }
    
    /**
     * 情報セット
     * @param word 対象の検索ワード群を設定します.
     */
    public final void set( final String... word ) {
        OList<IString> n = new OList<IString>() ;
        final int len = word.length ;
        for( int i = 0 ; i < len ; i ++ ) {
            n.add( new IString( word[ i ] ) ) ;
        }
        set( n ) ;
    }
    
    /**
     * 情報セット
     * @param word 対象の検索ワード群を設定します.
     */
    public final void set( final IString... word ) {
        OList<IString> n = new OList<IString>() ;
        final int len = word.length ;
        for( int i = 0 ; i < len ; i ++ ) {
            n.add( word[ i ] ) ;
        }
        set( n ) ;
    }
    
    /**
     * 情報セット
     * @param word 対象の検索ワード群を設定します.
     */
    public final void set( final Object word ) {
        set( getWord( word ) ) ;
    }
    
    /**
     * 情報セット
     * @param word 対象の検索ワード群を設定します.
     */
    public final void parameter( final Object word ) {
        set( getWord( word ) ) ;
    }
    
    /**
     * ワード変換.
     * @param word 対象のワードオブジェクトを設定します.
     * @return OList 変換されたワード内容が返却されます.
     */
    public static final OList<IString> getWord( Object word ) {
        if( word instanceof List ) {
            final List n = (List)word ;
            final int len = n.size() ;
            final OList<IString> ret = new OList<IString>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( n.get( i ) ) ) ;
            }
            return ret ;
        }
        else if( word instanceof String[] ) {
            final String[] n = (String[])word ;
            final int len = n.length ;
            final OList<IString> ret = new OList<IString>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( n[ i ] ) ) ;
            }
            return ret ;
        }
        else if( word instanceof Object[] ) {
            final Object[] n = (Object[])word ;
            final int len = n.length ;
            final OList<IString> ret = new OList<IString>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( n[ i ] ) ) ;
            }
            return ret ;
        }
        else if( word instanceof IString[] ) {
            final IString[] n = (IString[])word ;
            final int len = n.length ;
            final OList<IString> ret = new OList<IString>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( n[ i ] ) ;
            }
            return ret ;
        }
        else if( word instanceof OList ) {
            final OList n = (OList)word ;
            if( n.size() != 0 && n.get( 0 ) instanceof IString ) {
                return (OList)word ;
            }
            final int len = n.size() ;
            final OList<IString> ret = new OList<IString>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( n.get( i ) ) ) ;
            }
            return ret ;
        }
        else if( word.getClass().isArray() ) {
            final int len = Array.getLength( word ) ;
            final OList<IString> ret = new OList<IString>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( Array.get( word,i ) ) ) ;
            }
            return ret ;
        }
        final OList<IString> ret = new OList<IString>( 1 ) ;
        ret.add( convert( word ) ) ;
        return ret ;
    }
    
    /** IString変換. **/
    protected static final IString convert( final Object o ) {
        if( o instanceof IString ) {
            return (IString)o ;
        }
        return new IString( ConvertUtil.convertString( o ) ) ;
    }
    
    /**
     * オブジェクトコピー.
     * @param mode [true]を設定した場合、パラメータ情報はコピーされません.
     * @return SearchPointer コピーされたオブジェクトが返却されます.
     */
    public final StringIn copy( final boolean mode ) {
        StringIn ret = new StringIn() ;
        baseCopy( mode,ret ) ;
        return ret ;
    }
}
