package com.infoteria.asteria.sample.plugin;

import com.infoteria.asteria.flowbuilder2.component.Component;
import com.infoteria.asteria.flowbuilder2.component.ComponentOutputConnector;
import com.infoteria.asteria.flowbuilder2.event.BaseObjectUndoableEvent;
import com.infoteria.asteria.flowbuilder2.plugin.ComponentEditor;
import com.infoteria.asteria.flowbuilder2.plugin.SQLTool;
import com.infoteria.asteria.flowbuilder2.plugin.PluginUtil;
import com.infoteria.asteria.flowbuilder2.property.category.CategoryProperty;
import com.infoteria.asteria.flowbuilder2.resource.BuilderInfo;
import com.infoteria.asteria.flowbuilder2.sqlbuilder.NullTableProvider;
import com.infoteria.asteria.flowbuilder2.stream.field.FieldDefinition;
import com.infoteria.asteria.sqlbuilder.model.SQLBuilder;
import com.infoteria.asteria.sqlbuilder.model.SQLOption;
import com.infoteria.asteria.sqlbuilder.model.Table;
import com.infoteria.asteria.sqlbuilder.model.TableProvider;
import com.infoteria.asteria.sqlbuilder.ui.SQLBuilderDialog;
import com.infoteria.gui.property.Property;
import com.infoteria.gui.property.PropertyException;
import java.io.IOException;
import javax.swing.JOptionPane;

public class SQLBuilderSample extends ComponentEditor {
	
	private static final String BUILDER_PROP    = "SQLBuilder";
	private static final String PARAMETER_PROP  = "SQLParameter";
	private static final String CONNECTION_PROP = "Connection";
	private static final String SQL_PROP        = "SQL";
	
	protected void doAction(BaseObjectUndoableEvent e, boolean bEditable) {
		Component c = (Component)e.getBaseObject();
		
		Property sqlProp = c.getProperty(SQL_PROP);
		Property builderProp = c.getProperty(BUILDER_PROP);
		Property connectionProp = c.getProperty(CONNECTION_PROP);
		CategoryProperty parameterProp = (CategoryProperty)c.getAdditionalProperty(PARAMETER_PROP);
		
		if (sqlProp == null || builderProp == null || connectionProp == null || parameterProp == null)
			return;
		
		if (builderProp.getValue() == null && connectionProp.getValue() == null) {
			PluginUtil.showError("Connection not set");
			return;
		}
		
		//現在編集中のフローのContextを使用してSQLToolを作成します。
		SQLTool tool = PluginUtil.getSQLTool();
		
		//コネクションに対応するTableProviderを取得します。
		//コネクションがない場合はNullTableProvider(何も情報を持たないProvider)を使用します。
		//(コネクションが取得できない場合はエラーにしても構いません。)
		try {
			TableProvider provider = tool.getTableProvider(connectionProp.getValueAsString());
			if (provider == null)
				provider = new NullTableProvider();
			
			//SQLBuilderのモデルの取得
			//存在しない場合は作成し、存在する場合はcloneする
			//cloneするのはSQLBuilderでの操作がモデルにはリアルタイムで反映されるため
			//キャンセル時には変更前の状態に戻さなければならないため
			SQLBuilder builder = null;
			if (builderProp.getValue() == null)
				builder = new SQLBuilder(SQLTool.getDefaultSQLOption());
			else
				builder = (SQLBuilder)((SQLBuilder)builderProp.getValue()).clone();
			builder.getOption().setOracle(provider.isOracle());
			builder.setDefaultSchema(provider.getSchemaName());
			
			SQLBuilderDialog dlg = tool.createSQLBuilderDialog("SQLBuilder", provider, builder);
			try {
				//現在のSQL設定値をダイアログにセットします。
				//パラメータはSQLBuilderの持つ情報と常に同期しているのでセットする必要はありません。
				String sql = sqlProp.getValueAsString();
				if (sql != null)
					dlg.setSQL(sql);
				dlg.setVisible(true);
				//フローが編集可能でダイアログがOKボタンで終了した場合だけ処理を行う
				if (bEditable && dlg.isOK()) {
					//SQLとパラメータの取得
					String sql2 = dlg.getSQL();
					Table params = builder.getParams();
					
					e.addUndo(sqlProp.setValue(sql2));
					e.addUndo(builderProp.setValue(builder));
					e.addUndo(SQLTool.updateCategoryProperty(parameterProp, params));
					
					//出力フィールド定義の設定
					//フィールド定義はSQLBuilderと常に同期しているわけではないので確認が必要です。
					if (PluginUtil.showConfirm("フィールド定義を更新しますか？", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
						//Componentの出力コネクタからFieldDefinitionを取得します。
						FieldDefinition fd = ((ComponentOutputConnector)c.getDefaultOutputConnector()).getStreamDefinition().getFieldDefinition();
						e.addUndo(SQLTool.updateFieldDefinition(fd, sql2, builder.getSelect()));
					}
				}
			} finally {
				dlg.dispose();
			}
		} catch (PropertyException ex) {
			//not occur
			ex.printStackTrace();
		} catch (IOException ex) {
			PluginUtil.showError(ex.getMessage());
		}
	}
	
}
