/*
 * 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.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 FIELD_SIZE		= 15 ;			// 6.2.0.0 (2015/02/27) ﾌｨｰﾙﾄﾞｻｲｽﾞ 追加

	/** 内部ﾃﾞｰﾀのｶﾗﾑ数 {@value}	*/
	public static final int DATA_SIZE		= 16 ;			// 6.2.0.0 (2015/02/27) 件数を増やす

	/** ﾘｿｰｽ読み込みのために一時利用 4.3.5.7 (2009/03/22) */
	/* default */ static final int FG_LOAD			= 16 ;	// 6.2.0.0 (2015/02/27) 位置をずらす
	/** FGLOAD の読み込み済み設定用のUNIQ 6.3.1.1 (2015/07/10) */
	/* default */ static final int UNIQ				= 17 ;
	/** FGLOAD の読み込み済み設定用のSYSTEM_ID 6.3.1.1 (2015/07/10) */
	/* default */ static final int SYSTEM_ID		= 18 ;

	/** 内部ﾃﾞｰﾀのｶﾗﾑ番号 {@value}	*/
	public static final int KBSAKU			= 19 ;			// 7.4.2.0 (2021/05/18) 内部的に使ってないが定義しておく
	/** 内部ﾃﾞｰﾀのｶﾗﾑ番号 {@value}	*/
	public static final int SNO				= 20 ;			// 7.2.6.1 (2020/07/17) 内部的に使ってないが定義しておく

	private final String	name			;				// ｶﾗﾑ名
	private final String	className		;				// ﾃﾞｰﾀの属性(VARCHAR2,NUMBER...)
	private final String	maxlength		;				// 最大桁数
	private final String	viewLength		;				// 表示桁数
	private final String	fieldSize		;				// 6.2.0.0 (2015/02/27) 入力枠ｻｲｽﾞ
	private final String	renderer		;				// 表示種別
	private final String	editor			;				// 編集種別
	private final String	dbType			;				// 文字種別(S9,X...)
	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		;				// ﾘｿｰｽDBから作成されたかどうか

	/**
	 * 配列文字列のﾃﾞｰﾀを元に､ColumnDataｵﾌﾞｼﾞｪｸﾄを構築します｡
	 * このｺﾝｽﾄﾗｸﾀは､他のﾊﾟｯｹｰｼﾞから呼び出せないように､
	 * ﾊﾟｯｹｰｼﾞﾌﾟﾗｲﾍﾞｰﾄにしておきます｡
	 * このｺﾝｽﾄﾗｸﾀは､DBﾘｿｰｽﾌｧｲﾙを想定しています｡
	 *
	 * @og.rev 4.3.0.0 (2008/07/04) ﾛｰﾙﾓｰﾄﾞﾏﾙﾁ対応
	 * @og.rev 5.1.6.0 (2010/05/01) DBTypeの初期値を "XK" とします｡
	 * @og.rev 5.2.2.0 (2010/11/01) ﾊﾟﾗﾒｰﾀｰもVer3互換のためNVAL2で処理します｡
	 * @og.rev 5.5.8.5 (2012/11/27) 編集ﾊﾟﾗﾒｰﾀで､"=" と記述されている場合は､表示ﾊﾟﾗﾒｰﾀを利用する｡
	 * @og.rev 6.1.0.0 (2014/12/26) ｶﾗﾑの表示桁数(小数部)対応
	 * @og.rev 6.2.0.0 (2015/02/27) ﾌｨｰﾙﾄﾞｻｲｽﾞ 追加(VIEW_LENGTHと分離して､役割を明確にする)
	 * @og.rev 8.3.1.0 (2022/10/14) 入力枠ｻｲｽﾞの復活(※RELEASE-NOTES_7.txtに7.2.7.0の対応が「一旦保留」とｺﾒﾝﾄされている為)
	 *
	 * @param	data	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,FIELD_SIZE
	 *
	 */
	public ColumnData( final String[] data ) {
		name		= data[CLM].intern() ;										// ｶﾗﾑ名
		className	= data[CLS_NAME].intern() ;									// ﾃﾞｰﾀの属性
		maxlength	= data[USE_LENGTH].replace( '.',',' ).intern();				// 最大桁数
		renderer	= nval2( data[RENDERER]		 , null ) ;						// 表示種別
		editor		= nval2( data[EDITOR]		 , null ) ;						// 編集種別
		dbType		= nval2( data[DBTYPE]		 , "XK" ) ;						// 文字種別 5.1.6.0 (2010/05/01)
		dataDef		= nval2( data[DATA_DEFAULT]	 , ""   ) ;						// ﾃﾞｰﾀのﾃﾞﾌｫﾙﾄ値
		labelClm	= nval2( data[LABEL_CLM]	 , name ) ;						// ﾗﾍﾞﾙｶﾗﾑ
		codeClm		= nval2( data[CODE_CLM]		 , name ) ;						// ｺｰﾄﾞｶﾗﾑ
		columnPrm	= nval2( data[CLM_PARAM]	 , null ) ;						// ｶﾗﾑﾊﾟﾗﾒｰﾀ
		rendererPrm	= nval2( data[RENDERER_PARAM], null ) ;						// 表示ﾊﾟﾗﾒｰﾀ
		dbTypePrm	= nval2( data[TYPE_PARAM]	 , null ) ;						// 文字ﾊﾟﾗﾒｰﾀ
		roles		= nval2( data[ROLES]		 , null ) ;						// ｶﾗﾑﾛｰﾙ
//		fieldSize	= nval2( data[FIELD_SIZE]	 , null ) ;						// 6.2.0.0 (2015/02/27) 入力枠ｻｲｽﾞ 8.3.1.0 (2022/10/14) Delete
		official	= true;														// ﾘｿｰｽDBから作成されたかどうか

		// 6.1.0.0 (2014/12/26) ｶﾗﾑの表示桁数(小数部)対応と､ｶﾝﾏ置換処理
		final String viewLen = nval2( data[VIEW_LENGTH] , null ) ;
		viewLength = viewLen == null ? null : viewLen.replace( '.',',' ).intern();

	//	// 7.2.7.0 (2020/08/07) fieldSize には、viewLength を設定する(昔に戻る)。
	//	if( viewLength != null && viewLength.indexOf( ',' ) > 0 ) {		// ｶﾝﾏを含む場合は、10桁固定にします。
	//		fieldSize = "10" ;
	//	}
	//	else {
	//		fieldSize = viewLength;
	//	}
		// 8.3.1.0 (2022/10/14) 入力枠ｻｲｽﾞの復活(※RELEASE-NOTES_7.txtに一旦保留とｺﾒﾝﾄされている)
		final String fSize;
		if( viewLength != null && viewLength.indexOf( ',' ) > 0 ) {				// ｶﾝﾏを含む場合
			final String[] fSizeAry = viewLength.split(",");
			fSize = String.valueOf(Integer.parseInt(fSizeAry[0]) + Integer.parseInt(fSizeAry[1]) +1);
		}
		else {
			fSize = viewLength;
		}
		fieldSize	= nval2( data[FIELD_SIZE] , fSize ) ;						// 入力枠サイズ

		// 5.5.8.5 (2012/11/27) 編集ﾊﾟﾗﾒｰﾀで､"=" と記述されている場合は､表示ﾊﾟﾗﾒｰﾀを利用する｡
		final String tempEditPrm = nval2( data[EDITOR_PARAM], null ) ;
		if( "=".equals( tempEditPrm ) ) {
			editorPrm = rendererPrm	;
		}
		else {
			editorPrm = tempEditPrm	;
		}

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

		// x,y 形式の場合､x + 2 桁で表されます｡(ﾏｲﾅｽ記号と小数点記号)
		// 7,3 は､ xxxx,yyy のﾌｫｰﾏｯﾄで､ﾃﾞｰﾀ長は､9 になります｡
		final 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 ; }

	/**
	 * 文字列の表示文字数を返します｡
	 *
	 * これは､ﾃｷｽﾄﾌｨｰﾙﾄﾞのｻｲｽﾞではなく､Renderer系の表示に使用する
	 * 文字数指定に使われます｡
	 * 無指定の場合は､null が返されます｡
	 *
	 * @return	表示文字数
	 */
	public String getViewLength() { return viewLength; }

	/**
	 * ﾌｨｰﾙﾄﾞの入力枠ｻｲｽﾞを返します｡
	 *
	 * ﾃｷｽﾄﾌｨｰﾙﾄﾞのｻｲｽﾞに該当します｡
	 * 何も指定しない場合は､null が返ります｡
	 * その場合の､入力枠ｻｲｽﾞは､maxlength が使用されます｡
	 * ただし､桁数が大きい場合は､ｼｽﾃﾑ定数の HTML_COLUMNS_MAXSIZE や､
	 * HTML_VIEW_COLUMNS_MAXSIZE で指定された値が使われます｡
	 * それらの値よりも､ここで取得 した fieldSize が優先されます｡
	 *
	 * @og.rev 6.2.0.0 (2015/02/27) ﾌｨｰﾙﾄﾞｻｲｽﾞ 追加(VIEW_LENGTHと分離して､役割を明確にする)
	 *
	 * @return	入力枠ｻｲｽﾞ
	 */
	public String getFieldSize() { return fieldSize; }

	/**
	 * 表示種別を返します｡
	 *
	 * @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; }

	/**
	 * ﾘｿｰｽDBから作成されたかどうかを返します｡
	 * 正式な場合は､true / ﾘｿｰｽになく､独自に作成された場合は､false になります｡
	 *
	 * @return	ﾘｿｰｽDBから作成されたかどうか
	 */
	public boolean isOfficial() { return official; }

	/**
	 * 内部ﾃﾞｰﾀの文字列配列を返します｡
	 *
	 * @og.rev 6.2.0.0 (2015/02/27) ﾌｨｰﾙﾄﾞｻｲｽﾞ 追加(VIEW_LENGTHと分離して､役割を明確にする)
	 *
	 * @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		;
		data[FIELD_SIZE		] = fieldSize	;									// 6.2.0.0 (2015/02/27)

		return data ;
	}
}
