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

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityView;

import com.teamcenter.rac.aif.AbstractAIFUIApplication;
import com.teamcenter.rac.aifrcp.AIFUtility;
import com.teamcenter.rac.cme.application.MFGLegacyApplication;
import com.teamcenter.rac.cme.framework.treetable.CMEBOMTreeTable;
import com.teamcenter.rac.cme.framework.views.primary.BOMPrimaryView;
import com.teamcenter.rac.kernel.TCComponentBOMLine;
import com.teamcenter.rac.kernel.TCComponentBOMWindow;
import com.teamcenter.rac.kernel.TCComponentItemType;
import com.teamcenter.rac.kernel.TCSession;
import com.teamcenter.rac.util.MessageBox;
import com.teamcenter.rac.util.PlatformHelper;
import com.teamcenter.rac.util.Registry;

import cn.net.connor.std.aifrcp.util.KUtil;
import cn.net.connor.std.fx.KFXPanel;
import cn.net.connor.std.fx.KFXPanelController;
import cn.net.connor.std.processedit.meopviewfx.bean.KTableRow;
import cn.net.connor.std.processedit.meopviewfx.bean.TextBean;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;

@SuppressWarnings("restriction")
public class MEOPPanelController extends KFXPanelController {

	public static final String PREF_BOM_TABLE = "Connor_AVIC_GXBZ_Bomline";
	public static final String PREF_PREFIX_BOM_TABLE_WITH_TYPE = "Connor_AVIC_GXBZ_";
	public static final String PREF_PREFIX_PROP_FLOW_WITH_TYPE = "Connor_AVIC_GXBZ_Property_";
	public static final String PREF_PREFIX_SEARCH_BY_SQL = "Connor_AVIC_GXBZ_SelectSql_";

	@FXML
	private TableView<KTableRow> table1;
	@FXML
	private TableView<KTableRow> table2;
	@FXML
	private FlowPane propPane;
	@FXML
	private AnchorPane cover;
	@FXML
	private Button b_AddRow;
	@FXML
	private Button b_DelRow;
	@FXML
	private Button b_MoveUp;
	@FXML
	private Button b_MoveDown;
	@FXML
	private Button b_Reorder;
	@FXML
	private VBox buttonBox;
	@FXML
	private TabPane textTab;
	@FXML
	private Button b_Symbol;
	@FXML
	private Button b_Search;
	private boolean busy = false;

	private TCSession session = (TCSession) AIFUtility.getCurrentApplication().getSession();
	private TableLoader table1Loader = new TableLoader(session);
	private TableLoader table2Loader;
	private PropFlowLoader propLoader = new PropFlowLoader(session);
	private static final Registry REG = Registry.getRegistry(MEOPPanelController.class);

	// private MEOPPanel panel;

	public Image folder = new Image(MEOPPanelController.class.getResourceAsStream("/icons/folder_24.png"), 18, 18, true, false);
	public Image text = new Image(MEOPPanelController.class.getResourceAsStream("/icons/text.png"), 18, 18, true, false);
	private TCComponentBOMLine targetLine;
	private CMEBOMTreeTable bomTreeTable;
	private MFGLegacyApplication bomApp;
	private BOMPrimaryView bomView;

