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

import static org.opengion.fukurou.util.StringUtil.nval2;

/**
 * systemId に対応したカラムデータを作成します。
 *
 * カラムデータは、項目(CLM)に対して、各種カラム情報を持っています。
 * エンジン内部で使用している DBColumn オブジェクトは、RENDERER や EDITOR など
 * 実際にはオブジェクトで管理していますが、この ColumnData では、それらのキーとなる
 * 文字列を持っています。実際に DBColumn オブジェクトの構築時に、各属性オブジェクトを
 * 生成（または、キャッシュから取り出し）ます。
 *
 * カラムデータを作成する場合は、同一カラムで、作成区分(KBSAKU)違いの場合は、
 * 最も大きな作成区分を持つコードを使用します。
 * 作成区分(KBSAKU)は、0:システム予約、1:アプリ設定、2:ユーザー設定 という具合に
 * カスタマイズの度合いに応じて大きな数字を割り当てることで、キー情報を上書き修正
 * することが可能になります。（削除することは出来ません。）
 *
 * @og.rev 4.0.0 (2004/12/31) 新規作成
 * @og.group リソース管理
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public final class ColumnData {

	/** 内部データのカラム番号 {@value}	*/
	public static final int CLM				= 0 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int CLS_NAME		= 1 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int USE_LENGTH		= 2 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int VIEW_LENGTH		= 3 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int RENDERER		= 4 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int EDITOR			= 5 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int DBTYPE			= 6 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int DATA_DEFAULT	= 7 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int LABEL_CLM		= 8 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int CODE_CLM		= 9 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int CLM_PARAM		= 10 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int RENDERER_PARAM	= 11 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int EDITOR_PARAM	= 12 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int TYPE_PARAM		= 13 ;
	/** 内部データのカラム番号 {@value}	*/
	public static final int ROLES			= 14 ;
	/** 内部データのカラム数 {@value}	*/
	public static final int DATA_SIZE		= 15 ;
	/** リソース読み込みのために一時利用 4.3.5.7 (2009/03/22) */
	public static final int FG_LOAD			= 15 ;

	private final String	name			;		// カラム名
	private final String	className		;		// データの属性
	private final String	maxlength		;		// 使用桁数
	private final String	viewLength		;		// 表示桁数
	private final String	renderer		;		// 表示種別
	private final String	editor			;		// 編集種別
	private final String	dbType			;		// 文字種別
	private final String	dataDef			;		// データのデフォルト値
	private final String	labelClm		;		// ラベルカラム
	private final String	codeClm			;		// コードカラム
	private final String	columnPrm		;		// カラムパラメータ
	private final String	rendererPrm		;		// 表示パラメータ
	private final String	editorPrm		;		// 編集パラメータ
	private final String	dbTypePrm		;		// 文字パラメータ
	private final String	roles			;		// カラムロール
	private final RoleMode	roleMode		;		// 4.3.0.0 (2008/07/04) ロールズとモードを管理するオブジェクト

	private final int		totalSize		;		// 総桁数(小数点も含む)
	private final int		sizeX			;		// カラムの文字桁数（整数部）
	private final int		sizeY			;		// カラムの文字桁数（少数部）
	private final boolean   official		;		// リソースＤＢから作成されたかどうか

	/**
	 * 配列文字列のデータを元に、ColumnDataオブジェクトを構築します。
	 * このコンストラクタは、他のパッケージから呼び出せないように、
	 * パッケージプライベートにしておきます。
	 * このコンストラクタは、ＤＢリソースファイルを想定しています。
	 *
	 * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
	 *
	 * @param data String[] CLM,CLS_NAME,USE_LENGTH,VIEW_LENGTH,
	 *                      RENDERER,EDITOR,DBTYPE,DATA_DEFAULT,LABEL_CLM,CODE_CLM,
	 *                      CLM_PARAM,RENDERER_PARAM,EDITOR_PARAM,TYPE_PARAM,ROLES
	 *
	 */
	public ColumnData( final String[] data ) {
		name		= data[CLM].intern() ;					// カラム名
		className	= data[CLS_NAME].intern() ;				// データの属性
//		maxlength	= StringUtil.toNumber( data[USE_LENGTH] ).intern() ;	// 使用桁数
		maxlength	= data[USE_LENGTH].replace( '.',',' ).intern();			// 使用桁数
		viewLength	= nval2( data[VIEW_LENGTH], null ) ;	// 表示桁数
		renderer	= nval2( data[RENDERER], null ) ;		// 表示種別
		editor		= nval2( data[EDITOR], null ) ;			// 編集種別
		dbType		= nval2( data[DBTYPE], null ) ;			// 文字種別
		dataDef		= nval2( data[DATA_DEFAULT] , ""   ) ;	// データのデフォルト値
		labelClm	= nval2( data[LABEL_CLM]    , name ) ;	// ラベルカラム
		codeClm		= nval2( data[CODE_CLM]     , name ) ;	// コードカラム
		columnPrm	= data[CLM_PARAM] ;						// カラムパラメータ
		rendererPrm	= data[RENDERER_PARAM] ;				// 表示パラメータ
		editorPrm	= data[EDITOR_PARAM] ;					// 編集パラメータ
		dbTypePrm	= data[TYPE_PARAM] ;					// 文字パラメータ
		roles		= nval2( data[ROLES] , null ) ;			// カラムロール
		official	= true;									// リソースＤＢから作成されたかどうか

		roleMode	= RoleMode.newInstance( roles );	// ロールモード

		// x,y 形式の場合、x + 2 桁で表されます。(マイナス記号と小数点記号)
		// 7,3 は、 xxxx,yyy のフォーマットで、データ長は、9 になります。
		int ch = maxlength.indexOf( ',' ) ;
		if( ch > 0 ) {
			sizeY = Integer.parseInt( maxlength.substring( ch+1 ) );
			sizeX = Integer.parseInt( maxlength.substring( 0,ch ) ) - sizeY;
			totalSize = sizeX + sizeY+ 2;
		}
		else {
			sizeY = 0;
			sizeX = Integer.parseInt( maxlength );
			if( "S9".equals( dbType ) ) {
				totalSize = sizeX + 1;	// 数字型の場合は、マイナス記号分を加える。
			}
			else {
				totalSize = sizeX ;
			}
		}
	}

	/**
	 * カラム名を返します。
	 *
	 * @return  カラム名
	 */
	public String getName() { return name; }

	/**
	 * カラムのデータの属性を返します。
	 *
	 * @return  カラムのデータの属性
	 */
	public String getClassName() { return className; }

	/**
	 * フィールドの使用桁数を返します。
	 * 少数指定の場合は、"7,3" のようなカンマで整数部、小数部を区切った書式になります。
	 * 7,3 は、 xxxx,yyy のフォーマットで、整数部４桁、小数部３桁を意味します。
	 *
	 * @return  使用桁数
	 */
	public String getMaxlength() { return maxlength; }

	/**
	 * フィールドのデータ長を返します。
	 * 通常は、整数型の文字列とデータ長は同じですが,小数点を表すデータ長は
	 * x.y 形式の場合、x + 1 桁で表されます。
	 * 6.2 は、 xxxx.yy のフォーマットです。
	 *
	 * @return  データ長定義文字列
	 */
	public int getTotalSize() { return totalSize; }

	/**
	 * フィールドの整数部のデータ長を返します。
	 *
	 * @return  データ長定義文字列
	 */
	public int getSizeX() { return sizeX ; }

	/**
	 * フィールドの小数部のデータ長を返します。
	 *
	 * @return  データ長定義文字列
	 */
	public int getSizeY() { return sizeY ; }

	/**
	 * フィールドの表示桁数を返します。
	 *
	 * @return  表示桁数
	 */
	public String getViewLength() { return viewLength; }

	/**
	 * 表示種別を返します。
	 *
	 * @return  表示種別の文字列
	 */
	public String getRenderer() { return renderer; }

	/**
	 * 編集種別を返します。
	 *
	 * @return  編集種別
	 */
	public String getEditor() { return editor; }

	/**
	 * 文字種別を返します。
	 *
	 * @return  文字種別
	 */
	public String getDbType() { return dbType; }

	/**
	 * ラベルカラムを返します。
	 *
	 * @return  ラベルカラム
	 */
	public String getLabelColumn() { return labelClm; }

	/**
	 * コードカラムを返します。
	 *
	 * @return  コードカラム
	 */
	public String getCodeColumn() { return codeClm; }

	/**
	 * データのデフォルト値を返します。
	 *
	 * @return  データのデフォルト値
	 */
	public String getDefault() { return dataDef; }

	/**
	 * カラムのパラメータを取得します。
	 *
	 * @return	カラムパラメータ
	 */
	public String getColumnParam() { return columnPrm; }

	/**
	 * 表示用レンデラーのパラメータを取得します。
	 *
	 * @return	表示パラメータ
	 */
	public String getRendererParam() { return rendererPrm; }

	/**
	 * 編集用エディターのパラメータを取得します。
	 *
	 * @return	編集パラメータ
	 */
	public String getEditorParam() { return editorPrm; }

	/**
	 * データタイプのパラメータを取得します。
	 *
	 * @return	データタイプのパラメータ
	 */
	public String getDbTypeParam() { return dbTypePrm; }

	/**
	 * カラムロールを取得します。
	 *
	 * @return	カラムロール
	 */
	public String getRoles() { return roles; }

	/**
	 * カラムオブジェクトのロールモードを返します。
	 *
	 * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
	 *
	 * @return カラムオブジェクトのロールモード
	 */
	public RoleMode getRoleMode() { return roleMode; }

	/**
	 * リソースＤＢから作成されたかどうかを返します。
	 * 正式な場合は、true / リソースになく、独自に作成された場合は、false になります。
	 *
	 * @return official リソースＤＢから作成されたかどうか
	 *
	 */
	public boolean isOfficial() { return official; }

	/**
	 * 内部データの文字列配列を返します。
	 *
	 * @return	内部データの文字列配列
	 */
	public String[] getColumnData() {
		String[] data = new String[DATA_SIZE];

		data[CLM			] = name		;
		data[CLS_NAME		] = className	;
		data[USE_LENGTH 	] = maxlength	;
		data[VIEW_LENGTH	] = viewLength	;
		data[RENDERER		] = renderer	;
		data[EDITOR 		] = editor		;
		data[DBTYPE 		] = dbType		;
		data[DATA_DEFAULT	] = dataDef		;
		data[LABEL_CLM		] = labelClm	;
		data[CODE_CLM		] = codeClm		;
		data[CLM_PARAM		] = columnPrm	;
		data[RENDERER_PARAM	] = rendererPrm	;
		data[EDITOR_PARAM	] = editorPrm	;
		data[TYPE_PARAM 	] = dbTypePrm	;
		data[ROLES			] = roles		;

		return data ;
	}
}
