package com.fr.design.data.datapane.sqlpane;

import com.fr.base.FRContext;
import com.fr.data.core.DataCoreUtils;
import com.fr.data.core.db.TableProcedure;
import com.fr.design.actions.UpdateAction;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.design.utils.gui.GUICoreUtils;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.*;
import java.awt.event.ActionEvent;

/**
 * Created by IntelliJ IDEA.
 * Author : Richer
 * Version: 7.0.3
 * Date: 13-5-2
 * Time: 上午11:09
 */
public class SQLEditPane extends RSyntaxTextArea {
    public static final boolean REQUEST_DROPTARGET = true;
    public static final boolean UNREQUEST_DROPTARGET = false;

    public SQLEditPane() {
		this(REQUEST_DROPTARGET);
	}

    public SQLEditPane(boolean requestDroptarget) {
        super();

		setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL);

		setAnimateBracketMatching(true);
		setAntiAliasingEnabled(true);
		setAutoIndentEnabled(true);
		setCodeFoldingEnabled(true);
		setUseSelectedTextColor(true);
		setCloseCurlyBraces(true);
		setBracketMatchingEnabled(true);
		setAntiAliasingEnabled(true);
		setCloseMarkupTags(true);
		setLineWrap(true);
        if (requestDroptarget) {
            new SQLPaneDropTarget(this);
        }

    }


	private static class SQLPaneDropTarget extends DropTargetAdapter {
		private TableProcedure sqlTable;

		public SQLPaneDropTarget(SQLEditPane sqlTextPane) {
			new DropTarget(sqlTextPane, this);
		}

		public void dragEnter(DropTargetDragEvent dtde) {
			dtde.acceptDrag(dtde.getDropAction());
		}

		public void dragOver(DropTargetDragEvent dtde) {
			dtde.acceptDrag(dtde.getDropAction());
		}

		public void drop(DropTargetDropEvent dtde) {
			Point p = dtde.getLocation();
			DropTargetContext dtc = dtde.getDropTargetContext();
			SQLEditPane jTextPane = (SQLEditPane) dtc.getComponent();

			try {
				Transferable tr = dtde.getTransferable();
				DataFlavor[] flavors = tr.getTransferDataFlavors();
				for (int i = 0; i < flavors.length; i++) {
					if (!tr.isDataFlavorSupported(flavors[i])) {
						continue;
					}
					dtde.acceptDrop(dtde.getDropAction());
					Object userObj = tr.getTransferData(flavors[i]);

					if (userObj instanceof TableProcedure) {
						this.sqlTable = (TableProcedure) userObj;

						JPopupMenu popupMenu = new JPopupMenu();
						popupMenu.add(new NameAction(jTextPane, sqlTable).createMenuItem());
						if (ComparatorUtils.equals(sqlTable.getType(), TableProcedure.PROCEDURE)) {
							popupMenu.add(new CallAction(jTextPane, sqlTable).createMenuItem());
						} else {
							popupMenu.add(new SelectAction(jTextPane, sqlTable).createMenuItem());
						}

						GUICoreUtils.showPopupMenu(popupMenu, jTextPane,
								(int) p.getX() + 1, (int) p.getY() + 1);
					}

					dtde.dropComplete(true);
				}

				dtde.rejectDrop();
			} catch (Exception e) {
				dtde.rejectDrop();
			}
		}

		class NameAction extends UpdateAction {
			private SQLEditPane sqlTextPane;
			private TableProcedure sqlTable;

			public NameAction(SQLEditPane sqlTextPane, TableProcedure sqlTable) {
				this.sqlTextPane = sqlTextPane;
				this.sqlTable = sqlTable;

				this.setName(Inter.getLocText("Name"));
				this.setMnemonic('N');
				this.setSmallIcon(null);
			}

			public void actionPerformed(ActionEvent evt) {
				if (sqlTable != null) {
					insertStringTo(sqlTextPane, sqlTable.toString());
				}

			}
		}

		class SelectAction extends UpdateAction {
			private SQLEditPane sqlTextPane;
			private TableProcedure sqlTable;

			public SelectAction(SQLEditPane sqlTextPane, TableProcedure sqlTable) {
				this.sqlTextPane = sqlTextPane;
				this.sqlTable = sqlTable;

				this.setName("SELECT *");
				this.setMnemonic('s');
				this.setSmallIcon(null);
			}

			public void actionPerformed(ActionEvent evt) {
				//daniel: 添加参数
				insertStringTo(sqlTextPane, DataCoreUtils.createSelectSQL(sqlTable.getSchema(), sqlTable.getName(), sqlTable.getDialect()));
			}
		}

		class CallAction extends UpdateAction {
			private SQLEditPane sqlTextPane;
			private TableProcedure sqlTable;

			public CallAction(SQLEditPane sqlTextPane, TableProcedure sqlTable) {
				this.sqlTextPane = sqlTextPane;
				this.sqlTable = sqlTable;

				this.setName("CALL PROCEDURE ");
				this.setMnemonic('s');
				this.setSmallIcon(null);
			}

			public void actionPerformed(ActionEvent evt) {
				StringBuffer sBuf = new StringBuffer();
				sBuf.append("{call ");
				if (sqlTable != null) {
					sBuf.append(sqlTable.toString()).append("()");
				}
				sBuf.append('}');

				insertStringTo(sqlTextPane, sBuf.toString());
			}
		}

		private void insertStringTo(SQLEditPane sqlTextPane, String str) {
			Document document = sqlTextPane.getDocument();
			try {
				document.insertString(sqlTextPane.getCaretPosition(), str, null);
			} catch (BadLocationException badLocationException) {
                FRContext.getLogger().error(badLocationException.getMessage(), badLocationException);
			}

			sqlTextPane.requestFocus();
		}
	}
}