	@Override
	public void initData(KFXPanel panel) throws Exception {
		// this.panel = (MEOPPanel) panel;
		// table1.getSelectionModel().setCellSelectionEnabled(true);
		// table2.getSelectionModel().setCellSelectionEnabled(true);
		b_AddRow.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/add_24px.png"), 19, 19, true, false)));
		b_DelRow.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/delete_24px.png"), 19, 19, true, false)));
		b_MoveUp.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/up_24px.png"), 19, 19, true, false)));
		b_MoveDown.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/down_24px.png"), 19, 19, true, false)));
		if(b_Reorder!=null)
			b_Reorder.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/sort-line-2.png"), 19, 19, true, false)));
		if(b_Symbol!=null)
			b_Symbol.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/T.png"), 19, 19, true, false)));
		if(b_Search!=null)
			b_Search.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/search-2.png"), 19, 19, true, false)));
		table1.setVisible(table1Loader.load(table1, PREF_BOM_TABLE));
		if (table1.isVisible()) {
			String colName = REG.getString("index.COL");
			TableColumn<KTableRow, String> c = new TableColumn<KTableRow, String>(colName);
			c.setCellFactory(col -> new TableCell<KTableRow, String>() {
				@Override
				public void updateIndex(int index) {
					super.updateIndex(index);
					if (isEmpty() || index < 0) {
						setText(null);
					} else {
						setText(Integer.toString(index + 1));
					}
				}
			});
			Platform.runLater(() -> {
				c.setEditable(false);
				c.setSortable(false);
				c.setPrefWidth(70);
				table1.getColumns().add(0, c);
			});
		}
		textTab.getTabs().clear();
		// load special text
		Map<String, TextBean> textMap = new TextTreeLoader(session).loadText();
		for (String sheetName : textMap.keySet()) {
			TextBean bean = textMap.get(sheetName);
			Tab tab = new Tab(sheetName);
			textTab.getTabs().add(tab);
			TreeView<TextBean> tree = new TreeView<TextBean>();
			TreeItem<TextBean> rootNode = new TreeItem<TextBean>(bean, new ImageView(folder));
			tree.setRoot(rootNode);
			tree.setShowRoot(false);
			rootNode.setExpanded(true);
			loadTree(rootNode, bean);
			tab.setContent(tree);
			tree.setOnMouseClicked(e -> {
				if (e.getButton() != MouseButton.PRIMARY || e.getClickCount() != 2) {
					return;
				}
				TreeItem<TextBean> treeItem = tree.getSelectionModel().getSelectedItem();
				if (treeItem.getChildren().size() > 0) {
					return;
				}
				String text = treeItem.getValue().getRealValue();
				System.out.println("Insert: " + text);
				long time = Math.max(table1Loader.focuseTime, table2Loader.focuseTime);
				time = Math.max(time, propLoader.focuseTime);
				if (propLoader.focuseTime == time) {
					propLoader.insertText(text);
				}
				if (table1Loader.focuseTime == time) {
					table1Loader.insertText(text);
				}
				if (table2Loader.focuseTime == time) {
					String parentText = treeItem.getParent() == null ? "" : treeItem.getParent().getValue().getRealValue();
					table2Loader.insertText(text, parentText);
				}
			});
		}
		table2.getSelectionModel().selectedItemProperty().addListener(e -> {
			try {
				int index = table2.getSelectionModel().getSelectedIndex();
				System.out.println("Select Table2: " + index);
				KTableRow row = table2.getSelectionModel().getSelectedItem();
				TCComponentBOMLine bomLine = row == null ? null : row.getBomLine();
				System.out.println(">> bomline: " + bomLine);
				if (bomLine == null) {
					bomLine = targetLine;
				}
				if (!bomLine.equals(table1Loader.targetLine)) {
					table1Loader.loadTCData(bomLine, true);
				}
			} catch (Exception e1) {
				e1.printStackTrace();
				MessageBox.post(e1);
			}
		});
	}

