package org.phosphoresce.commons.csv;

import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

/**
 * CSVレコード郡を保持するリストクラス。<br>
 *
 * @author Kitagawa<br>
 *
 *<!--
 * 更新日		更新者			更新内容
 * 2007/02/16	Kitagawa		新規作成
 * 2008/11/25	Kitagawa		get、remove、listIterator、subListにおいて添え字がサイズを超える場合にリストサイズを自動拡張しないように修正
 * 2008/11/25	Kitagawa		toStringオーバーライド
 *-->
 */
public final class CSVRecordList implements Serializable {

	/** CSVレコードリスト */
	private List list = null;

	/**
	 * コンストラクタ<br>
	 */
	public CSVRecordList() {
		super();
		this.list = new LinkedList();
	}

	/**
	 * コンストラクタ<br>
	 * @param list 初期化時のCSVレコードリストオブジェクト
	 */
	public CSVRecordList(CSVRecordList list) {
		super();
		this.list = new LinkedList(list.list);
	}

	/**
	 * CSVレコードリストが空であるか判定します。<br>
	 * @return CSVレコードリストが空である場合trueを返却
	 */
	public boolean isEmpty() {
		return list.isEmpty();
	}

	/**
	 * 指定されたCSVレコードリストが保持されているか判定します。<br>
	 * @param record 判定対象CSVレコード
	 * @return リストにCSVレコードが保持されている場合はtrueを返却
	 */
	public boolean contains(CSVRecord record) {
		return this.list.contains(record);
	}

	/**
	 * 指定されたCSVレコードリスト内容が全て保持されているか判定します。<br>
	 * @param list 判定対象CSVレコードリスト
	 * @return 指定されたCSVレコードリスト内容が全て保持されている場合trueを返却
	 */
	public boolean containsAll(CSVRecordList list) {
		return this.list.containsAll(list.list);
	}

	/**
	 * CSVレコードリストイテレータを取得します。<br>
	 * @return CSVレコードリストイテレータ
	 */
	public Iterator iterator() {
		return list.iterator();
	}

	/**
	 * 保持しているCSVレコードを配列として取得します。<br>
	 * @return CSVレコード配列
	 */
	public CSVRecord[] toArray() {
		return (CSVRecord[]) list.toArray(new CSVRecord[list.size()]);
	}

	/**
	 * 指定されたCSVレコードリストを全て追加します。<br>
	 * @param list 追加対象CSVレコードリスト
	 * @return 追加処理の結果、リスト内容が変更された場合はtrueを返却
	 */
	public boolean addAll(CSVRecordList list) {
		return this.list.addAll(list.list);
	}

	/**
	 * 指定されたCSVレコードリストを指定位置に全て追加します。<br>
	 * @param index 追加位置インデックス
	 * @param list 追加対象CSVレコードリスト
	 * @return 処理の結果、リスト内容が変更された場合はtrueを返却
	 */
	public boolean addAll(int index, CSVRecordList list) {
		expand(index);
		return this.list.addAll(index, list.list);
	}

	/**
	 * 指定されたCSVレコードリストリストに格納されている要素のみを残してリストを編集します。<br>
	 * @param list 保持対象のCSVレコードリストを保持するリストオブジェクト
	 * @return 処理の結果、リスト内容が変更された場合はtrueを返却
	 */
	public boolean retainAll(CSVRecordList list) {
		return this.list.retainAll(list.list);
	}

	/**
	 * 保持しているCSVレコードを全て削除します。<br>
	 */
	public void clear() {
		this.list.clear();
	}

	/**
	 * 保持しているCSVレコード数を取得します。<br>
	 * @return 保持しているCSVレコード数
	 */
	public int size() {
		return list.size();
	}

	/**
	 * 指定されたサイズまでトークンリストサイズを拡張します。<br>
	 * @param size 拡張後のサイズ
	 */
	public void expand(int size) {
		int listSize = list.size();
		for (int i = 0; i <= size - listSize; i++) {
			list.add(new CSVRecord());
		}
	}

	/**
	 * 指定されたCSVレコードを追加します。<br>
	 * @param record CSVレコード
	 */
	public void add(CSVRecord record) {
		this.list.add(record);
	}

