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

import java.io.PrintWriter;
import java.util.List;

import org.odftoolkit.odfdom.OdfFileDom;
import org.odftoolkit.odfdom.doc.office.OdfOfficeAutomaticStyles;
import org.odftoolkit.odfdom.doc.office.OdfOfficeMasterStyles;
import org.odftoolkit.odfdom.doc.style.OdfStyle;
import org.odftoolkit.odfdom.doc.style.OdfStyleFooter;
import org.odftoolkit.odfdom.doc.style.OdfStyleFooterLeft;
import org.odftoolkit.odfdom.doc.style.OdfStyleHeader;
import org.odftoolkit.odfdom.doc.style.OdfStyleHeaderLeft;
import org.odftoolkit.odfdom.doc.style.OdfStyleMasterPage;
import org.odftoolkit.odfdom.doc.style.OdfStylePageLayout;
import org.odftoolkit.odfdom.doc.style.OdfStyleParagraphProperties;
import org.odftoolkit.odfdom.doc.style.OdfStyleTableCellProperties;
import org.odftoolkit.odfdom.doc.table.OdfTableCell;
import org.odftoolkit.odfdom.doc.table.OdfTableRow;
import org.odftoolkit.odfdom.dom.element.style.StylePageLayoutPropertiesElement;
import org.odftoolkit.odfdom.dom.style.OdfStyleFamily;
import org.opengion.fukurou.model.NativeType;
import org.opengion.fukurou.util.HybsEntry;
import org.opengion.hayabusa.common.HybsSystemException;
import org.opengion.hayabusa.db.DBColumn;
import org.opengion.hayabusa.db.DBTableModel;
import org.w3c.dom.Node;

/**
 * Calcファイルの書き出しクラスです。
 *
 * このクラスでは、通常の出力クラスと異なり、データ部分には、データではなく、
 * {&#064;カラム名_行番号}が出力されます。
 *
 * この出力結果は、通常、Calc帳票システムの雛形を作成するための、元情報として
 * 利用することを想定しています。
 *
 * @og.group ファイル出力
 *
 * @version  5.0
 * @author	 Hiroki Nakamura
 * @since    JDK6.0,
 */
public class TableWriter_CalcDef extends TableWriter_Calc {
	//* このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "4.0.0 (2005/08/31)" ;

	private static final int INIT_DATA_SIZE	= 25;

	private int dataSize	= INIT_DATA_SIZE;

	/**
	 * PrintWriter に DBTableModelのテーブル情報を書き込みます。
	 * このクラスでは，データを ダブルコーテーション(")で囲みます。
	 * PrintWriter に DBTableModelのテーブル情報を書き込みます。
	 *
	 * @og.rev 5.1.8.0 (2010/07/01) コメント出力(CalcDefAno)追加による対応
	 *
	 * @param	table  DBTableModelオブジェクト
	 * @param	writer PrintWriterオブジェクト
	 */
	@Override
	protected void writeData( final DBTableModel table,final PrintWriter writer ) {
		for( int r=0; r<dataSize; r++ ) {
			OdfTableRow row = new OdfTableRow( contentDom );

			if( useNumber ) {
//				String val = "ROWNO_" + String.valueOf( r );
				String val = "ROWNO_" + r ;
				row.appendCell( createTextCell( contentDom, val, null, true, true ) );
			}

			boolean[] cellType = new boolean[numberOfColumns];
			for( int i=0; i<numberOfColumns; i++ ) {
				int clm = clmNo[i];
				NativeType nativeType = dbColumn[clm].getNativeType();
				switch( nativeType ) {
					case INT    :
					case LONG   :
					case DOUBLE :
						cellType[i] = true ;
						break;
					case STRING :
					case CALENDAR :
					default :
						cellType[i] = false ;
						break;
				}
			}

			for( int i=0; i<numberOfColumns; i++ ) {
				int clm = clmNo[i];
//				String val = String.valueOf( table.getColumnName( clm ) ) + "_" + String.valueOf( r );
				String val = table.getColumnName( clm ) + "_" + r ;
				row.appendCell( createTextCell( contentDom, val, table.getDBColumn( clm ), cellType[i], false ) );
				row.setStyleName( "ro1" );
			}

			sheet.appendRow( row );
		}
	}

