package cn.net.connor.std.processedit.gygxsqbm;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.Window;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Vector;

import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JTable;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;

import com.teamcenter.rac.aif.AbstractAIFDialog;
import com.teamcenter.rac.aif.kernel.AIFComponentContext;
import com.teamcenter.rac.aif.kernel.InterfaceAIFComponent;
import com.teamcenter.rac.commands.open.OpenFormDialog;
import com.teamcenter.rac.kernel.ListOfValuesInfo;
import com.teamcenter.rac.kernel.TCComponent;
import com.teamcenter.rac.kernel.TCComponentBOMLine;
import com.teamcenter.rac.kernel.TCComponentBOMWindow;
import com.teamcenter.rac.kernel.TCComponentBOMWindowType;
import com.teamcenter.rac.kernel.TCComponentContextList;
import com.teamcenter.rac.kernel.TCComponentDataset;
import com.teamcenter.rac.kernel.TCComponentDatasetType;
import com.teamcenter.rac.kernel.TCComponentForm;
import com.teamcenter.rac.kernel.TCComponentItemRevision;
import com.teamcenter.rac.kernel.TCComponentListOfValues;
import com.teamcenter.rac.kernel.TCComponentListOfValuesType;
import com.teamcenter.rac.kernel.TCComponentPseudoFolder;
import com.teamcenter.rac.kernel.TCComponentQuery;
import com.teamcenter.rac.kernel.TCComponentQueryType;
import com.teamcenter.rac.kernel.TCException;
import com.teamcenter.rac.kernel.TCQueryClause;
import com.teamcenter.rac.kernel.TCSession;
import com.teamcenter.rac.util.MessageBox;

public class TCUtil {
	public static final int MINWIDTH = 1280;
	public static final int MINHEIGHT = 768;
	
	public static void fitToScreen(AbstractAIFDialog abstractAIFDialog) {
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		double screenWidth = screenSize.getWidth();
		double screenHeight = screenSize.getHeight();
		Dimension dialogSize = abstractAIFDialog.getSize();
		if (screenWidth < MINWIDTH && dialogSize.getWidth() > screenWidth) {
			abstractAIFDialog.setSize(new Dimension((int) Math.floor(screenWidth - 20), (int) Math.floor(dialogSize.getHeight())));
			abstractAIFDialog.setLocation(10, (int) Math.floor(abstractAIFDialog.getLocation().getY()));
		}
		if (screenHeight < MINHEIGHT && dialogSize.getHeight() > screenHeight) {
			abstractAIFDialog.setSize(new Dimension((int) Math.floor(dialogSize.getWidth()), (int) Math.floor(screenHeight - 20)));
			abstractAIFDialog.setLocation((int) Math.floor(abstractAIFDialog.getLocation().getX()), 10);
		}
		/*
		 * if((screenWidth<MINWIDTH||screenHeight<MINHEIGHT)&&(dialogSize.getWidth()>
		 * MINWIDTH||dialogSize.getHeight()>MINHEIGHT)) { abstractAIFDialog.setSize(new
		 * Dimension((int)Math.floor(screenWidth-20),(int)Math.floor(screenHeight-20)));
		 * abstractAIFDialog.setLocation(10, 10); }
		 */
	}

	public static void fitToScreen(OpenFormDialog openFormDialog) {
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		double screenWidth = screenSize.getWidth();
		double screenHeight = screenSize.getHeight();
		Dimension dialogSize = openFormDialog.getSize();
		if (screenWidth < MINWIDTH && dialogSize.getWidth() > screenWidth) {
			openFormDialog.setSize(new Dimension((int) Math.floor(screenWidth - 20), (int) Math.floor(dialogSize.getHeight())));
			openFormDialog.setLocation(10, (int) Math.floor(openFormDialog.getLocation().getY()));
		}
		if (screenHeight < MINHEIGHT && dialogSize.getHeight() > screenHeight) {
			openFormDialog.setSize(new Dimension((int) Math.floor(dialogSize.getWidth()), (int) Math.floor(screenHeight - 20)));
			openFormDialog.setLocation((int) Math.floor(openFormDialog.getLocation().getX()), 10);
		}
		/*
		 * if((screenWidth<MINWIDTH||screenHeight<MINHEIGHT)&&(dialogSize.getWidth()>
		 * MINWIDTH||dialogSize.getHeight()>MINHEIGHT)) { openFormDialog.setSize(new
		 * Dimension((int)Math.floor(screenWidth-20),(int)Math.floor(screenHeight-20)));
		 * openFormDialog.setLocation(10, 10); }
		 */
	}

	public static TCComponentBOMWindow getWindow(TCSession session) throws Exception{
		TCComponentBOMWindow window = null;
		TCComponentBOMWindowType bomWinType = (TCComponentBOMWindowType) session.getTypeComponent("BOMWindow");
		window = bomWinType.create(null);
		return window;
	}

