/*
 * 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.column;

import org.opengion.hayabusa.db.CellEditor;
import org.opengion.hayabusa.db.DBColumn;
import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.fukurou.util.Attributes;
import org.opengion.fukurou.util.StringUtil;
import org.opengion.fukurou.util.TagBuffer;

/**
 * CellEditor の具象クラスで、カラムのデータを編集する場合に使用するクラスです。
 *
 *  カラムの表示に必要な属性は, DBColumn オブジェクト より取り出します。
 * このクラスは、DBColumn オブジェクト毎に１つ作成されます。
 *
 * @og.group データ編集
 *
 * @version  4.0
 * @author	 Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public abstract class AbstractEditor implements CellEditor {
	private final int COLUMNS_MAXSIZE = HybsSystem.sysInt( "HTML_COLUMNS_MAXSIZE" ) ;	// 表示フィールドの大きさ
	// 3.5.4.7 (2004/02/06) viewタグで表示する場合のカラムの大きさ
	private final int VIEW_COLUMNS_MAXSIZE = HybsSystem.sysInt( "HTML_VIEW_COLUMNS_MAXSIZE" ) ;

	// 3.3.1.1 (2003/07/03) name , attributes 属性を final にする。
	protected  Attributes	  attributes ;		// SubClass で誤って new することを防止
	protected  String		  name		 ;
	protected  String		  size1		 ;
	protected  String		  size2		 ;
	protected  String		  optAttr	 ;
	protected  TagBuffer	  tagBuffer = new TagBuffer() ;
	protected  String		  eventColumn; // 4.3.6.0 (2009/04/01)
	protected  String		  eventURL;	   // 4.3.6.0 (2009/04/01)
	protected  String		  editor;	   // 4.3.6.0 (2009/04/01)

	/**
	 * デフォルトコンストラクター。
	 * このコンストラクターで、基本オブジェクトを作成します。
	 *
	 * @og.rev 3.1.1.1 (2003/04/03) 各オブジェクトから自分のインスタンスを返すファクトリメソッドを追加。
	 *
	 */
	public AbstractEditor() {
		// ここでは処理を行いません。
	}

	/**
	 * コンストラクター。
	 *
	 * @og.rev 3.1.1.1 (2003/04/03) 各オブジェクトから自分のインスタンスを返すファクトリメソッドを追加。
	 * @og.rev 3.5.4.2 (2003/12/15) 漢字入力（IMEモード）をONにするのを、"K" のみとします。
	 * @og.rev 3.5.4.2 (2003/12/15) size が 1 の場合、CSSファイルでサイズ指定を行うクラスを出力します。
	 * @og.rev 3.5.4.6 (2004/01/30) 漢字入力（IMEモード）をONにするのを、"K" と、"KX" のみとします。
	 * @og.rev 3.5.5.5 (2004/04/23) maxlength の導入
	 * @og.rev 4.0.0 (2005/01/31) getFieldSize メソッドを XHTMLTag から DBColumn へ移動
	 *
	 * @param   clm DBColumn オブジェクト
	 */
	protected AbstractEditor( final DBColumn clm ) {
		name			 = clm.getName();
		String	disabled = clm.isWritable() ? null : "disabled" ;
		eventColumn = clm.getEventColumn(); // 4.3.6.0 (2009/04/01)
		eventURL	= clm.getEventURL();	// 4.3.6.0 (2009/04/01)
		editor		= clm.getEditor();		// 4.3.6.0 (2009/04/01)
		

		int maxlength = clm.getTotalSize();		// 4.0.0 (2005/01/31) メソッド名変更

		attributes = new Attributes();
		attributes.set( "type"		  ,"text" );
		attributes.set( "maxlength"   ,String.valueOf( maxlength ) );
		attributes.set( "disabled"	  ,disabled );

		attributes.addAttributes( clm.getEditorAttributes() );

		String clazz = clm.getDbType();
		attributes.add( "class" ,clazz );
		if( maxlength <= 5 ) {
			attributes.add( "class" ,"S0" + maxlength );
		}

		optAttr = attributes.get( "optionAttributes" );

		// 3.5.5.5 (2004/04/23) size の導入、初期値は、一覧表のサイズにします。
		String size = clm.getViewLength();		// 4.0.0 (2005/01/31)
		if( size != null ) {
			if( size.indexOf(',') >= 0 ) {
				size = size.substring( 0,size.indexOf(',') ) ;
			}
			size1 = size ;
			size2 = size ;
		}
		else {
			// 4.0.0 (2005/01/31) getFieldSize メソッドを XHTMLTag から DBColumn へ移動
			size1 = String.valueOf(clm.getFieldSize( maxlength,COLUMNS_MAXSIZE )) ;
			size2 = String.valueOf(clm.getFieldSize( maxlength,VIEW_COLUMNS_MAXSIZE )) ;
		}
	}

	/**
	 * データの編集用文字列を返します。
	 *
	 * @og.rev 3.5.5.5 (2004/04/23) viewSize の導入
	 * @og.rev 4.3.7.2 (2009/06/15) 属性でidが出力される場合は、idを出力しない
	 *
	 * @param	value String
	 * @return	データの編集用文字列
	 */
	public String getValue( final String value ) {

		TagBuffer tag = new TagBuffer( "input" );
		tag.add( "name"    , name );
		if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) { // 4.3.7.2 (2009/06/15)
			tag.add( "id"      , name ); // 4.3.6.0 (2009/04/01)
		}
		tag.add( "value"   , value );
		tag.add( "size"    , size1 );
		tag.add( tagBuffer.makeTag() );
		tag.add( optAttr );		// 3.5.5.8 (2004/05/20)
		

		// return tag.makeTag();
		return tag.makeTag() + createEventColumnJS( name, editor, -1, eventURL ); // 4.3.6.0 (2009/04/01)
	}

	/**
	 * name属性を変えた、データ表示/編集用のHTML文字列を作成します。
	 * テーブル上の name に 行番号を付加して、名前_行番号 で登録するキーを作成し,
	 * リクエスト情報を１つ毎のフィールドで処理できます。
	 *
	 * @og.rev 2.0.0.3 (2002/09/26) optionAttributes 属性に "$i" を使うとその行数に置き換る機能を追加。
	 * @og.rev 3.1.0.0 (2003/03/20) 名前と行番号の区切り記号を "^" から "__" に変更。
	 * @og.rev 3.5.4.2 (2003/12/15) getFieldSize を、XHTMLTag.getFieldSize に変更。
	 * @og.rev 3.5.4.7 (2004/02/06) viewタグで表示する場合のカラムの大きさ VIEW_COLUMNS_MAXSIZE 追加
	 * @og.rev 3.5.5.0 (2004/03/12) 名前と行番号の区切り記号("__")を、HybsSystem.JOINT_STRING  に変更。
	 * @og.rev 3.5.5.5 (2004/04/23) viewSize の導入、初期値は、一覧表にあわせました。
	 * @og.rev 3.5.5.5 (2004/04/23) 新規に Attributes オブジェクトを作成する方式を止めます。
	 * @og.rev 4.3.7.2 (2009/06/15) 属性でidが出力される場合は、idを出力しない
	 *
	 * @param	row   int 行番号
	 * @param	value String
	 * @return	データ表示/編集用の文字列
	 */
	public String getValue( final int row,final String value ) {
		TagBuffer tag = new TagBuffer( "input" );
		String newName = name + HybsSystem.JOINT_STRING + row;
		// tag.add( "name"    , name + HybsSystem.JOINT_STRING + row );
		tag.add( "name"  , newName ); // 4.3.6.0 (2009/04/01)
		if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) { // 4.3.7.2 (2009/06/15)
			tag.add( "id"    , newName ); // 4.3.6.0 (2009/04/01)
		}
		tag.add( "value"   , value );
		tag.add( "size"    , size2 );
		tag.add( tagBuffer.makeTag() );
		tag.add( optAttr );		// 3.5.5.8 (2004/05/20)

		// return tag.makeTag( row,value );
		return tag.makeTag( row,value ) + createEventColumnJS( name, editor, row, eventURL );
	}
	
	/**
	 * EventColumnをセットした場合に出力するJavaScriptを作ります。
	 * 吐かれるJavaScriptは
	 * eventColumnに対してchangeイベント発生時にmakeColumnを呼びます。
	 * なおかつ１度changeイベントを発生させます。
	 * 以下のようなJavaScriptとなります。
	 * $(function(){$('#EMPNO').change(function(){makeColumn(...);}).change();});
	 * 
	 * rowに負の値を入れると__iを出力しません。
	 * 
	 * @og.rev 4.3.6.0 (2009/04/01)
	 * 
	 * @param clmName
	 * @param clmEditor
	 * @param row
	 * @param URL
	 */
	protected String createEventColumnJS( final String clmName, final String clmEditor, final int row, final String URL ){
		if( eventColumn != null && eventColumn.length() > 0 ){
			StringBuilder rtn = new StringBuilder();
			String[] evntCols = StringUtil.csv2Array( eventColumn );
			for( int i=0; i<evntCols.length; i++ ){
				rtn.append( "<script type=\"text/javascript\">" )
					.append( "$(function(){$('#" )
					.append( evntCols[i] );
				if( row >= 0 ){
					rtn.append( HybsSystem.JOINT_STRING ).append( row );
				}
				
				rtn.append( "').change(function(){" )
					.append( "makeColumn('" )
					.append( clmName );
				if( row >= 0 ){
					rtn.append( HybsSystem.JOINT_STRING ).append( row );
				}
				rtn.append( "','" )
					.append( clmName ).append( "',EC_" )
					.append( clmName )
					.append( ",'" )
					.append( clmEditor ).append( "','" )
					.append( URL ).append( "');}).change();});" )
					.append( "</script>" );
			}
			return rtn.toString();
		}
		return "";
	}
}
