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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.teamcenter.rac.aif.kernel.AIFComponentContext;
import com.teamcenter.rac.kernel.TCComponent;
import com.teamcenter.rac.kernel.TCComponentBOMLine;
import com.teamcenter.rac.kernel.TCComponentItemRevision;

import cn.net.connor.std.aifrcp.util.KUtil;

public class PropLocation2 {

	public static final String ITEM = "ITEM";
	public static final String REV = "REV";
	public static final String ITEMMASTER = "ITEMMASTER";
	public static final String REVMASTER = "REVMASTER";
	public static final String BOMLINE = "BOMLINE";
	
	public static final String CITEM = "CITEM";
	public static final String CREV = "CREV";
	public static final String CITEMMASTER = "CITEMMASTER";
	public static final String CREVMASTER = "CREVMASTER";
	public static final String CBOMLINE = "CBOMLINE";
	
	public static final String PITEM = "PITEM";
	public static final String PREV = "PREV";
	public static final String PITEMMASTER = "PITEMMASTER";
	public static final String PREVMASTER = "PREVMASTER";
	public static final String PBOMLINE = "PBOMLINE";
	
	public static final String METARGET_ITEM = "MITEM";
	public static final String METARGET_REV = "MREV";
	public static final String METARGET_ITEMMASTER = "MITEMMASTER";
	public static final String METARGET_REVMASTER = "MREVMASTER";

	public static final String ITEM2 = "ITEM2";
	public static final String REV2 = "REV2";
	public static final String ITEMMASTER2 = "ITEMMASTER2";
	public static final String REVMASTER2 = "REVMASTER2";
	public static final String BOMLINE2 = "BOMLINE2";
	
	public static void formatMarkedData_old(TCComponentBOMLine targetLine, TCComponentItemRevision meTargetRev, String[] item2Types, Map<String, TCComponent> markedComponents, List<Map<String, TCComponent>> markedLineComponents) throws Exception{
		System.out.println("-------------------------------------------------------------------");
		System.out.println("Parse Marked Component: "+targetLine+" | "+meTargetRev);
		PropLocation2.initLocationMap(markedComponents, targetLine);
		PropLocation2.initPLocationMap(markedComponents, targetLine);
		PropLocation2.initMLocationMap(markedComponents, meTargetRev);
		AIFComponentContext[] cc = targetLine.getChildren();
		int cnt = KUtil.getLen(cc);
		int gdInd = -1;
		int fgdInd = -1;
		for (int i = 0; i < cnt; i++) {
			TCComponentBOMLine cLine = (TCComponentBOMLine) cc[i].getComponent();
			String cItemType = cLine.getStringProperty("bl_item_object_type");
			System.out.println(String.format("%d. Child Line: [%s](%s)", i + 1, cLine.toString(), cItemType));
			Map<String, TCComponent> cMarkedComponents;
			if (KUtil.inArray(cItemType, item2Types) >= 0) { // reorder child line by different types. 
				gdInd++;
				if(gdInd>=markedLineComponents.size()) {
					cMarkedComponents = new HashMap<String, TCComponent>();
					markedLineComponents.add(cMarkedComponents);
				}else {
					cMarkedComponents = markedLineComponents.get(gdInd);
				}
				PropLocation2.initLocationMap2(cMarkedComponents, cLine);
			}else {
				fgdInd++;
				if(fgdInd>=markedLineComponents.size()) {
					cMarkedComponents = new HashMap<String, TCComponent>();
					markedLineComponents.add(cMarkedComponents);
				}else {
					cMarkedComponents = markedLineComponents.get(fgdInd);
				}
				PropLocation2.initLocationMap(cMarkedComponents, cLine);
			}
		}
		System.out.println("Parse Marked Component Complete");
		System.out.println("-------------------------------------------------------------------");
	}
	
