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

import com.teamcenter.rac.stylesheet.gdt.GenerateGDTHTML;
import com.teamcenter.rac.util.Registry;
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.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.concurrent.Worker.State;
import javafx.event.Event;
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.input.MouseButton;
import javafx.scene.layout.Region;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.web.WebEngine;
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 KFXEditableStringAreaHtmlTableCellBackup20220409<T, E> extends TableCell<T, String> {
	protected WebView webView;
	protected PropConfig config;
	protected TextArea textArea;
	private static final Registry REG = Registry.getRegistry(KFXEditableStringAreaHtmlTableCellBackup20220409.class);
	private static double ZOOM = 1;
	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 KFXEditableStringAreaHtmlTableCellBackup20220409(PropConfig config, KFXTextLocator textLocator) {
		super();
		this.config = config;
		this.textLocator = textLocator;
	}

	@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 boolean showWebView() {
		Object obj = super.getTableRow().getItem();
		boolean showWebView = true;
		if (obj != null && (obj instanceof KTableRow)) {
			showWebView = ((KTableRow) obj).showWebView();
		}
		return showWebView;
	}

	@Override
	public void cancelEdit() {
		super.cancelEdit();
		// setText((String) getItem());
		// setGraphic(null);
		if (showWebView()) {
			setGraphic(webView);
		} 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");
		}
		boolean showWebView = showWebView();
		if (empty) {
			setText(null);
			setGraphic(null);
		} else if (showWebView) {
			String newValue = item;
			String html = KUtil.isEmpty(newValue) || newValue.startsWith("<html>") ? newValue : GenerateGDTHTML.generatePage(newValue);
			createWebView(html);
			// 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());
				}
			});

			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(KFXEditableStringAreaHtmlTableCellBackup20220409.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 synchronized void createWebView(String value) {
		if(webView==null) {
			webView = new WebView();
			webView.setCache(false);
			if (ZOOM != 1) {
				webView.setZoom(ZOOM);
			}
			webView.setPrefHeight(120 * ZOOM);
//			webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
//				@Override
//				public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
//					if (newValue != State.SUCCEEDED) {
//						// System.out.println("Load Failed: "+newValue);
//						webView.setPrefHeight(Region.USE_COMPUTED_SIZE);
//						KFXEditableStringAreaHtmlTableCell.this.setPrefHeight(Region.USE_COMPUTED_SIZE);
//						return;
//					}
//					try {
//						Object res = webView.getEngine().executeScript(
//								"var body = document.body, html = document.documentElement; Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );");
//						double height = Integer.parseInt(res.toString()) * ZOOM + 20;
//						webView.setPrefHeight(height);
//						KFXEditableStringAreaHtmlTableCell.this.setPrefHeight(height);
//						webView.getEngine().reload();
//					} catch (Exception e) {
//						e.printStackTrace();
//					}
//				
//				}
//			});
		}
		WebEngine engine = webView.getEngine();
		//webView.setPrefHeight(Region.USE_COMPUTED_SIZE);
		// KFXEditableStringAreaHtmlTableCell.this.setPrefHeight(Region.USE_COMPUTED_SIZE);
		setGraphic(webView);
		engine.loadContent(value);
		engine.reload();
//		Platform.runLater(()->{
//			engine.loadContent(value);
//		});
//		engine.documentProperty().addListener((obj, prev, newv) -> {
//			Double height = 20.0;
//			if(!KUtil.isEmpty(value)) {
//				String heightText = engine.executeScript("var body = document.body," + "html = document.documentElement;" + "Math.max( body.scrollHeight , body.offsetHeight, "
//						+ "html.clientHeight, html.scrollHeight , html.offsetHeight );").toString();
//				height = Double.parseDouble(heightText.replace("px", "")) * ZOOM + 10;
//			}
//			webView.setPrefHeight(height);
//			this.setPrefHeight(height);
//		});
		webView.setOnScroll(e -> {
			Event.fireEvent(KFXEditableStringAreaHtmlTableCellBackup20220409.this, e);
		});
		if (isEditable()) {
			webView.setOnMouseClicked(e -> {
				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);
			});
		}
	}

	protected void createWebViewBackup() {
		webView = new WebView();
		webView.setPrefHeight(Region.USE_COMPUTED_SIZE);
		if (ZOOM != 1) {
			webView.setZoom(ZOOM);
		}
		webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
			@Override
			public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
				if (newValue != State.SUCCEEDED) {
					return;
				}
				try {
					Object res = webView.getEngine().executeScript(
							"var body = document.body, html = document.documentElement; Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );");
					// System.out.println("Height: " + res);
					int height = Integer.parseInt(res.toString());
					// int width = Integer.parseInt(webView.getEngine().executeScript("var body =
					// document.body, html = document.documentElement; Math.max( body.scrollWidth,
					// body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth
					// );").toString());
					webView.setPrefHeight(height * ZOOM);
					KFXEditableStringAreaHtmlTableCellBackup20220409.this.setPrefHeight(height * ZOOM + 20);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		if (isEditable()) {
			webView.setOnScroll(e -> {
				Event.fireEvent(getTableColumn(), e);
			});
			webView.setOnMouseClicked(e -> {
				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);
			});
			// webView.setOnMouseClicked(e -> {
			// if (e.getButton() != MouseButton.PRIMARY || e.getClickCount() != 2) {
			// if (e.getButton() == MouseButton.SECONDARY && e.getClickCount() == 1) {
			// Object obj = super.getTableRow().getItem();
			// if (obj != null && (obj instanceof KTableRow)) {
			// Event.fireEvent(getTableColumn(), e);
			// }
			// }
			// return;
			// }
			// TableRow<?> row = getTableRow();
			// KTableRow bean = (KTableRow) getTableView().getItems().get(row.getIndex());
			// String oldValue = bean.stringProps.get(config).getValueSafe();
			// System.out.println("Modify [" + row + "]: " + oldValue);
			// Display localDisplay = Display.getCurrent();
			// if (localDisplay == null) {
			// localDisplay = Display.getDefault();
			// }
			// GdtEditor editor = new GdtEditor(new JTextArea(oldValue));
			// editor.setValue(oldValue);
			// localDisplay.asyncExec(new Runnable() {
			// public void run() {
			// Shell localShell = UIUtilities.getCurrentModalShell();
			// GdtDialog gdtDialog = new GdtDialog(localShell, null, editor, true) {
			// public boolean close() {
			// try {
			// String newValue = editor.getValue();
			// System.out.println("New Value: " + newValue);
			// bean.stringProps.get(config).setValue(newValue);
			//
			// } catch (Exception e) {
			// e.printStackTrace();
			// }
			// return super.close();
			// }
			// };
			// editor.setGdtDialog(gdtDialog);
			// gdtDialog.open();
			// }
			// });
			// });
		}
		// webView.prefWidthProperty().bind(getTableColumn().widthProperty().subtract(20));
	}

	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());
		}
	}

}
