package dfatool.views;


import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import patterns.Observer;
import dfatool.strategy.elements.Atom;
import dfatool.strategy.elements.Channel;
import dfatool.strategy.elements.Configuration;
import dfatool.strategy.elements.Datatype;
import dfatool.strategy.elements.Description;
import dfatool.strategy.elements.NamedElement;
import dfatool.strategy.elements.Var;
import dfatool.views.dialogs.AtomCreationDialog;
import dfatool.views.dialogs.ChannelCreationDialog;
import dfatool.views.dialogs.DatatypeCreationDialog;
import dfatool.views.dialogs.VarCreationDialog;



public class DescriptionList extends ViewPart {

	/**
	 * The ID of the view as specified by the extension.
	 */
	
	public static final String ID = "dfatool.views.DescriptionList";

	private ListViewer viewer;
	private Action addType;
	private Action addVar;
	private Action addChannel;
	private Action addAtom;
	private Action refresh;
	 
	class ViewContentProvider implements IStructuredContentProvider {

		@Override
		public void dispose() {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			// TODO Auto-generated method stub
			
		}
		@Override
		public Object[] getElements(Object inputElement) {
			Description description =  (Description) inputElement;
			Object[] a = description.getList().toArray();
			return a;
		}
	}
	
	class ViewLabelProvider extends LabelProvider implements ILabelProvider {
		public String getText(Object obj, int index) {
			return getText(obj);
		}
	}

	/**
	 * The constructor.
	 */
	public DescriptionList() {
	}

	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */

	
	public void createPartControl(Composite parent) {

		//Create gui
		viewer = new ListViewer(parent);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());

		getSite().setSelectionProvider(viewer);
		// Create the help context id for the viewer's control
		makeActions();
		hookSelectAction();
		contributeToActionBars();
		update();
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalToolBar(bars.getToolBarManager());
	}


	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(refresh);
		manager.add(addType);
		manager.add(addVar);
		manager.add(addAtom);
		manager.add(addChannel);
	}

	private void makeActions() {
		
		refresh = new Action() {
			public void run() {
				viewer.refresh();
			}
		};
		refresh.setText("Refresh");
		refresh.setToolTipText("Refresh view");
		
		
		addType = new Action() {
			public void run() {
				new DatatypeCreationDialog(getViewSite()).open();
				viewer.refresh();
			}
		};
		addType.setText("+Ty");
		addType.setToolTipText("Add new datatype");

		addVar = new Action() {
			public void run() {
				new VarCreationDialog(getViewSite()).open();
				viewer.refresh();
			}
		};
		addVar.setText("+Va");
		addVar.setToolTipText("Add new variable");
		
		addAtom = new Action() {
			public void run() {
				new AtomCreationDialog(getViewSite()).open();
				viewer.refresh();
			}
		};
		addAtom.setText("+At");
		addAtom.setToolTipText("Add new atom");
		
		addChannel = new Action() {
			public void run() {
				new ChannelCreationDialog(getViewSite()).open();
				viewer.refresh();
			}
		};
		addChannel.setText("+Ch");
		addChannel.setToolTipText("Add new channel");
		
	}
	
	private void hookSelectAction() {
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				NamedElement selectedElement = ((NamedElement)((StructuredSelection) event.getSelection()).getFirstElement());
				String viewId = null;
				if(selectedElement instanceof Channel)
					viewId = ChannelInfo.ID;
				else if(selectedElement instanceof Atom)
					viewId = AtomInfo.ID;
				else if(selectedElement instanceof Datatype)
					viewId = DatatypeInfo.ID;
				else if(selectedElement instanceof Var)
					viewId = VarInfo.ID;
				if(viewId != null)
					displayAndUpdateEditionView(viewId, selectedElement);
					
			}
		});
	}
	
	private void displayAndUpdateEditionView(String viewId, NamedElement element){
		System.out.println("Display and Update: viewId"+viewId+ " NamedElement "+ element.getName());
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
		InfoView view = (InfoView) page.findView(viewId);
		page.activate(view);
		view.updateView(element);
	}


	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
	
	public void refresh(){
		viewer.setInput(Configuration.getInstance().getDescription());
		viewer.refresh();	
	}


	@Override
	public void dispose() {
		super.dispose();
		Configuration.getInstance().getDescription().unregister(this);
	}

}