	public static void formatMarkedData2(TCComponentBOMLine targetLine, TCComponentItemRevision meTargetRev, String[] filterTypes, boolean readGrandChild, String[] grandChildTypes, Map<String, TCComponent> markedComponents, List<Map<String, TCComponent>> markedLineComponents) throws Exception{
		System.out.println("-------------------------------------------------------------------");
		System.out.println("Parse Marked Component: "+targetLine+" | "+meTargetRev);
		PropLocation2.initLocationMap(markedComponents, targetLine);
		PropLocation2.initPLocationMap(markedComponents, targetLine);
		PropLocation2.initMLocationMap(markedComponents, meTargetRev);
		AIFComponentContext[] cc = targetLine.getChildren();
		int cnt = KUtil.getLen(cc);
		boolean filterType = KUtil.getLen(filterTypes)>0;
		boolean filterGrandChild = KUtil.getLen(grandChildTypes)>0;
		for (int i = 0; i < cnt; i++) {
			TCComponentBOMLine cLine = (TCComponentBOMLine) cc[i].getComponent();
			String cItemType = cLine.getStringProperty("bl_item_object_type");
			System.out.println(String.format("%d. Child Line: [%s](%s)", i + 1, cLine.toString(), cItemType));
			Map<String, TCComponent> cMarkedComponents = new HashMap<String, TCComponent>();
			if(filterType&&KUtil.inArray(cItemType, filterTypes)<0) {
				continue;
			}
			markedLineComponents.add(cMarkedComponents);
			PropLocation2.initLocationMap(cMarkedComponents, cLine);
			if(readGrandChild) {
				List<TCComponentBOMLine> filterGrandChilds = new ArrayList<TCComponentBOMLine>();
				AIFComponentContext[] ccc = cLine.getChildren();
				int grandChildCnt = KUtil.getLen(ccc);
				for(int j=0;j<grandChildCnt;j++) {
					TCComponentBOMLine ccLine = (TCComponentBOMLine) ccc[j].getComponent();
					if(filterGrandChild) {
						String grandItemType = ccLine.getStringProperty("bl_item_object_type");
						if(KUtil.inArray(grandItemType, grandChildTypes)<0) {
							continue;
						}
					}
					filterGrandChilds.add(ccLine);
				}
				grandChildCnt = filterGrandChilds.size();
				for(int j=0;j<grandChildCnt;j++) {
					TCComponentBOMLine ccLine = filterGrandChilds.get(j);
					if(j>0) {
						cMarkedComponents = new HashMap<String, TCComponent>();
						markedLineComponents.add(cMarkedComponents);
					}
					PropLocation2.initCLocationMap(cMarkedComponents, ccLine);
				}
			}
		}
		System.out.println("Parse Marked Component Complete");
		System.out.println("-------------------------------------------------------------------");
	}
	
	public static void formatMarkedData2(TCComponentBOMLine targetLine, TCComponentItemRevision meTargetRev, String[] filterTypes, boolean readGrandChild, boolean readGrandChildAsTarget, String[] grandChildTypes, Map<String, TCComponent> markedComponents, List<Map<String, TCComponent>> markedLineComponents, Map<TCComponent, List<TCComponent>> relatedComponents) throws Exception{
		System.out.println("-------------------------------------------------------------------");
		System.out.println("Parse Marked Component: "+targetLine+" | "+meTargetRev);
		PropLocation2.initLocationMap(markedComponents, targetLine);
		PropLocation2.initPLocationMap(markedComponents, targetLine);
		PropLocation2.initMLocationMap(markedComponents, meTargetRev);
		AIFComponentContext[] cc = targetLine.getChildren();
		int cnt = KUtil.getLen(cc);
		boolean filterType = KUtil.getLen(filterTypes)>0;
		boolean filterGrandChild = KUtil.getLen(grandChildTypes)>0;
		List<TCComponentItemRevision> addedGrandChilds = new ArrayList<TCComponentItemRevision>();
		for (int i = 0; i < cnt; i++) {
			TCComponentBOMLine cLine = (TCComponentBOMLine) cc[i].getComponent();
			String cItemType = cLine.getStringProperty("bl_item_object_type");
			System.out.println(String.format("%d. Child Line: [%s](%s)", i + 1, cLine.toString(), cItemType));
			Map<String, TCComponent> cMarkedComponents = new HashMap<String, TCComponent>();
			if(filterType&&KUtil.inArray(cItemType, filterTypes)<0) {
				continue;
			}
			if(!readGrandChildAsTarget) {
				markedLineComponents.add(cMarkedComponents);
				PropLocation2.initLocationMap(cMarkedComponents, cLine);
			}
			if(readGrandChild) {
				List<TCComponentBOMLine> filterGrandChilds = new ArrayList<TCComponentBOMLine>();
				AIFComponentContext[] ccc = cLine.getChildren();
				int grandChildCnt = KUtil.getLen(ccc);
				for(int j=0;j<grandChildCnt;j++) {
					TCComponentBOMLine ccLine = (TCComponentBOMLine) ccc[j].getComponent();
					if(filterGrandChild) {
						String grandItemType = ccLine.getStringProperty("bl_item_object_type");
						if(KUtil.inArray(grandItemType, grandChildTypes)<0) {
							continue;
						}
					}
					filterGrandChilds.add(ccLine);
				}
				grandChildCnt = filterGrandChilds.size();
				for(int j=0;j<grandChildCnt;j++) {
					TCComponentBOMLine ccLine = filterGrandChilds.get(j);
					if(readGrandChildAsTarget) {
						TCComponentItemRevision ccRev = ccLine.getItemRevision();
						// add related line
						if(relatedComponents!=null) {
							List<TCComponent> relateList;
							if(relatedComponents.containsKey(ccRev)) {
								relateList =relatedComponents.get(ccRev);
							}else {
								relateList= new ArrayList<TCComponent>();
								relatedComponents.put(ccRev, relateList);
							}
							if(!relateList.contains(cLine)) {
								relateList.add(cLine.getItemRevision().getRelatedComponent("IMAN_master_form_rev"));
							}
						}
						// add grand child
						if(addedGrandChilds.contains(ccRev)) {
							continue;
						}
						cMarkedComponents = new HashMap<String, TCComponent>();
						markedLineComponents.add(cMarkedComponents);
						PropLocation2.initLocationMap(cMarkedComponents, ccLine);
						addedGrandChilds.add(ccRev);
					}else {
						if(j>0) {
							cMarkedComponents = new HashMap<String, TCComponent>();
							markedLineComponents.add(cMarkedComponents);
						}
						PropLocation2.initCLocationMap(cMarkedComponents, ccLine);
					}
				}
			}
		}
		System.out.println("Parse Marked Component Complete");
		System.out.println("-------------------------------------------------------------------");
	}