	/**
	 * 指定されたインデックス位置にCSVレコードを追加します。<br>
	 * @param index 追加位置インデックス
	 * @param record 追加対象CSVレコード
	 */
	public void add(int index, CSVRecord record) {
		expand(index);
		this.list.add(index, record);
	}

	/**
	 * 指定されたインデックスのCSVレコードを取得します。<br>
	 * @param index 取得対象インデックス
	 * @return CSVレコード
	 */
	public CSVRecord get(int index) {
		//expand(index + 1);
		if (index > list.size() - 1) {
			return null;
		}
		return (CSVRecord) list.get(index);
	}

	/**
	 * 指定されたインデックスに対してCSVレコードを設定します。<br>
	 * @param index インデックス
	 * @param record CSVレコード
	 * @return 設定処理前に保持されていたCSVレコード
	 */
	public CSVRecord set(int index, CSVRecord record) {
		expand(index + 1);
		return (CSVRecord) this.list.set(index, record);
	}

	/**
	 * 指定されたCSVレコードリストを削除します。<br>
	 * @param record 削除対象CSVレコード
	 * @return 指定されたCSVレコードが保持されている場合はtrueを返却
	 */
	public boolean remove(CSVRecord record) {
		return this.list.remove(record);
	}

	/**
	 * 指定されたインデックスのCSVレコードを削除します。<br>
	 * @param index レコードリストインデックス
	 * @return 指定されたインデックスに存在するCSVレコード
	 */
	public CSVRecord remove(int index) {
		//expand(index + 1);
		if (index > list.size() - 1) {
			return null;
		}
		return (CSVRecord) list.remove(index);
	}

	/**
	 * 指定されたCSVレコードリストに格納されているすべての要素をリストから削除します。<br>
	 * @param list 削除対象のCSVレコードを保持するリストオブジェクト
	 * @return 処理の結果、リスト内容が変更された場合はtrueを返却
	 */
	public boolean removeAll(CSVRecordList list) {
		return this.list.removeAll(list.list);
	}

	/**
	 * 指定されたCSVレコード位置を取得します。<br>
	 * @param record 位置取得対象CSVレコード
	 * @return 指定された要素がリスト内で最初に検出された位置のインデックス。リストにこの要素がない場合は-1を返却。
	 */
	public int indexOf(CSVRecord record) {
		return this.list.indexOf(record);
	}

	/**
	 * 指定されたCSVレコードの最終出現位置を取得します。<br>
	 * @param record 位置取得対象CSVレコード
	 * @return 指定された要素がリスト内で最後に検出された位置のインデックス。リストにこの要素がない場合は-1を返却。
	 */
	public int lastIndexOf(CSVRecord record) {
		return this.list.lastIndexOf(record);
	}

	/**
	 * CSVレコードリスト内の要素を適切な順序で繰り返し処理する反復子を取得します。<br>
	 * @return  CSVレコードリスト内の要素を適切な順序で繰り返し処理する反復子
	 */
	public ListIterator listIterator() {
		return list.listIterator();
	}

	/**
	 * リスト内の要素を適切な順序で繰り返し処理する、リスト内の指定された位置から開始する反復子を取得します。<br>
	 * @param index nextメソッドの呼び出しによってリスト反復子から返される最初の要素のインデックス
	 * @return  CSVレコードリスト内の要素を適切な順序で繰り返し処理する反復子
	 */
	public ListIterator listIterator(int index) {
		//expand(index);
		return list.listIterator(index);
	}

	/**
	 * 指定されたインデックス範囲のCSVレコードリストを取得します。<br>
	 * @param fromIndex 開始インデックス
	 * @param toIndex 終了インデックス
	 * @return 指定範囲のCSVレコードリスト
	 */
	public CSVRecordList subList(int fromIndex, int toIndex) {
		//expand(fromIndex);
		//expand(toIndex);
		List record = this.list.subList(fromIndex, toIndex);
		CSVRecordList result = new CSVRecordList();
		for (Iterator iterator = record.iterator(); iterator.hasNext();) {
			result.add((CSVRecord) iterator.next());
		}
		return result;
	}

	/**
	 * オブジェクトの文字列表現を返します。<br>
	 * @return オブジェクトの文字列表現
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		//		StringBuffer buffer = new StringBuffer();
		//		buffer.append("{");
		//		buffer.append("}");
		//		return buffer.toString();
		return list.toString();
	}
}

