/*
 * Paraselene
 * Copyright (c) 2009  Akira Terasaki
 * このファイルは同梱されているLicense.txtに定めた条件に同意できる場合にのみ
 * 利用可能です。
 */
package paraselene.tag.table;


import java.util.*;
import paraselene.*;
import paraselene.tag.*;

/**
 * TABLEタグ。
 * スレッドセーフです。
 */
public class Table extends Tag {
	private static final long serialVersionUID = 2L;
	static final String	TR = "tr";

	/**
	 * コンストラクタ。
	 */
	public Table() {
		this( "table" );
	}

	Table( String s ) {
		super( s, false );
	}

	protected Tag newReplica() {
		return new Table();
	}

	/**
	 * 行の列挙。trタグを検出し配列にして返します。
	 * @return 行。
	 */
	public synchronized Line[] getLineArray() {
		Tag[]	tag = getTagArray();
		ArrayList<Line>	line = new ArrayList<Line>();
		for ( int i = 0; i < tag.length; i++ ) {
			if ( tag[i] instanceof Line ) {
				line.add( (Line)tag[i] );
			}
		}
		return line.toArray(new Line[0]);
	}

	/**
	 * 行の追加。末尾に追加されます。
	 * @param line	追加行。
	 */
	public void addLine( Line line ) {
		addHTMLPart( line );
	}

	/**
	 * 行の追加。指定位置に追加します。
	 * 現在の最大行よりも大きい位置を指定すると末尾に追加します。
	 * @param idx 行番号。
	 * @param line	追加行。
	 */
	public void addLine( int idx, Line line ) {
		Line[]	l = getLineArray();
		if ( l.length <= idx ) {
			addHTMLPart( line );
			return;
		}
		addHTMLPart( indexOf( l[idx] ), line );
	}

	/**
	 * 行番号を返す。最初に登場した指定インスタンスの位置を返します。
	 * @param line 検索行。
	 * @return 行番号。無ければ-1を返す。
	 */
	public int indexOfLine( Line line ) {
		Line[]	l = getLineArray();
		for ( int i = 0; i < l.length; i++ ) {
			if ( l[i] == line )	return i;
		}
		return -1;
	}

	/**
	 * 行の削除。指定行を削除します。
	 * 現在の最大行よりも大きい位置を指定すると何もしません。
	 * @param idx 行番号。
	 */
	public void removeLine( int idx ) {
		Line[]  l = getLineArray();
		if ( l.length <= idx )	return;
		removeHTMLPart( l[idx] );
	}

	/**
	 * 行の削除。最初に登場した指定インスタンスを削除します。
	 * @param line 削除行。
	 */
	public void removeLine( Line line ) {
		removeHTMLPart( line );
	}

	/**
	 * 行の削除。指定範囲を削除します。
	 * @param start 開始行。負数を与えると0行目とみなします。
	 * @param end 終了行。負数や最大行を越えると最大行とみなします。
	 */
	public void removeLine( int start, int end ) {
		Line[]	l = getLineArray();
		if ( start < 0 )	start = 0;
		if ( end < 0 )	end = l.length - 1;
		for ( int i = start; i <= end; i++ ) {
			removeHTMLPart( l[i] );
		}
	}

	/**
	 * 行の複製作成。指定行の複製インスタンスを返します。<br>
	 * 行番号が0未満または最大行数を超える場合はnullを返します。
	 * @param idx 行番号。
	 * @return 行の複製。
	 */
	public Line getLineReplica( int idx ) {
		Line[]	l = getLineArray();
		if ( l.length == 0 )	return null;
		if ( idx < 0 || idx >= l.length )	return null;
		return (Line)l[idx].getReplica();
	}

	/**
	 * 行数の取得。
	 * @return 行数。
	 */
	public int getLineCount() {
		Line[]	l = getLineArray();
		return l.length;
	}
}

