package interactivefeaturelocator.views;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;

import interactivefeaturelocator.model.DerivationManager;
import interactivefeaturelocator.model.DerivationUnit;
import interactivefeaturelocator.model.TreeModel;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.ntlab.trace.ThreadInstance;
import org.ntlab.trace.Trace;


/**
 * This sample class demonstrates how to plug-in a new
 * workbench view. The view shows data obtained from the
 * model. The sample creates a dummy model on the fly,
 * but a real implementation would connect to the model
 * available either in this or another plug-in (e.g. the workspace).
 * The view is connected to the model using a content provider.
 * <p>
 * The view uses a label provider to define how model
 * objects should be presented in the view. Each
 * view can present the same model objects using
 * different labels and icons, if needed. Alternatively,
 * a single label provider can be shared between views
 * in order to ensure that objects of the same type are
 * presented in the same way everywhere.
 * <p>
 */

public class TraceView extends ViewPart {

	public static TraceView theInstance = null;
	public static final String ID = "interactivefeaturelocator.views.traceview";
	private TreeViewer viewer;
//	private HashMap<String, ThreadInstance> threads = new HashMap<>();
	private TreeNode focusNode = null;
	private InteractiveDerivationView selectMethodView;
	private ArrayList<Trace> traces = new ArrayList<>();
	private DerivationManager inferenceManager;
	
	public TraceView() {
		
	}

	@Override
	public void createPartControl(Composite parent) {
		// TODO Auto-generated method stub
		theInstance = this;
		selectMethodView = InteractiveDerivationView.theInstance;
		
		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.setContentProvider(new TreeNodeContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setInput(makeData(null));
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
			
			// ノードが選択されたときの処理
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				// TODO Auto-generated method stub
				StructuredSelection selection = (StructuredSelection)event.getSelection();
				if (selection.getFirstElement() != null) {
					setFocusNode((TreeNode)selection.getFirstElement());
					if (getFocusNode() != null) {
						selectMethodView.changeFolder(0);
					}
				}
			}
		});
	}
	
	// Viewerの更新
	public void updateViewer() {
		traces.clear();
		if (selectMethodView == null) {
			selectMethodView = InteractiveDerivationView.theInstance;
		}
		for (int i = 0; i < inferenceManager.getInferenceUnitCount(); i++) {
			DerivationUnit unit = inferenceManager.getInferenceUnit(i);
			Trace plusTrace = unit.getPlusTrace();
			traces.add(plusTrace);
			selectMethodView.createTabFolder(unit);
			System.out.println(plusTrace.getFileName());
		}
		viewer.setInput(makeData(traces));
		StructuredSelection selection = new StructuredSelection(getFocusNode());
		viewer.setSelection(selection);
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub
		if (getFocusNode() != null) {
			StructuredSelection selection = new StructuredSelection(getFocusNode());
			viewer.setSelection(selection);
		}
		viewer.getControl().setFocus();
	}
	
	// データ作成メソッド
	private TreeNode[] makeData(ArrayList<Trace> traces) {
//		if (selectMethodView == null) {
//			selectMethodView = SelectMethodView.theInstance;
//		}
		if (traces == null) {
			return null;
		}
		setFocusNode(null);
		TreeNode[] node = new TreeNode[traces.size()];
		for (int i = 0; i < traces.size(); i++) {
			Trace trace = traces.get(i);
			node[i] = new TreeNode(new TreeModel(trace.getFileName(), 1));
			if (getFocusNode() == null) {
				setFocusNode(node[i]);
			}
		}
		return node;
	}
	
	public TreeNode getFocusNode() {
		return focusNode;
	}
	
	public void setFocusNode(TreeNode focus) {
		this.focusNode = focus;
	}

	public DerivationManager getIm() {
		return inferenceManager;
	}

	public void setInferanceManager(DerivationManager im) {
		this.inferenceManager = im;
	}

	public void dispose() {
		super.dispose();
		theInstance = null;
	}
}