package org.maachang.rawio.mapping ;

import java.util.HashSet;
import java.util.Iterator;

/**
 * 1つのMapping要素.
 *  
 * @version 2008/06/15
 * @author  masahito suzuki
 * @since   Rawio 1.00
 */
class MappingChild {
    
    /**
     * セクタサイズ.
     */
    private int sector = -1 ;
    
    /**
     * Maaping開始位置.
     */
    private int startPos = -1 ;
    
    /**
     * Mapping終了位置.
     */
    private int endPos = -1 ;
    
    /**
     * Mapping長.
     */
    private int length = -1 ;
    
    /**
     * Mappingバイナリ.
     */
    private Object[] mapping = null ;
    
    /**
     * 更新位置.
     */
    private HashSet<Integer> updatePos = null ;
    
    /**
     * コンストラクタ.
     */
    private MappingChild() {
        
    }
    
    /**
     * コンストラクタ.
     * @param sector セクタ長を設定します.
     * @param startPos 開始位置を設定します.
     * @param length 長さを設定します.
     */
    public MappingChild( int sector,int startPos,int length ) {
        this.sector = sector ;
        this.startPos = startPos ;
        this.endPos = startPos + length ;
        this.length = length ;
        this.updatePos = new HashSet<Integer>() ;
        Object[] o = new Object[ length ] ;
        for( int i = 0 ; i < length ; i ++ ) {
            o[ i ] = new byte[ sector ] ;
        }
        this.mapping = o ;
    }
    
    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        destroy() ;
    }
    
    /**
     * オブジェクト破棄.
     */
    protected void destroy() {
        mapping = null ;
        updatePos = null ;
    }
    
    /**
     * 指定位置のポジションが範囲内かチェック.
     * @param no チェック対象の位置を設定します.
     * @return boolean [true]の場合、範囲内です.
     */
    public boolean isPosition( int no ) {
        return ( startPos <= no && endPos > no ) ;
    }
    
    /**
     * 開始位置を取得.
     * @return int 開始位置が返されます.
     */
    public int getStartPos() {
        return startPos ;
    }
    
    /**
     * 更新ポジションを追加.
     * @param no 更新ポジションを設定します.
     */
    public void updatePos( int no ) {
        if( no <= -1 || no >= length ) {
            return ;
        }
        updatePos.add( new Integer( no ) ) ;
    }
    
    /**
     * 更新一覧を取得.
     */
    public Iterator<Integer> iterator() {
        return updatePos.iterator() ;
    }
    
    /**
     * 指定ポジションのMappingバイナリを取得.
     * @param no 対象の項番を設定します.
     * @return byte[] 対象のバイナリが返されます.
     */
    public byte[] get( int no ) {
        if( no <= -1 || no >= length ) {
            return null ;
        }
        return ( byte[] )mapping[ no ] ;
    }
    
    /**
     * Mapping長を取得.
     * @return int Mapping長が返されます.
     */
    public int length() {
        return length ;
    }
    
    /**
     * 更新ポジション長を取得.
     * @return int 更新ポジション長が返されます.
     */
    public int updateLength() {
        return updatePos.size() ;
    }
    
    /**
     * セクタサイズを取得.
     * @return int セクタサイズが返されます.
     */
    public int getSector() {
        return sector ;
    }
}