	public static void initLocationMap(Map<String, TCComponent> markedComponents, TCComponentItemRevision rev) throws Exception {
		if (markedComponents == null || rev == null) {
			return;
		}
		markedComponents.put(PropLocation2.ITEM, rev.getItem());
		markedComponents.put(PropLocation2.REV, rev);
		markedComponents.put(PropLocation2.ITEMMASTER, rev.getItem().getRelatedComponent("IMAN_master_form"));
		markedComponents.put(PropLocation2.REVMASTER, rev.getRelatedComponent("IMAN_master_form_rev"));
	}
	
	public static void initMLocationMap(Map<String, TCComponent> markedComponents, TCComponentItemRevision rev) throws Exception {
		if (markedComponents == null || rev == null) {
			return;
		}
		markedComponents.put(PropLocation2.METARGET_ITEM, rev.getItem());
		markedComponents.put(PropLocation2.METARGET_REV, rev);
		markedComponents.put(PropLocation2.METARGET_ITEMMASTER, rev.getItem().getRelatedComponent("IMAN_master_form"));
		markedComponents.put(PropLocation2.METARGET_REVMASTER, rev.getRelatedComponent("IMAN_master_form_rev"));
	}
	
	public static void initLocationMap(Map<String, TCComponent> markedComponents, TCComponentBOMLine targetLine) throws Exception {
		if (markedComponents == null || targetLine == null) {
			return;
		}
		markedComponents.put(PropLocation2.BOMLINE, targetLine);
		markedComponents.put(PropLocation2.ITEM, targetLine.getItem());
		markedComponents.put(PropLocation2.REV, targetLine.getItemRevision());
		markedComponents.put(PropLocation2.ITEMMASTER, targetLine.getItem().getRelatedComponent("IMAN_master_form"));
		markedComponents.put(PropLocation2.REVMASTER, targetLine.getItemRevision().getRelatedComponent("IMAN_master_form_rev"));
	}
	
	public static void initCLocationMap(Map<String, TCComponent> markedComponents, TCComponentBOMLine targetLine) throws Exception {
		if (markedComponents == null || targetLine == null) {
			return;
		}
		markedComponents.put(PropLocation2.CBOMLINE, targetLine);
		markedComponents.put(PropLocation2.CITEM, targetLine.getItem());
		markedComponents.put(PropLocation2.CREV, targetLine.getItemRevision());
		markedComponents.put(PropLocation2.CITEMMASTER, targetLine.getItem().getRelatedComponent("IMAN_master_form"));
		markedComponents.put(PropLocation2.CREVMASTER, targetLine.getItemRevision().getRelatedComponent("IMAN_master_form_rev"));
	}
	
	public static void initPLocationMap(Map<String, TCComponent> markedComponents, TCComponentBOMLine targetLine) throws Exception {
		if (markedComponents == null || targetLine == null) {
			return;
		}
		TCComponentBOMLine parentLine = targetLine.parent();
		if(parentLine==null) {
			return;
		}
		markedComponents.put(PropLocation2.PBOMLINE, parentLine);
		markedComponents.put(PropLocation2.PITEM, parentLine.getItem());
		markedComponents.put(PropLocation2.PREV, parentLine.getItemRevision());
		markedComponents.put(PropLocation2.PITEMMASTER, parentLine.getItem().getRelatedComponent("IMAN_master_form"));
		markedComponents.put(PropLocation2.PREVMASTER, parentLine.getItemRevision().getRelatedComponent("IMAN_master_form_rev"));
	}
	
	public static void initLocationMap2(Map<String, TCComponent> markedComponents, TCComponentBOMLine targetLine) throws Exception {
		if (markedComponents == null || targetLine == null) {
			return;
		}
		markedComponents.put(PropLocation2.BOMLINE2, targetLine);
		markedComponents.put(PropLocation2.ITEM2, targetLine.getItem());
		markedComponents.put(PropLocation2.REV2, targetLine.getItemRevision());
		markedComponents.put(PropLocation2.ITEMMASTER2, targetLine.getItem().getRelatedComponent("IMAN_master_form"));
		markedComponents.put(PropLocation2.REVMASTER2, targetLine.getItemRevision().getRelatedComponent("IMAN_master_form_rev"));
		
	}
}