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

import java.util.Arrays;

import com.teamcenter.rac.cme.time.common.ActivityUtils;
import com.teamcenter.rac.kernel.TCComponent;
import com.teamcenter.rac.kernel.TCComponentBOMLine;
import com.teamcenter.rac.kernel.TCComponentCfgActivityLine;
import com.teamcenter.rac.kernel.TCComponentCfgAttachmentLineType;
import com.teamcenter.rac.kernel.TCComponentMEActivity;
import com.teamcenter.rac.kernel.TCComponentMEActivityType;
import com.teamcenter.rac.kernel.TCComponentType;
import com.teamcenter.rac.kernel.TCException;
import com.teamcenter.rac.kernel.TCPropertyDescriptor;
import com.teamcenter.rac.kernel.TCSession;

import cn.net.connor.std.aifrcp.util.KUtil;
import cn.net.connor.std.processedit.meopviewfx.bean.KTableRow;
import cn.net.connor.std.processedit.meopviewfx.bean.KTableRowMEActivity;
import cn.net.connor.std.processedit.meopviewfx.bean.PropConfig;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.control.TableView;

public class TableLoaderMEActivity extends TableLoader {

	protected TCComponentMEActivityType folderType;

	public TableLoaderMEActivity(TCSession session) {
		super(session);
	}

