package org.maachang.rimdb.index.number64 ;

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;

/**
 * Number64(long)複数一致ポインタ.
 * 
 * @version 2014/06/29
 * @author  masahito suzuki
 * @since   rimdb-1.00
 */
@SuppressWarnings("unchecked")
public final class Number64In extends InPointer<Long> {
    protected Number64In(){}
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     */
    public Number64In( Number64Index index ) {
        this.type = TYPE_IN ;
        this.columnName = index.getColumnName() ;
    }
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public Number64In( Number64Index index,OList<Long> word ) {
        this( index ) ;
        set( word ) ;
    }
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public Number64In( Number64Index index,long... word ) {
        this( index ) ;
        set( word ) ;
    }
    
    /**
     * コンストラクタ.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public Number64In( Number64Index index,Object word ) {
        this( index ) ;
        set( word ) ;
    }
    
    /**
     * 情報セット.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public final void set( final long... word ) {
        OList<Long> n = new OList<Long>() ;
        final int len = word.length ;
        for( int i = 0 ; i < len ; i ++ ) {
            n.add( word[ i ] ) ;
        }
        set( n ) ;
    }
    
    /**
     * 情報セット.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public final void set( final Object word ) {
        set( getWord( word ) ) ;
    }
    
    /**
     * 情報セット.
     * @param index 対象のインデックスを設定します.
     * @param word 対象の検索ワード群を設定します.
     */
    public final void parameter( final Object word ) {
        set( getWord( word ) ) ;
    }
    
    /**
     * ワード変換.
     * @param word 対象のワードオブジェクトを設定します.
     * @return OList 変換されたワード内容が返却されます.
     */
    public static final OList<Long> getWord( Object word ) {
        if( word instanceof List ) {
            final List n = (List)word ;
            final int len = n.size() ;
            final OList<Long> ret = new OList<Long>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( n.get( i ) ) ) ;
            }
            return ret ;
        }
        else if( word instanceof long[] ) {
            final long[] n = (long[])word ;
            final int len = n.length ;
            final OList<Long> ret = new OList<Long>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( n[ i ] ) ;
            }
            return ret ;
        }
        else if( word instanceof Long[] ) {
            final Long[] n = (Long[])word ;
            final int len = n.length ;
            final OList<Long> ret = new OList<Long>( 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<Long> ret = new OList<Long>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( n[ i ] ) ) ;
            }
            return ret ;
        }
        else if( word instanceof OList ) {
            final OList n = (OList)word ;
            if( n.size() != 0 && n.get( 0 ) instanceof Long ) {
                return (OList)word ;
            }
            final int len = n.size() ;
            final OList<Long> ret = new OList<Long>( 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<Long> ret = new OList<Long>( len ) ;
            for( int i = 0 ; i < len ; i ++ ) {
                ret.add( convert( Array.get( word,i ) ) ) ;
            }
            return ret ;
        }
        final OList<Long> ret = new OList<Long>( 1 ) ;
        ret.add( convert( word ) ) ;
        return ret ;
    }
    
    /** long変換. **/
    protected static final long convert( final Object o ) {
        // 数値で無い場合は、日付orタイムスタンプ変換.
        if( !ConvertUtil.isNumeric( o ) ) {
            if( o instanceof java.sql.Date ) {
                return (ConvertUtil.convertSqlDate( o )).getTime() ;
            }
            else if( o instanceof java.util.Date ) {
                return ((java.util.Date)o).getTime() ;
            }
            else if( o instanceof String ) {
                return ConvertUtil.convertDate( o ).getTime() ;
            }
        }
        return ConvertUtil.convertInt( o ) ;
    }
    
    /**
     * オブジェクトコピー.
     * @param mode [true]を設定した場合、パラメータ情報はコピーされません.
     * @return SearchPointer コピーされたオブジェクトが返却されます.
     */
    public final Number64In copy( final boolean mode ) {
        Number64In ret = new Number64In() ;
        baseCopy( mode,ret ) ;
        return ret ;
    }
}