	private void initBomTreeTableInfo() throws Exception {
		this.bomTreeTable = null;
		this.bomApp = null;
		this.bomView = null;
		AbstractAIFUIApplication app = AIFUtility.getCurrentApplication();
		TCComponentBOMWindow bomWindow = targetLine.window();
		System.out.println(">> BomWindow: " + bomWindow);
		System.out.println(">> " + app.getClass());
		if (app instanceof MFGLegacyApplication) {
			this.bomApp = (MFGLegacyApplication) app;
			List<Object> viewParts = PlatformHelper.getAllViewParts();
			IWorkbenchWindow var1 = AIFUtility.getActiveDesktop().getDesktopWindow();
			IWorkbenchPage page = var1.getActivePage();
			for (Object viewPart : viewParts) {
				if (viewPart == null || !(viewPart instanceof CompatibilityView)) {
					continue;
				}
				IViewPart view = ((CompatibilityView) viewPart).getView();
				if (view == null || !(view instanceof BOMPrimaryView)) {
					continue;
				}

				BOMPrimaryView bomView = (BOMPrimaryView) view;
				CMEBOMTreeTable treeTable = bomView.getBOMTreeTable();
				if (treeTable == null) {
					continue;
				}
				boolean visible = page.isPartVisible(view);
				System.out.println(">> BOMPrimaryView: [" + visible + "]" + bomView);
				if (!visible) {
					continue;
				}
				if (treeTable.getBOMWindow() == bomWindow) {
					System.out.println(">>>>> find window");
					TCComponentBOMLine[] bomlines = treeTable.getSelectedBOMLines();
					System.out.println(">> Selected lines: " + Arrays.toString(bomlines));
					boolean findLine = false;
					int bomLineCnt = KUtil.getLen(bomlines);
					for (int i = 0; i < bomLineCnt; i++) {
						if (targetLine == bomlines[i]) {
							findLine = true;
							break;
						}
					}
					if (findLine) {
						System.out.println(">>>>> Find targetline");
						this.bomTreeTable = treeTable;
						this.bomView = bomView;
						// Display.getDefault().syncExec(()->{
						// view.setFocus();
						// });
						// treeTable.setRefreshingBOM();
						// ((MFGLegacyApplication) app).refreshBOM();
						// treeTable.refreshBOMLine(targetLine, true);
						return;
					}
				}
			}
		}

	}

	public void reloadDataButtonClick() {
		new Thread(() -> {
			session.setStatus("Reloading...");
			setProgressVisible(true);
			try {
				reloadData(null);
			} catch (Exception e) {
				e.printStackTrace();
				MessageBox.post(e);
			}
			setProgressVisible(false);
			System.out.println("Reload Complete");
		}).start();
	}