	public static boolean isActivityConfig(TCSession session, String prefName) {
		if (KUtil.isEmpty(prefName)) {
			return false;
		}
		try {
			String[] prefVals = KUtil.getPrefVals(session, prefName);
			int len = KUtil.getLen(prefVals);
			if (len <= 1) {
				return false;
			}
			String itemTypeName = prefVals[0];
			TCComponentType typeComp = session.getTypeComponent(itemTypeName);
			if (typeComp == null) {
				return false;
			}
			if (typeComp instanceof TCComponentMEActivityType) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public boolean load(TableView<KTableRow> table, String prefName) throws Exception {
		this.table = table;
		clearLocatorData();
		Platform.runLater(() -> {
			table.getColumns().clear();
			table.getItems().clear();
		});
		propConfigs.clear();
		sequenceConfigMap.clear();
		sequenceConfigMapReorder.clear();
		if (KUtil.isEmpty(prefName)) {
			return false;
		}
		System.out.println("Load table from pref: " + prefName);
		String[] prefVals = KUtil.getPrefVals(session, prefName);
		int len = KUtil.getLen(prefVals);
		if (len <= 1) {
			return false;
		}
		String itemTypeName = prefVals[0];
		System.out.println(">> Item Type: " + itemTypeName);
		TCComponentCfgAttachmentLineType cfglineType = null;
		folderType = null;
		cfglineType = (TCComponentCfgAttachmentLineType) session.getTypeComponent("CfgActivityLine");
		if (cfglineType == null) {
			throw new Exception("Type not found: CfgAttachmentLine");
		}
		folderType = (TCComponentMEActivityType) session.getTypeComponent(itemTypeName);
		if (folderType == null) {
			throw new Exception(String.format(REG.getString("typenotfound.ERROR1"), itemTypeName));
		}
		for (int i = 1; i < len; i++) {
			String propName = prefVals[i];
			System.out.println("Load Config: " + propName);
			if (KUtil.isEmpty(propName)) {
				continue;
			}
			if (propName.toLowerCase().startsWith("sequence_step=")) {
				String numStr = propName.substring("sequence_step=".length()).trim();
				if (!KUtil.isEmpty(numStr)) {
					try {
						this.defaultSequenceStep = Integer.parseInt(numStr);
						System.out.println("Default Sequence Step: " + this.defaultSequenceStep);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				continue;
			}
			String propLoc = null;
			String filterValue = null;
			int width = 0;
			int height = 0;
			int maxCharacter = 0;
			if ('-' == propName.charAt(0)) {
				width = -1;
				propName = propName.substring(1);
			} else {
				while (!KUtil.isEmpty(propName) && Character.isDigit(propName.charAt(0))) {
					width = width * 10 + (propName.charAt(0) - '0');
					propName = propName.substring(1);
				}
				if (propName.startsWith("x")) {
					propName = propName.substring(1);
					while (!KUtil.isEmpty(propName) && Character.isDigit(propName.charAt(0))) {
						height = height * 10 + (propName.charAt(0) - '0');
						propName = propName.substring(1);
					}
				}
				if (propName.startsWith("$")) {
					propName = propName.substring(1);
					while (!KUtil.isEmpty(propName) && Character.isDigit(propName.charAt(0))) {
						maxCharacter = maxCharacter * 10 + (propName.charAt(0) - '0');
						propName = propName.substring(1);
					}
				}
			}
			int ind = propName.indexOf('.');
			if (ind > 0) {
				propLoc = propName.substring(0, ind);
				propName = propName.substring(ind + 1);
			}
			ind = propName.indexOf('=');
			if (ind > 0) {
				filterValue = propName.substring(ind + 1);
				propName = propName.substring(0, ind);
			}
			// System.out.println(propName + "|" + filterValue);
			TCComponentType type = null;
			if (KUtil.isEmpty(propLoc)) {
				type = folderType;
				propLoc = KTableRow.ITEM;
			} else {
				switch (propLoc.toUpperCase()) {
				case KTableRow.BOMLINE:
					type = cfglineType;
					break;
				case KTableRow.ITEM:
					type = folderType;
					break;
				default:
					System.out.println(">> Prop location error: " + propLoc);
					break;
				}
			}
			if (type != null) {
				boolean isSeq = propName.startsWith("#");
				boolean reorder = false;
				if (isSeq) {
					propName = propName.substring(1);
				}
				reorder = propName.startsWith("#");
				if (reorder) {
					propName = propName.substring(1);
				}
				TCPropertyDescriptor propDesc = type.getPropDesc(propName);
				if (propDesc == null) {
					throw new Exception(String.format(REG.getString("propnotdefinedintype.ERROR2"), propName, type.getDisplayTypeName()));
				}
				PropConfig propConfig;
				this.propConfigs.add(propConfig = new PropConfig(propLoc, propDesc, filterValue, width, height, maxCharacter));
				if (reorder) {
					this.sequenceConfigMapReorder.put(propConfig, 0);
				} else if (isSeq) {
					this.sequenceConfigMap.put(propConfig, 0);
				}
			}
		}
		System.out.println("Load complete");
		int size = this.propConfigs.size();
		if (size == 0) {
			return false;
		}
		this.gdtPropNames = KUtil.getPrefVals(session, PREF_GDT_PROP);
		for (int i = 0; i < size; i++) {
			PropConfig config = propConfigs.get(i);
			addTableCol(table, config);
		}
		// table.setOnMouseClicked(e->{
		// if(e.getButton()!=MouseButton.SECONDARY || e.getClickCount()!=1) {
		// return;
		// }
		// KTableRow row = table.getSelectionModel().getSelectedItem();
		// if(row!=null) {
		// row.switchWebView();
		// table.refresh();
		// }
		// });
		return true;
	}

	public void loadTCData(TCComponentBOMLine targetLine, boolean useLatestRev) throws Exception {
		Platform.runLater(() -> {
			table.getItems().clear();
		});
		if (targetLine == null) {
			return;
		}
		int size = this.propConfigs.size();
		if (size == 0) {
			return;
		}
		removeRows.clear();
		this.targetLine = targetLine;
		this.targetLine.refresh();
		TCComponentCfgActivityLine actLine = (TCComponentCfgActivityLine) targetLine.getReferenceProperty("bl_me_activity_lines");
		System.out.println("Activity line: " + targetLine + " -> " + actLine);
		if (actLine == null) {
			return;
		}
		TCComponent[] cc = ActivityUtils.getSortedActivityChildren(actLine);
		System.out.println(">> " + Arrays.toString(cc));
		int len = KUtil.getLen(cc);
		for (int i = 0; i < len; i++) {
			TCComponentCfgActivityLine bomine = (TCComponentCfgActivityLine) cc[i];
			bomine.refresh();
			TCComponentMEActivity item = (TCComponentMEActivity) bomine.getUnderlyingComponent();
			if (this.folderType != null && !this.folderType.getName().equals(item.getType())) {
				continue;
			}
			KTableRowMEActivity row = new KTableRowMEActivity(bomine, item);
			boolean checkOK = true;
			for (int j = 0; j < size; j++) {
				PropConfig config = propConfigs.get(j);
				if (!row.parseConfig(config)) {
					checkOK = false;
					break;
				}
			}
			if (checkOK) {
				for (PropConfig sequenceConfig : this.sequenceConfigMap.keySet()) {
					int maxSeqNo = this.sequenceConfigMap.get(sequenceConfig);
					String seq2 = row.getTCValue(sequenceConfig.propLoc, sequenceConfig.propName);
					if (!KUtil.isEmpty(seq2)) {
						try {
							int seqNum = Integer.parseInt(seq2);
							if (seqNum > maxSeqNo) {
								maxSeqNo = seqNum;
								this.sequenceConfigMap.put(sequenceConfig, maxSeqNo);
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
				for (PropConfig sequenceConfig : this.sequenceConfigMapReorder.keySet()) {
					int maxSeqNo = this.sequenceConfigMapReorder.get(sequenceConfig);
					String seq2 = row.getTCValue(sequenceConfig.propLoc, sequenceConfig.propName);
					if (!KUtil.isEmpty(seq2)) {
						try {
							int seqNum = Integer.parseInt(seq2);
							if (seqNum > maxSeqNo) {
								maxSeqNo = seqNum;
								this.sequenceConfigMapReorder.put(sequenceConfig, maxSeqNo);
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
				Platform.runLater(() -> {
					table.getItems().add(row);
				});
			}
		}
		Platform.runLater(() -> {
			table.refresh();
		});
		System.out.println("Max Sequence: " + sequenceConfigMap);
		System.out.println("Max Sequence Reorder: " + sequenceConfigMapReorder);
	}

	public void saveTCData() throws Exception {
		System.out.println("Save: " + targetLine);
		if (targetLine == null) {
			return;
		}
		targetLine.refresh();
		TCComponentCfgActivityLine actLine = (TCComponentCfgActivityLine) targetLine.getReferenceProperty("bl_me_activity_lines");
		if (actLine != null) {
			actLine.refresh();
		}
		TCComponent alObject = actLine == null ? null : actLine.getReferenceProperty("al_object");
		System.out.println("Activity line: " + targetLine + " -> " + alObject);
		if (actLine == null) {
			return;
		}
		if (alObject == null) {
			throw new TCException(REG.getString("alobjectisnull.ERROR"));
		}
		while (removeRows.size() > 0) {
			removeRows.get(0).removeLine();
			removeRows.remove(0);
		}
		KTableRow[] rows = table.getItems().toArray(new KTableRow[] {});
		int len = KUtil.getLen(rows);
		TCComponentCfgActivityLine pline = null;
		for (int i = 0; i < len; i++) {
			KTableRowMEActivity row = (KTableRowMEActivity) rows[i];
			row.saveTCData(actLine, folderType);
			if (pline != null && row.actline != null) {
				ActivityUtils.moveActivityAfter(row.actline, pline);
			}
			pline = row.actline;
		}
	}

	public KTableRow getNewRow() {
		KTableRow row = new KTableRowMEActivity(null, null);
		for (PropConfig propConfig : propConfigs) {
			row.stringProps.put(propConfig, new SimpleStringProperty(""));
		}
		return row;
	}

}
