package cn.net.connor.std.processedit.meopviewfx.ui;

import com.teamcenter.rac.treetable.SwingTextContextActivator;
import com.teamcenter.rac.util.Utilities;

import cn.net.connor.std.aifrcp.util.KUtil;
import cn.net.connor.std.fx.KFXTextLocator;
import cn.net.connor.std.gdtex.KGenerateGDTHTML;
import cn.net.connor.std.processedit.meopviewfx.bean.KTableRow;
import cn.net.connor.std.processedit.meopviewfx.bean.PropConfig;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.Event;
import javafx.geometry.Bounds;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.input.KeyCode;
import javafx.scene.text.Text;
import javafx.scene.web.WebView;

/**
 * select color:
 * 
 * .table-row-cell .ktext { -fx-fill: black; }
 * 
 * .table-row-cell:selected .ktext { -fx-fill: white; }
 * 
 * .table-cell .ktext { -fx-fill: black; }
 * 
 * .table-cell:selected .ktext { -fx-fill: white; }
 * 
 * @author Administrator
 *
 * @param <T>
 * @param <E>
 */

public class KFXEditableStringAreaHtmlTableCell<T, E> extends TableCell<T, String> {

	protected PropConfig config;
	protected TextArea textArea;

	// private static final Registry REG =
	// Registry.getRegistry(KFXEditableStringAreaHtmlTableCell.class);
	// private static int FONTSIZE = -1;
	// static {
	// try {
	// // String zoomStr = REG.getString("zoom");
	// // if (!KUtil.isEmpty(zoomStr)) {
	// // double d = Double.parseDouble(zoomStr);
	// // System.out.println("Zoom: " + d);
	// // ZOOM = d;
	// // }
	// // FONTSIZE = REG.getInt("fontsize", -1);
	// } catch (Exception e) {
	// }
	// if (ZOOM < 0) {
	// ZOOM = 1;
	// }
	// }
	protected ChangeListener<? super Boolean> changeListener = (obs, ov, nv) -> {
		if (!nv) {
			commitEdit(textArea.getText());
		}
	};
	private Text text;
	private KFXTextLocator textLocator;

	public KFXEditableStringAreaHtmlTableCell(PropConfig config, KFXTextLocator textLocator) {
		super();
		this.config = config;
		this.textLocator = textLocator;
		// this.localToSceneTransformProperty().addListener((obs, oldIndex, newIndex) ->
		// {
		// if (getGraphic() == null || oldIndex==newIndex) {
		// return;
		// }
		// if(!(getGraphic() instanceof WebView)) {
		// return;
		// }
		// });

	}

	@Override
	public void startEdit() {
		if (editableProperty().get()) {
			if (!isEmpty()) {
				super.startEdit();
				createTextField();
				setText(null);
				setGraphic(textArea);
				textArea.requestFocus();
			}
		}
	}

	public void startEdit(int temp) {
		if (isEditing()) {
			System.out.println("=====>" + temp);
			textArea.positionCaret(temp);
		}
	}

	public KTableRow showWebView() {
		Object obj = null;
		try {
			obj = super.getTableRow().getItem();
		} catch (Exception e1) {
		}
		if (obj != null && (obj instanceof KTableRow)) {
			WebView webView = ((KTableRow) obj).checkWebView();
			if (webView != null) {
				webView.setOnScroll(e -> {
					Event.fireEvent(KFXEditableStringAreaHtmlTableCell.this, e);
				});
				// webView.setOnMouseClicked(null);
				// if (isEditable()) {
				// webView.setOnMouseClicked(e -> {
				// System.out.println("?????????/");
				// TableView<T> table = getTableView();
				// if (table == null) {
				// return;
				// }
				// TableRow<?> row = getTableRow();
				// int rowNum = row.getIndex();
				// if (rowNum < 0) {
				// return;
				// }
				// TableColumn<T, String> col = getTableColumn();
				// if (e.getButton() != MouseButton.PRIMARY || e.getClickCount() != 2) {
				// table.getSelectionModel().select(rowNum, col);
				// return;
				// }
				// KTableRow bean = (KTableRow) table.getItems().get(rowNum);
				// bean.showWebView(false);
				// updateItem(getItem(), isEmpty());
				// table.layout();
				// table.edit(rowNum, col);
				// });
				// }
				return ((KTableRow) obj);
			}
		}
		return null;
	}

	@Override
	public void cancelEdit() {
		super.cancelEdit();
		// setText((String) getItem());
		// setGraphic(null);
		KTableRow webView = showWebView();
		if (webView != null) {
			setGraphic(webView.getWebView());
		} else {
			setGraphic(text);
		}
	}

