/**
 * LOGICAL-PARADOX.ORG variable record manager library
 * Copyright (C)2004 satoshi akabane(akabane@logical-paradox.org)
 *
 * Release 1.0
 * ・初期パージョン
 */
package org.logical_paradox.common.vrm;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.logical_paradox.common.io.ByteStream;

/**
 * 利用可能リストで使用するレコード
 * 
 * @author satoshi akabane@logical-paradox.org
 * @version 1.0
 */
public class AvailableRecord extends Record implements Comparable {
	/**
	 * コンストラクタ
	 * @param size データレコードのサイズ
	 * @param nextptr 次の利用可能レコードのバイト変位
	 */
	public AvailableRecord(int size, long nextptr) {
		o = new AvailableRecordByteStream(size, nextptr);
	}
	/**
	 * オブジェクト同士の大小比較
	 * @param 比較対象オブジェクト
	 * @return 1:this > arg0 0:this == arg0 -1:this < arg0
	 */
	public int compareTo(Object arg0) {
		AvailableRecord r = (AvailableRecord)arg0;

		if(getRecordSize() > r.getRecordSize()) {
			return 1;
		} else if(getRecordSize() < r.getRecordSize()) {
			return -1;
		} else {
			return 0;
		}
	}
	/**
	 * このレコードが指し示す，利用可能なレコードサイズを返す
	 * @return レコードサイズ
	 */
	public int getRecordSize() {
		return ((AvailableRecordByteStream)o).size;
	}
	/**
	 * 次の利用可能レコードのバイト変位を返す
	 * @return バイト変位
	 */
	public long getNextPtr() {
		return ((AvailableRecordByteStream)o).nextptr;
	}


	/**
	 * このレコードのバイト列表現を返す
	 * @return バイト列
	 */
	public byte[] byteStream() {
		byte[] bstream = o.byteStream();
		ByteBuffer buffer = ByteBuffer.allocate(bstream.length).order(ByteOrder.BIG_ENDIAN);
		buffer.put(bstream);						// 格納するデータのバイト列(固定長)
		
		return buffer.array();
	}
	/**
	 * バイト列からレコードを復元する
	 * @param bstream バイト列
	 * @throws IllegalArgumentException バイト列からの復元に失敗した
	 */
	protected void createObjectFromByteStream(byte[] bstream) throws IllegalArgumentException {
		o = new AvailableRecordByteStream(bstream);
	}
	/**
	 * レコード値の比較
	 * @param o 比較対象
	 * @return true:同じ / false:違う
	 */
	public boolean equals(Object o) {
		AvailableRecord r = (AvailableRecord)o;
		if(r == null) {
			// nullの場合は自動的に違うと判断する
			return false;
		}
		return getRecordSize() == r.getRecordSize() && getNextPtr() == r.getNextPtr();
	}

	class AvailableRecordByteStream implements ByteStream {
		private int size;
		private long nextptr;

		/**
		 * コンストラクタ
		 * @param s サイズ
		 * @param n 次のレコードのバイト変位
		 */
		public AvailableRecordByteStream(int s, long n) {
			size = s;
			nextptr = n;
		}
		/**
		 * コンストラクタ
		 * @param bstream バイト列
		 */
		public AvailableRecordByteStream(byte[] bstream) {
			createObjectFromByteStream(bstream);
		}
		/**
		 * バイト列からレコードを復元する
		 * @param bstream バイト列
		 * @throws IllegalArgumentException バイト列からの復元に失敗した
		 */
		protected void createObjectFromByteStream(byte[] bstream) throws IllegalArgumentException {
			ByteBuffer buffer = ByteBuffer.allocate(bstream.length).order(ByteOrder.BIG_ENDIAN);
			buffer.put(bstream);
			buffer.rewind();
	
			size = buffer.getInt();
			// 次のレコードのバイト変位を読み取る
			nextptr = buffer.getLong();
		}
		/**
		 * バイト列に変換して返す
		 * @return バイト列
		 */
		public byte[] byteStream() {
			ByteBuffer buffer = ByteBuffer.allocate(4+8).order(ByteOrder.BIG_ENDIAN);
			buffer.rewind();
			buffer.putInt(size);
			buffer.putLong(nextptr);
			return buffer.array();
		}
	}
}
