package org.maachang.rimdb.index ;

import org.maachang.rimdb.RimDbException;
import org.maachang.rimdb.util.NAdd;
import org.maachang.rimdb.util.NList;


/**
 * Like検索ポインター.
 * 
 * @version 2014/06/29
 * @author  masahito suzuki
 * @since   rimdb-1.00
 */
@SuppressWarnings("unchecked")
public abstract class LikePointer<W> extends SearchPointer<Index<W>> {
    
    /** 一致行. **/
    protected NList position ;
    
    /** 検索ワード. **/
    protected String word ;
    
    /**
     * 情報リセット.
     * @param mode [true]を設定した場合、設定ワード条件も削除します.
     */
    public void reset( boolean mode ) {
        super.reset( mode ) ;
        if( mode ) {
            word = null ;
        }
        position = null ;
    }
    
    /**
     * 情報セット.
     * @param word 対象の情報を設定します.
     */
    public void set( String word ) {
        if( word == null ) {
            throw new RimDbException( "[" + this.getClass().getName() + "]検索条件にnullは設定できません" ) ;
        }
        this.word = word ;
        this.resetFlag = false ;
    }
    
    /**
     * インデックス位置を取得.
     * @return int インデックス位置が返却されます.
     */
    public final NList position() {
        return position ;
    }
    
    /**
     * 検索処理.
     * @param index 対象のインデックスを設定します.
     */
    public final void search( final Index<W> index ) {
        
        if( resetFlag ) {
            throw new RimDbException( "[" + this.getClass().getName() + "]条件が設定されていません" ) ;
        }
        
        if( position == null ) {
            position = new NList() ;
        }
        else {
            position.clear() ;
        }
        index.like( position,word ) ;
        
        final int len = position.size() ;
        final MaskLine[] lm = index.getMaskLine() ;
        int cnt = 0 ;
        for( int i = 0 ; i < len ; i ++ ) {
            cnt += lm[ position.get( i ) ].length ;
        }
        count = cnt ;
        length = len ;
    }
    
    /**
     * 検索結果情報をNAdd情報に格納.
     * ※この処理は、検索条件が１件の場合に利用します.
     * @param out 検索結果の行情報をNAdd情報にセットします.
     * @param index 対象のインデックスを設定します.
     */
    public final void get( final NAdd out,final Index<W> index ) {
        
        final NList pos = position ;
        if( pos.size() == 0 ) {
            return ;
        }
        
        int j,lenJ ;
        int[] n ;
        final int[][] indexToLine = ((Index)index).getIndexToLine() ;
        final int len = pos.size() ;
        
        for( int i = 0 ; i < len ; i ++ ) {
            n = indexToLine[ pos.get( i ) ] ;
            lenJ = n.length ;
            for( j = 0 ; j < lenJ ; j ++ ) {
                out.add( n[ j ] ) ;
            }
        }
    }
    
    /** ベースコピー. **/
    protected void baseCopy( final boolean mode,final LikePointer o ) {
        super.baseCopy( mode,o ) ;
        if( !mode ) {
            o.word = word ;
            o.resetFlag = false ;
        }
        o.position = null ;
    }
}
