/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.plugin.view;

/**
 * JavaScript のツリー階層を持ったテーブル表示を行う、ツリーテーブル表示クラスです。
 *
 * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。
 * 各HTMLのタグに必要な setter/getterメソッドのみ，追加定義しています。
 *
 * AbstractViewForm を継承している為,ロケールに応じたラベルを出力させる事が出来ます。
 *
 * @og.group 画面表示
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class ViewForm_HTMLTreeBOM extends ViewForm_HTMLTable  {
	/** このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "6.4.2.0 (2016/01/29)" ;

	public static final String COLUMN_LEVEL_KEY = "COLUMN_LEVEL";

	/**
	 * デフォルトコンストラクター
	 *
	 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
	 */
	public ViewForm_HTMLTreeBOM() {
		super();		// これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
	}

	/**
	 * DBTableModel から HTML文字列を作成して返します。
	 * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
	 * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
	 *
	 * @og.rev 3.5.2.1 (2003/10/27) JavaScript 内のダブルコーテーションをシングルコーテーションに変更する。
	 * @og.rev 3.9.0.1 (2007/12/18) DBクラスを出力する。
	 *
	 * @param  stNo     表示開始位置
	 * @param  pgSize   表示件数
	 *
	 * @return  DBTableModelから作成された HTML文字列
	 * @og.rtnNotNull
	 */
	@Override
	public String create( final int stNo, final int pgSize )  {
		// このクラスでは、テーブル全データを使用します。
		if( getRowCount() == 0 ) { return ""; }	// 暫定処置

		final int startNo = 0;
		final int pageSize = getRowCount();

		final int lastNo = getLastNo( startNo, pageSize );

		final StringBuilder out = new StringBuilder( BUFFER_LARGE );

		out.append( getHeader() );

		int level;
//		boolean isFld;
		final int clmCnt = getColumnCount();	// 3.5.5.7 (2004/05/10)
		for( int row=startNo; row<lastNo; row++ ) {
			// カラム==０は、レベルを指定する。
			level = Integer.parseInt( getValueLabel(row,0) );
			// 6.3.9.0 (2015/11/06) Found 'DD'-anomaly for variable(PMD)
//			isFld = false;
//			if( row+1<lastNo ) {
//				final int nextLevel = Integer.parseInt( getValueLabel(row+1,0) );
//				isFld = level < nextLevel ;
//			}
			final boolean isFld = row+1<lastNo && level < Integer.parseInt( getValueLabel(row+1,0) );
			out.append( getLevelScript( level,isFld ) );

			// カラム==０は、レベルを指定するので表示しない。
			for( int column=1; column<clmCnt; column++ ) {
				if( isColumnDisplay( column ) ) {
					out.append("<td class=\""); // 3.9.0.1 (2007/12/18)
					out.append( getColumnDbType(column) );
					out.append("\"> ");
					out.append( getValueLabel(row,column) );
					out.append("</td>");
				}
			}
			out.append( "', '', 'gold')" );
			if( level != 0 ) {
				out.append( ')' );		// 6.0.2.5 (2014/10/31) char を append する。
			}
			out.append( CR );
		}
		out.append( getFutter() );

		return out.toString();
	}

	/**
	 * DBTableModel から テーブルのヘッダータグ文字列を作成して返します。
	 * JavaScript の TreeBody では、JavaScriptに関連する定義もこのヘッダーに
	 * 含めます。
	 *
	 * @og.rev 3.5.2.1 (2003/10/27) JavaScript 内のダブルコーテーションをシングルコーテーションに変更する。
	 * @og.rev 3.9.0.1 (2007/12/18) 文字サイズ変更スクリプト対応のため、id="viewTable"を出力
	 *
	 * @return  テーブルのヘッダータグ文字列
	 * @og.rtnNotNull
	 */
	@Override
	protected String getHeader() {
		final StringBuilder buf
				= new StringBuilder( BUFFER_MIDDLE )
					.append("<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\"  summary=\"bomTable\" id=\"viewTable\">")
					.append( CR )
					.append("<script type=\"text/javascript\">")
					.append( CR )
					.append("<!--")
					.append( CR )
					.append("aux0 = gFld('");
		// カラム==０は、レベルを指定するので表示しない。
		final int clmCnt = getColumnCount();	// 3.5.5.7 (2004/05/10)
		for( int column=1; column<clmCnt; column++ ) {
			if( isColumnDisplay( column ) ) {
				buf.append("<th>").append( getColumnLabel(column) ).append("</th>");
			}
		}
		buf.append("', '', 'gold')").append( CR );

		return buf.toString();
	}

	/**
	 * DBTableModel から テーブルのフッタータグ文字列を作成して返します。
	 * JavaScript の TreeBody では、JavaScriptに関連する定義もこのフッターに
	 * 含めます。
	 *
	 * @return  テーブルのフッタータグ文字列
	 * @og.rtnNotNull
	 */
	protected String getFutter() {
		final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
						.append("initializeDocument()").append( CR )
						.append("//-->").append( CR )
						.append("</script>").append( CR )
						.append("</table>").append( CR );

		return buf.toString();
	}

	/**
	 * 行のレベルに応じた JavaScript関数のヘッダー部分を返します。
	 *
	 * @og.rev 3.5.2.1 (2003/10/27) JavaScript 内のダブルコーテーションをシングルコーテーションに変更する。
	 *
	 * @param	lvl		ツリーのレベル
	 * @param	isFld	フォルダかどうか[true:フォルダ/false:最下層]
	 *
	 * @return	JavaScript関数のヘッダー部分
	 * @og.rtnNotNull
	 */
	private String getLevelScript( final int lvl,final boolean isFld ) {

		final String auxX = "\taux" + ( lvl );
		final String auxY = "aux" + ( lvl-1 );

		final String rtn ;
		if( isFld ) {
			rtn = auxX + " = insFld(" + auxY + ", gFld('";
		}
		else {
			rtn = "\tinsFld(" + auxY + ", gLnk('CONTENTS','";
		}

		return rtn;
	}
}
