package org.maachang.rimdb.index.comparable ;

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

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

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