	public void saveButtonClick() {
		if (this.bomView != null) {
			Display.getDefault().syncExec(() -> {
				this.bomView.setFocus();
			});
		}
		new Thread(() -> {
			session.setStatus("Saving...");
			setProgressVisible(true);
			if (this.bomTreeTable != null) {
				try {
					this.bomTreeTable.setRefreshingBOM();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			try {
				saveData();
				reloadData(null);
			} catch (Exception e) {
				e.printStackTrace();
				MessageBox.post(e);
			}
			if (this.bomApp != null) {
				try {
					this.bomApp.refreshBOM();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			setProgressVisible(false);
			System.out.println("Save Complete");
		}).start();
	}

	public synchronized void reloadData(TCComponentBOMLine targetLine) throws Exception {
		if (targetLine == null) {
			targetLine = this.targetLine;
			// AIFComponentContext cc =
			// AIFUtility.getCurrentApplication().getTargetContext();
			// System.out.println("Select: "+cc);
			// if(cc!=null&&cc.getComponent()!=null&&(cc.getComponent() instanceof
			// TCComponentBOMLine)){
			// targetLine = (TCComponentBOMLine) cc.getComponent();
			// }
		}
		if (targetLine == null) {
			return;
		}
		this.targetLine = targetLine;
		System.out.println("Load Line: " + targetLine);
		initBomTreeTableInfo();
		TCComponentItemType itemType = targetLine == null ? null : targetLine.getItem().getTypeComponent();
		String prefName = itemType == null ? null : PREF_PREFIX_BOM_TABLE_WITH_TYPE + itemType.getTypeName();
		if (TableLoaderMEActivity.isActivityConfig(session, prefName)) {
			table2Loader = new TableLoaderMEActivity(session);
		} else {
			table2Loader = new TableLoader(session);
		}
		boolean table2Visible = table2Loader.load(table2, prefName);
		String prefName2 = itemType == null ? null : PREF_PREFIX_PROP_FLOW_WITH_TYPE + itemType.getTypeName();
		boolean propVisible = propLoader.load(propPane, prefName2, itemType);
		if (!Platform.isFxApplicationThread()) {
			Platform.runLater(() -> {
				table2.setVisible(table2Visible);
				buttonBox.setVisible(table2Visible);
				propPane.setVisible(propVisible);
				try {
					propLoader.loadTCData(this.targetLine);
					table1Loader.loadTCData(this.targetLine, true);
					table2Loader.loadTCData(this.targetLine, false);
				} catch (Exception e) {
					e.printStackTrace();
					MessageBox.post(e);
				}
			});
		} else {
			table2.setVisible(table2Visible);
			buttonBox.setVisible(table2Visible);
			propPane.setVisible(propVisible);
			propLoader.loadTCData(targetLine);
			table1Loader.loadTCData(targetLine, true);
			table2Loader.loadTCData(targetLine, false);
		}
	}

	public void saveData() throws Exception {
		if (targetLine == null) {
			return;
		}
		propLoader.saveTCData(targetLine);
		table1Loader.saveTCData();
		table2Loader.saveTCData();
		targetLine.refresh();
		// session.refresh();
		// AIFUtility.getCurrentApplication().refresh();
	}

	private void loadTree(TreeItem<TextBean> rootNode, TextBean bean) {
		int childCnt = bean.children.size();
		for (int i = 0; i < childCnt; i++) {
			TextBean childBean = bean.children.get(i);
			boolean isFolder = childBean.children.size() > 0;
			TreeItem<TextBean> cNode = isFolder ? new TreeItem<TextBean>(childBean, new ImageView(folder)) : new TreeItem<TextBean>(childBean, new ImageView(text));
			rootNode.getChildren().add(cNode);
			if (isFolder) {
				loadTree(cNode, childBean);
			}
		}
	}

	public void refreshUI(TCComponentBOMLine targetLine) throws Exception {
		if (busy) {
			System.out.println("Task Running. Skip load: " + targetLine);
			return;
		}
		setProgressVisible(true);
		try {
			reloadData(targetLine);
		} finally {
			setProgressVisible(false);
		}
		// this.targetLine = targetLine;
		// TCComponentItemType itemType = targetLine == null ? null :
		// targetLine.getItem().getTypeComponent();
		// String prefName = itemType == null ? null : PREF_PREFIX_BOM_TABLE_WITH_TYPE +
		// itemType.getTypeName();
		// boolean table2Visible = table2Loader.load(table2, prefName);
		// String prefName2 = itemType == null ? null : PREF_PREFIX_PROP_FLOW_WITH_TYPE
		// + itemType.getTypeName();
		// boolean propVisible = propLoader.load(propPane, prefName2, itemType);
		// Platform.runLater(() -> {
		// table2.setVisible(table2Visible);
		// buttonBox.setVisible(table2Visible);
		// propPane.setVisible(propVisible);
		// });
		// reloadData();
	}

	public void addRowButtonClicked() {
		table2Loader.addRow();
	}

	public void delRowButtonClicked() {
		table2Loader.removeRow();
	}

	public void moveUpButtonClicked() {
		table2Loader.moveUp();
	}

	public void moveDownButtonClicked() {
		table2Loader.moveDown();
	}

	public void reorderButtonClicked() {
		try {
			table2Loader.reorder();
		} catch (Exception e) {
			e.printStackTrace();
			MessageBox.post(e);
		}
	}

	public void symbolButtonClicked() {
		try {
			table2Loader.editSymbol();
		} catch (Exception e) {
			e.printStackTrace();
			MessageBox.post(e);
		}
	}

	public void searchButtonClicked() {
		try {
			TCComponentItemType itemType = targetLine == null ? null : targetLine.getItem().getTypeComponent();
			String prefName = itemType == null ? null : PREF_PREFIX_SEARCH_BY_SQL + itemType.getTypeName();
			table2Loader.doSearch(prefName);
		} catch (Exception e) {
			e.printStackTrace();
			MessageBox.post(e);
		}
	}

	public void setProgressVisible(boolean visible) {
		this.busy = visible;
		if (cover != null) {
			if (Platform.isFxApplicationThread()) {
				cover.setVisible(visible);
			} else {
				Platform.runLater(() -> {
					cover.setVisible(visible);
				});
			}
			try {
				Thread.sleep(10);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