	@SuppressWarnings("deprecation")
	public static TCComponentBOMLine getBOMLine(TCSession session,TCComponentBOMWindow window, TCComponentItemRevision revision) 
			throws Exception {
		window.lock();
		TCComponentBOMLine bomLine = window.setWindowTopLine(null, revision, null, null);
		window.save();
		window.unlock();
		return bomLine;
	}
	public static TCComponentPseudoFolder getPseudoFolder(TCComponent parent, String relation) 
			throws Exception {
		TCComponentPseudoFolder pseudoFolder = null;
		AIFComponentContext[] comps = parent.getChildren();
		if (comps != null && comps.length > 0 && comps[0] != null) {
			for (int i = 0; i < comps.length; i++) {
				TCComponent comp = (TCComponent) comps[i].getComponent();
				if (comp instanceof TCComponentPseudoFolder) {
					if (comp.isTypeOf("PseudoFolder")) {
//						System.out.println("PseudoFolder type:" + comp.getDefaultPasteRelation());
						if (comp.getDefaultPasteRelation().equalsIgnoreCase(relation)) {
							pseudoFolder = (TCComponentPseudoFolder) comp;
							break;
						}
					}
				}
			}
		}
		return pseudoFolder;
	}
	public static TCComponentForm getItemRevisionMasterForm(TCComponentItemRevision revision) throws Exception {
		if (revision != null) {
			AIFComponentContext[] contexts = revision.getChildren("IMAN_master_form_rev");
			if (contexts != null && contexts.length > 0) {
				InterfaceAIFComponent component = contexts[0].getComponent();
				if (component instanceof TCComponentForm) {
					return (TCComponentForm) component;
				}
			}
		}
		return null;
	}

	public static LinkedHashMap<String, String> getlovValues(TCSession session, String lovName) throws TCException {
		LinkedHashMap<String, String> lovVal = new LinkedHashMap<String, String>();
		TCComponentListOfValuesType lovType = (TCComponentListOfValuesType) session.getTypeComponent("ListOfValues");
		TCComponentListOfValues[] lovs = lovType.find(lovName);
		if (lovs != null && lovs.length > 0) {
			TCComponentListOfValues lov = lovs[0];
			ListOfValuesInfo lovInfo = lov.getListOfValues();
			String[] code = lovInfo.getStringListOfValues();
			String[] name = lovInfo.getLOVDisplayValues();
			if (code != null && name != null) {
				for (int i = 0; i < code.length; i++) {
					// System.out.printf("code[%d]=%s name[%d]=%s \n", i, code[i], i, name[i]);
					lovVal.put(code[i], name[i]);
				}
			}
			return lovVal;
		}
		return null;
	}

	public static String getTableValue(JTable table, int row, int col){
		Object val = table.getValueAt(row, col);
		if(val==null)
			return "";
		else
			return val.toString();
	}
	public static TCComponent[] query(TCSession session, String queryName, String[] aKey, String[] aVal) throws Exception {
		TCComponentQueryType imanQueryType = (TCComponentQueryType) session.getTypeComponent("ImanQuery");
		TCComponentQuery imancomponentquery = (TCComponentQuery) imanQueryType.find(queryName);
		if (imancomponentquery == null) {
			throw new Exception("未找到查询构建器 " + queryName + "!");
		}
		aKey = session.getTextService().getTextValues(aKey);
//		for (int i = 0; i < aKey.length; i++) {
//			System.out.println(aKey[i] + "===============" + aVal[i]);
//		}
		TCComponentContextList componentContextList = imancomponentquery.getExecuteResultsList(aKey, aVal);
		return componentContextList.toTCComponentArray();
	}
	public static TCComponent[] query(TCSession session, String queryName, Vector<String> Keys, Vector<String> Vals) throws Exception {
		TCComponentQueryType imanQueryType = (TCComponentQueryType) session.getTypeComponent("ImanQuery");
		TCComponentQuery imancomponentquery = (TCComponentQuery) imanQueryType.find(queryName);
		if (imancomponentquery == null) {
			System.out.println("未找到查询构建器" + queryName);
			throw new Exception("Query:"+queryName+" cannot find");
		}
		TCQueryClause[] qc = imancomponentquery.describe();
//		Map<String, String> clauseMap = new HashMap<>();
		for(TCQueryClause c : qc) {
			String key = c.getUserEntryNameDisplay();
			String value = c.getDefaultValue();
//			System.out.println(key + "==>" + c.getAttributeName());
			if(!value.trim().isEmpty() && !Keys.contains(key)) {
				if(key.isEmpty())
					Keys.add(c.getAttributeName());
				else
					Keys.add(key);
				Vals.add(value);
			}
		}
		int size = Keys.size();
		String[] keyA = new String[size];
		String[] valueA = new String[size];
		for(int i=0; i<size; i++) {
			keyA[i] = Keys.get(i);
			valueA[i] = Vals.get(i);
			System.out.println(keyA[i] + ":" + valueA[i]);
		}
		TCComponentContextList componentContextList = imancomponentquery.getExecuteResultsList(keyA, valueA);
		return componentContextList.toTCComponentArray();
	}
	public static String getSerialNo(TCSession session, String itemId, String objectType) throws Exception {
		TCComponent[] comps = null;
		if (objectType.equals("")) {
			comps = query(session, "零组件 ID", new String[] { "ItemID" }, new String[] { itemId + "*" });
		} else {
			comps = query(session, "零组件...", new String[] { "ItemID", "Type" }, new String[] { itemId + "*", objectType });
		}
//		System.out.println("getSerialNo comps.len:" + (comps == null ? 0 : comps.length));
		if (comps.length > 0) {
			Integer maxId = 0;
			for (TCComponent comp : comps) {
				String pid = comp.getProperty("item_id");
				System.out.println("pid:" + pid);
				String pidSuffix = pid.substring(pid.length() - 3);
				if (Integer.parseInt(pidSuffix) > maxId) {
					maxId = Integer.parseInt(pidSuffix);
				}
			}
			return String.format("%03d", maxId + 1);
		}
		return "001";
	}

