package org.maachang.rimdb.index.position ;

import org.maachang.rimdb.RimDbException;
import org.maachang.rimdb.index.MaskFlags;
import org.maachang.rimdb.index.Pointer;
import org.maachang.rimdb.table.Indexs;

/**
 * 空間インデックスポインタ.
 * 
 * @version 2014/07/13
 * @author  masahito suzuki
 * @since   rimdb-1.00
 */
public final class PositionIndexPointer implements Pointer {
    
    protected boolean flag = false ;
    protected int x ;
    protected int y ;
    protected int half ;
    protected int no = -1 ;
    
    /**
     * コンストラクタ.
     */
    public PositionIndexPointer() {
    }
    
    /**
     * 情報リセット.
     * @param mode [true]を設定した場合、設定ワード条件も削除します.
     */
    public final void reset( final boolean mode ) {
        if( mode ) {
            flag = false ;
        }
    }
    
    /**
     * 番号設定.
     * @param no 対象の番号を設定します.
     */
    public final void setNo( final int no ) {
        this.no = no ;
    }
    
    /**
     * 番号取得.
     * @return int 番号が返却されます.
     */
    public final int getNo() {
        return no ;
    }
    
    /**
     * 情報コピー.
     * @param mode [true]を設定した場合、パラメータ情報はコピーされません.
     * @return PositionIndexPointer コピーされた情報が返却されます.
     */
    public final PositionIndexPointer copy( final boolean mode ) {
        PositionIndexPointer ret = new PositionIndexPointer() ;
        ret.no = no ;
        if( !mode ) {
            ret.x = x ;
            ret.y = y ;
            ret.half = half ;
        }
        return ret ;
    }
    
    /**
     * 情報セット.
     * @param x 対象のX軸を設定します.
     * @param y 対象のY軸を設定します.
     * @param half 対象の半径を設定します.
     */
    public final void set( final int x,final int y,final int half ) {
        this.x = x ;
        this.y = y ;
        this.half = half ;
        flag = true ;
    }
    
    /**
     * 情報セット.
     * @param word 検索内容を設定します.
     */
    public final void parameter( final Object word ) {
        int[] n = PositionIndex.convert( word ) ;
        set( n[0],n[1],n[2] ) ;
    }
    
    /**
     * 情報が有効かチェック.
     * @return boolean [true]の場合、有効です.
     */
    public final boolean isSet() {
        return flag ;
    }
    
    /**
     * 処理タイプを取得.
     * @return int 処理タイプが返却されます[TYPE_XXXX].
     */
    public final int getType() {
        return Pointer.TYPE_POSITION ;
    }
    
    /**
     * X軸を取得.
     * @return int X軸が返却されます.
     */
    public final int getX() {
        if( !flag ) {
            throw new RimDbException( "条件が設定されていません" ) ;
        }
        return x ;
    }
    
    /**
     * Y軸を取得.
     * @return int Y軸が返却されます.
     */
    public final int getY() {
        if( !flag ) {
            throw new RimDbException( "条件が設定されていません" ) ;
        }
        return y ;
    }
    
    /**
     * 半径を取得.
     * @return int 半径が返却されます.
     */
    public final int getHalf() {
        if( !flag ) {
            throw new RimDbException( "条件が設定されていません" ) ;
        }
        return half ;
    }
    
    /**
     * 検索処理.
     * @param out 検索結果を設定するオブジェクトを設定します.
     * @param index 対象のインデックスオブジェクトを設定します.
     */
    public final void search( final MaskFlags out,final PositionIndex index ) {
        search( out,null,index ) ;
    }
    
    /**
     * 検索処理.
     * @param out 検索結果を設定するオブジェクトを設定します.
     * @param indexTable 対象のインデックステーブルを設定します.
     */
    public final void search( final MaskFlags out,final Indexs indexTable ) {
        search( out,null,indexTable.getPositionIndex() ) ;
    }
    
    /**
     * 検索処理.
     * @param out 検索結果を設定するオブジェクトを設定します.
     * @param and And条件のオブジェクトを設定します.
     * @param index 対象のインデックスオブジェクトを設定します.
     */
    public final void search( final MaskFlags out,final MaskFlags and,final PositionIndex index ) {
        if( !flag ) {
            throw new RimDbException( "条件が設定されていません" ) ;
        }
        out.clear() ;
        index.search( out,and,x,y,half ) ;
    }
    
    /**
     * 検索処理.
     * @param out 検索結果を設定するオブジェクトを設定します.
     * @param and And条件のオブジェクトを設定します.
     * @param indexTable 対象のインデックステーブルを設定します.
     */
    public final void search( final MaskFlags out,final MaskFlags and,final Indexs indexTable ) {
        search( out,and,indexTable.getPositionIndex() ) ;
    }
    
    /**
     * 空間検索ソート要素を取得.
     * @param index 対象のインデックスオブジェクトを設定します.
     * @return RadiusSort ソート要素が返却されます.
     */
    public final RadiusSort getSort( final PositionIndex index ) {
        if( !flag ) {
            throw new RimDbException( "条件が設定されていません" ) ;
        }
        return index.getSort( x,y ) ;
    }
    
    /**
     * 空間検索ソート要素を取得.
     * @param indexTable 対象のインデックステーブルを設定します.
     * @return RadiusSort ソート要素が返却されます.
     */
    public final RadiusSort getSort( final Indexs indexTable ) {
        return getSort( indexTable.getPositionIndex() ) ;
    }
}
