package asandatabasebrowser.action;

import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JOptionPane;

import net.sourceforge.swingx.jspread.JSpread;

import asandatabasebrowser.AsanDatabaseBrowser;
import asandatabasebrowser.model.ColumnInfo;
import asandatabasebrowser.model.DbException;
import asandatabasebrowser.model.TableInfo;
import asandatabasebrowser.model.VvDatabase;
import asandatabasebrowser.view.DbResultSetView;
import asandatabasebrowser.view.DbTableView;


public class CreateUpdateAction extends AbstractAction {
	final AsanDatabaseBrowser tools;
	final VvDatabase db;
	final JComponent view;
	
	public CreateUpdateAction(AsanDatabaseBrowser tools, VvDatabase db, JComponent view) {
		super("選択されたレコードのUPDATE文をクリップボードに作成");
		putValue(SHORT_DESCRIPTION,	"選択されたレコードのUPDATE文をクリップボードに作成します");
		putValue(LONG_DESCRIPTION, "選択されたレコードのUPDATE文をクリップボードに作成します");
		this.tools = tools;
		this.db = db;
		this.view = view;
	}
	
	/**
	 * 最初はStringで実装していたけれど、6000件を超えると時間がかかりすぎたので、StringBufferにした。
	 * この修正で１，２秒で終わるようになった。
	 */
	public void actionPerformed(ActionEvent ev) {
		//System.out.println(ev);
		try {
			// 選択されたすべてのrowに対して、insert文を作る。
			StringBuffer sb = new StringBuffer();
			sb.append("-- 間違っているかもしれないので、あまり信用しないように。\n");
			if (view instanceof DbResultSetView) {
				DbResultSetView view2 = (DbResultSetView) view;
				int[] rows = view2.getSelectedRows();
				TableInfo info = (TableInfo) view2.data.tableInfo;
				for (int i=0; i<rows.length; i++) {
					System.out.println(rows[i]);
					String sql = createUpdate(info, view2.data.getRecord(rows[i]));
					sb.append(sql).append("\n");
				}
			} else {
				DbTableView view2 = (DbTableView) view;
				TableInfo info = (TableInfo) view2.data.tableInfo;
				boolean[] sel = view2.getSheet().getSelectionArray(JSpread.ROW);
				for (int i=0; i<sel.length; i++) {
					if (sel[i]) {
						String sql = createUpdate(info, view2.data.getRecord(i));
						sb.append(sql).append("\n");
					}
				}
//				int[] rows = view2.getSelectedRecordIndex();
//				for (int i=0; i<rows.length; i++) {
//					String sql = createUpdate(info, view2.data.getRecord(rows[i]));
//					sb.append(sql).append("\n");
//				}
			}
			
			// クリップボードにコピー
			StringSelection ss = new StringSelection(sb.toString());
	        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,ss);
			
		} catch (DbException e) {
			tools.showMessage(view, "UPDATE文の作成に失敗しました。", e, JOptionPane.ERROR_MESSAGE);
		}
	}

	String createUpdate(TableInfo info, Object[] data) throws DbException {
		StringBuffer sb = new StringBuffer();
		sb.append("update ");
		sb.append(info.getSqlTableName());
		sb.append(" set \n    ");
		for (int i=0; i<info.getColumnCount(); i++) {
			if (i != 0) {
				sb.append("\n    ,");
			}
			ColumnInfo col = info.getColumnInfo(i);
			String sqlvalue = db.getValueStr(col, data[i]);
			sb.append(col.columnName+"="+sqlvalue);
		}
		sb.append("\nwhere ");
		// PKがあるときは、PKを条件にする。
		if (info.pkList != null && info.pkList.size() > 0) {
			for (int i=0; i<info.pkList.size(); i++) {
				if (i != 0) {
					sb.append("\n    and ");
				}
				String pk = (String) info.pkList.get(i);
				int index = info.getColumnIndexByName(pk);
				assert index != -1: index;
				ColumnInfo col = info.getColumnInfo(index);
				if (data[index] != null) {
					String sqlvalue = db.getValueStr(col, data[index]);
					sb.append(col.columnName+"="+sqlvalue);
				} else {
					sb.append(col.columnName+" is null");
				}
			}
		} else {
			// PKがないときは、すべての値をキーにする
			for (int i=0; i<info.getColumnCount(); i++) {
				if (i != 0) {
					sb.append("\n    and ");
				}
				ColumnInfo col = info.getColumnInfo(i);
				if (data[i] != null) {
					String sqlvalue = db.getValueStr(col, data[i]);
					sb.append(col.columnName+"="+sqlvalue);
				} else {
					sb.append(col.columnName+" is null");
				}
			}
		}
		sb.append(";");
		System.out.println(sb.toString());
		return sb.toString();
	}
}