	public static File saveExcelChooser() {
		File dir = null;
		JFileChooser chooser = new JFileChooser();
		chooser.setAcceptAllFileFilterUsed(false);
//		File currentDir = FileSystemView.getFileSystemView().getDefaultDirectory();
		File desktopDir = FileSystemView.getFileSystemView().getHomeDirectory();
		chooser.setCurrentDirectory(desktopDir);
		String saveType[] = { "xlsx" };
		chooser.setFileFilter(new FileNameExtensionFilter("Excel工作簿", saveType));
		int returnVal = chooser.showSaveDialog(new Frame());
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			dir = chooser.getSelectedFile();
			String path = dir.getPath();
			if(!path.toLowerCase().endsWith(".xlsx")) {
				path += ".xlsx";
				dir = new File(path);
			}
			System.out.println("saveExcelChooser1:" + path);
		}
		return dir;
	}

	public static File saveExcelChooser(Window parent, String defaultFile) {
		File dir = null;
		JFileChooser chooser = new JFileChooser();
		chooser.setAcceptAllFileFilterUsed(false);
//		File currentDir = FileSystemView.getFileSystemView().getDefaultDirectory();
		File desktopDir = FileSystemView.getFileSystemView().getHomeDirectory();
		chooser.setCurrentDirectory(desktopDir);
		chooser.setSelectedFile(new File(defaultFile));
		String saveType[] = { "xlsx" };
		chooser.setFileFilter(new FileNameExtensionFilter("Excel工作簿", saveType));
		int returnVal = chooser.showSaveDialog(new JDialog(parent));
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			dir = chooser.getSelectedFile();
			String path = dir.getPath();
			if(!path.toLowerCase().endsWith(".xlsx")) {
				path += ".xlsx";
				dir = new File(path);
			}
			if(dir.exists())
				dir.delete();
//			System.out.println("saveExcelChooser1:" + dir.getPath());
		}
		return dir;
	}

	public static boolean contains(String[] array, String str) {
		for(String s : array) {
//			System.out.println("contains:"+s+"="+str);
			if(s.equals(str))
				return true;
		}
		return false;
	}
	
	public static Map<String, String> executeToMap(InputStream in){
		System.out.println("Read properties file");
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(in, "utf-8"));
			String line = null;
			Map<String, String> resultMap = new LinkedHashMap<>(16);
			if (reader.ready()) {
				while (null != (line = reader.readLine())) {
					if (line.length() <= 0 || line.startsWith("#") || !line.contains("=")) {
						continue;
					}
					resultMap.put(line.substring(0, line.indexOf("=")), line.substring(line.indexOf("=") + 1));
				}
			}
			in.close();
			reader.close();
			return resultMap;
		} catch (Exception e) {
			e.printStackTrace();
			MessageBox.post("Find properties file failed", "ERROR", MessageBox.ERROR);
		}
		return null;
	}

	public static TCComponentDataset createExcelDataset(TCSession session, File file, String datasetName) throws Exception {
		String refType = null, objType = null, fileName = null;
		fileName = file.getName().toLowerCase();
		if (fileName.endsWith("xls")) {
			refType = "excel";
			objType = "MSExcel";
		} else if (fileName.endsWith("xlsx")) {
			refType = "excel";
			objType = "MSExcelX";
		}
		TCComponentDatasetType compType = (TCComponentDatasetType) session.getTypeService().getTypeComponent("Dataset");
		TCComponentDataset dataset = compType.create(datasetName, "description", objType);
		dataset.setFiles(new String[] { file.getAbsolutePath() }, new String[] { refType });
		return dataset;
	}
	
	public static Vector<TCComponent> getChildren(TCComponent parent, String relation, String name) throws Exception {
		Vector<TCComponent> result = new Vector<>();
		AIFComponentContext[] children;
		if(relation==null || relation.isEmpty())
			children = parent.getChildren();
		else
			children = parent.getChildren(relation);
		for(AIFComponentContext c : children) {
			TCComponent comp = (TCComponent) c.getComponent();
			if(comp.getProperty("object_name").equals(name))
				result.add(comp);
		}
		return result;
	}
	
	public static void setByPass(boolean b) {
//		KUtil.setByPass(b);
	}
}
