package org.maachang.rimdb.index.string ;

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

/**
 * Like検索処理中の検索管理ポインタ.
 *
 * @version 2014/07/04
 * @author  masahito suzuki
 * @since   rimdb-1.00
 */
final class LikePositionList {
    private NList mem ;
    private int length ;
    LikePositionList() {}
    LikePositionList( int m ) {
        this( true,m ) ;
    }
    LikePositionList( boolean mode,int m ) {
        if( mode ) {
            NList mm = new NList( m << 1 ) ;
            for( int i = 0 ; i < m ; i ++ ) {
                mm.add( i ) ;
                mm.add( 0 ) ;
            }
            mem = mm ;
            length = m ;
        }
        else {
            mem = new NList( m >> 2 ) ;
            length = 0 ;
        }
    }
    public LikePositionList newList() {
        LikePositionList ret = new LikePositionList() ;
        if( length <= 0 ) {
            ret.mem = null ;
            ret.length = 0 ;
        }
        else {
            ret.mem = new NList( length >> 2 ) ;
            ret.length = 0 ;
        }
        return ret ;
    }
    public final void add( int p,int o ) {
        mem.add( p ) ;
        mem.add( o ) ;
        length ++ ;
    }
    public final int length() {
        return length ;
    }
    public int position( int no ) {
        return mem.get( no << 1 ) ;
    }
    public final int offset( int no ) {
        return mem.get( ( no << 1 ) + 1 ) ;
    }
    public final void offset( int no,int newOff ) {
        mem.set( ( no << 1 ) + 1,newOff ) ;
    }
    public final int[] list() {
        int[] ret = new int[ length ] ;
        int j = 0 ;
        for( int i = 0 ; i < length ; i ++ ) {
            ret[ i ] = mem.get( j ) ;
            j += 2 ;
        }
        return ret ;
    }
    public final void list( NAdd o ) {
        int j = 0 ;
        o.clear( length ) ;
        for( int i = 0 ; i < length ; i ++ ) {
            o.add( mem.get( j ) ) ;
            j += 2 ;
        }
    }
    public final void endOffset( int off,IString[] src,IString beforeIndexOf ) {
        int len = length ;
        int cnt = 0 ;
        NList tmp = new NList( len >> 2 ) ;
        if( beforeIndexOf == null ) {
            for( int i = 0,j = 0 ; i < len ; i ++,j += 2 ) {
                if( src[ mem.get( j ) ].length == mem.get( j+1 ) + off ) {
                    tmp.add( mem.get( j ) ) ;
                    tmp.add( mem.get( j+1 ) + off ) ;
                    cnt ++ ;
                }
            }
        }
        else {
            int p,cLen ;
            IString s ;
            int bLen = beforeIndexOf.length ;
            for( int i = 0,j = 0 ; i < len ; i ++,j += 2 ) {
                if( ( s = src[ mem.get( j ) ] ).length == mem.get( j+1 ) + off ) {
                    tmp.add( mem.get( j ) ) ;
                    tmp.add( mem.get( j+1 ) + off ) ;
                    cnt ++ ;
                }
                else {
                    cLen = s.length ;
                    p = mem.get( j+1 ) - ( bLen - 1 ) ;
                    while( ( p = s.indexOf( beforeIndexOf,p ) ) != -1 ) {
                        if( cLen == p + bLen + off ) {
                            tmp.add( mem.get( j ) ) ;
                            tmp.add( p + bLen + off ) ;
                            cnt ++ ;
                            break ;
                        }
                        p ++ ;
                    }
                }
            }
        }
        mem = tmp ;
        length = cnt ;
    }
}