	/**
	 * テキストコンテンツ用のセルを生成する
	 *
	 * @og.rev 5.1.8.0 (2010/07/01) コメント出力(CalcDefAno)追加による対応
	 *
	 * @param	contentDom	OdfFileDomオブジェクト
	 * @param	content		コンテンツ
	 * @param	col			DBColumnオブジェクト
	 * @param	isCellTypeNumber	[true:数字型/false:文字型]
	 * @param	isNumberList		[true:数字リスト=999/false:通常]
	 *
	 * @return	テキストコンテンツ用のセル
	 */
//	protected OdfTableCell createTextCell( final OdfFileDom contentDom, final String content, final Boolean isCellTypeNumber, final Boolean isNumberList ) {
	protected OdfTableCell createTextCell( final OdfFileDom contentDom, final String content, final DBColumn col, final Boolean isCellTypeNumber, final Boolean isNumberList ) {
		OdfTableCell cell = super.createTextCell( contentDom, "{@" + content + "}", false, isNumberList );
		if( isNumberList ) {
			OdfStyle style = contentAutoStyles.newStyle( OdfStyleFamily.TableCell );
			style.setProperty( OdfStyleTableCellProperties.TextAlignSource, "fix" );
			style.setProperty( OdfStyleTableCellProperties.RepeatContent, "false" );
			style.setProperty( OdfStyleParagraphProperties.TextAlign, "end" );
			style.setProperty( OdfStyleParagraphProperties.MarginRight, "0cm" );
			String cellStyleName = style.getStyleNameAttribute();
			cell.setStyleName( cellStyleName );
		}

		return cell;
	}

	/**
	 * デフォルトで用意されているStylesを調整します。
	 *
	 * ヘッダー表示しない
	 * フッターを数字のみにして、右端に出す
	 * ページレイアウトを横にする
	 * ページの設定を、拡大縮小モードを「印刷範囲をページ数に合わせる」に設定(1ページ)
	 */
	@Override
	protected void resetAutoStylesAndMasterStyles() {
		try {
			// AutomaticStyles調整
			OdfOfficeAutomaticStyles oas = wb.getStylesDom().getAutomaticStyles();
			OdfStylePageLayout spl = oas.getPageLayout( "pm1" );
			spl.setProperty( StylePageLayoutPropertiesElement.PageHeight, "21.00cm" );
			spl.setProperty( StylePageLayoutPropertiesElement.PageWidth, "29.70cm" );
			spl.setProperty( StylePageLayoutPropertiesElement.PrintOrientation, "landscape" );
			spl.setProperty( StylePageLayoutPropertiesElement.ScaleToPages, "1" );

			// MasterStyles調整
			OdfOfficeMasterStyles oms = wb.getOfficeMasterStyles();
			OdfStyleMasterPage smp = oms.getMasterPage( "Default" );

			// MasterPageのデフォルトで用意されているノードを削除
			Node fcd = smp.getFirstChild();
			while( fcd != null ) {
				smp.removeChild( fcd );
				fcd = smp.getFirstChild();
			}

			// MasterPageのノードを定義と追加
			OdfStyleHeader sh = new OdfStyleHeader( wb.getStylesDom() );
			OdfStyleHeaderLeft shl = new OdfStyleHeaderLeft( wb.getStylesDom() );
			sh.setStyleDisplayAttribute( false );
			shl.setStyleDisplayAttribute( false );
			smp.appendChild( sh );
			smp.appendChild( shl );
			OdfStyleFooter sf = new OdfStyleFooter( wb.getStylesDom() );
			OdfStyleFooterLeft sfl = new OdfStyleFooterLeft( wb.getStylesDom() );
			sf.newStyleRegionRightElement().newTextPElement().newTextPageNumberElement();
			sfl.setStyleDisplayAttribute( false );
			smp.appendChild( sf );
			smp.appendChild( sfl );
		}
		catch( Exception ex ) {
			String errMsg = "AutomaticStylesとMasterStyles調整できません";
			throw new HybsSystemException( errMsg, ex );
		}
	}

	/**
	 * パラメーターリストをセットします。
	 * 内部は、HybsEntry クラスを持っています。
	 * 引数が、null の場合は、何もしません。
	 *
	 * @param	listParam	HybsEntryリスト
	 */
	@Override
	public void setParam( final List<HybsEntry> listParam ) {
		if( listParam != null && !listParam.isEmpty() ) {
			for( HybsEntry entry : listParam ) {
				if( "Size".equalsIgnoreCase( entry.getKey() ) ) {
					dataSize = Integer.parseInt( entry.getValue() );
				}
			}
		}
	}
}