	@Override
	public void updateItem(String item, boolean empty) {
		super.updateItem(item, empty);
		// if (webView == null) {
		// createWebView();
		// }
		if (text == null) {
			text = new Text();
			text.wrappingWidthProperty().bind(getTableColumn().widthProperty().subtract(20));
			text.textProperty().bind(itemProperty());
			text.getStyleClass().add("ktext");
			text.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
				@Override
				public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
					KTableRow webView = showWebView();
					if (webView == null) {
						return;
					}
					double height = text.getLayoutBounds().getHeight() + 30; // +20 is for paddings
					webView.getWebView().setPrefHeight(height);
				}
			});
		}
		KTableRow webView = showWebView();
		if (empty) {
			setText(null);
			setGraphic(null);
		} else if (webView != null) {
			String newValue = item;
			String html = KUtil.isEmpty(newValue) || newValue.startsWith("<html>") ? newValue : KGenerateGDTHTML.generatePage(newValue);
			// createWebView(html);
			webView.loadContent(html);
			setGraphic(webView.getWebView());
			double height = text.getLayoutBounds().getHeight() + 30; // +20 is for paddings
			// System.out.println("Set Height [" + webView.getTCComponent(KTableRow.BOMLINE)
			// + "]: " + height);
			webView.getWebView().setPrefHeight(height);
			// webView.setPrefHeight(Region.USE_COMPUTED_SIZE);
			// Platform.runLater(() -> {
			// try {
			// // System.out.println("Load Html: " + newValue);
			// // System.out.println(">> " + html);
			// String html = newValue == null || newValue.startsWith("<html>") ? newValue :
			// GenerateGDTHTML.generatePage(newValue);
			// webView.getEngine().loadContent(html);
			// } catch (Exception e) {
			// e.printStackTrace();
			// }
			// });
			// setGraphic(webView);
		} else {
			if (isEditing()) {
				if (textArea != null) {
					textArea.setText(getString());
					// textArea.selectAll();
				}
				setText(null);
				setGraphic(textArea);
			} else {
				setGraphic(text);
				// setText(getString());
				// setGraphic(null);
			}
		}
	}

	protected void createTextField() {
		if (textArea == null) {
			textArea = new TextArea();
			textArea.setWrapText(true);
			// if (FONTSIZE > 0) {
			// try {
			// textArea.setFont(Font.font(FONTSIZE));
			// } catch (Exception e) {
			// e.printStackTrace();
			// }
			// }
			textArea.setOnKeyPressed((ke) -> {
				if (ke.getCode().equals(KeyCode.ESCAPE)) {
					textArea.focusedProperty().removeListener(changeListener);
					cancelEdit();
				}
				if (ke.getCode().equals(KeyCode.TAB)) {
					commitEdit(textArea.getText());
				}
			});
			textArea.focusedProperty().addListener(new ChangeListener<Boolean>() {
				@Override
				public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
					if (arg2) {
						SwingTextContextActivator.instance().activateContext();
					} else {
						SwingTextContextActivator.instance().deactivateContext();
					}
				}
			});
			if (textLocator != null) {
				textArea.focusedProperty().addListener(new ChangeListener<Boolean>() {
					@Override
					public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
						if (newValue) {
							System.out.println("focus get:" + getTableColumn().getText() + ":" + getTableRow().getIndex());
							textLocator.updateControl(KFXEditableStringAreaHtmlTableCell.this);
						} else {
							System.out.println("focus lost: " + getTableColumn().getText() + ":" + getTableRow().getIndex());
						}
					}
				});
				textArea.caretPositionProperty().addListener(new ChangeListener<Number>() {
					@Override
					public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
						if (textArea.isFocused()) {
							System.out.println("caret: " + oldValue + " -> " + newValue);
							Utilities.setPrivateField(textLocator, "currentCaret", newValue.intValue());
							// textLocator.currentCaret = newValue.intValue();
						}
					}
				});
			}
		}
		textArea.setText(getString());
		textArea.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
		textArea.setPrefHeight(this.getHeight());
		textArea.focusedProperty().addListener(changeListener);
		// textArea.setOnAction(evt -> commitEdit(textField.getText()));
	}

	protected String getString() {
		return getItem() == null ? "" : getItem().toString();
	}

	@Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void commitEdit(String item) {
		if (isEditing()) {
			super.commitEdit(item);
		} else {
			final TableView table = getTableView();
			if (table != null) {
				TablePosition position = new TablePosition(getTableView(), getTableRow().getIndex(), getTableColumn());
				CellEditEvent editEvent = new CellEditEvent(table, position, TableColumn.editCommitEvent(), item);
				Event.fireEvent(getTableColumn(), editEvent);
			}
			updateItem(item, false);
			if (table != null) {
				table.edit(-1, null);
			}
			// super.commitEdit(item); // 20201217 bug fix
		}
		TableRow<?> row = getTableRow();
		if (row != null && row.getIndex() >= 0) {
			KTableRow bean = (KTableRow) getTableView().getItems().get(row.getIndex());
			bean.showWebView(true);
			updateItem(item, isEmpty());
		}
	}

}
