//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.properties;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.dialogs.ItemsFilterDialog;
import org.eclipse.epf.authoring.ui.filters.ProcessGuidanceFilter;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.configuration.GuidanceItemProvider;
import org.eclipse.epf.library.edit.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.itemsfilter.FilterInitializer;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.command.AddGuidanceToBreakdownElementCommand;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.ProcessScopeUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Checklist;
import org.eclipse.epf.uma.Concept;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.EstimationConsiderations;
import org.eclipse.epf.uma.Example;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.Guideline;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.Report;
import org.eclipse.epf.uma.ReusableAsset;
import org.eclipse.epf.uma.SupportingMaterial;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.Template;
import org.eclipse.epf.uma.ToolMentor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableFontProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

/**
 * The breakdown element guidance section. It list all available guidances for an breakdown element
 * 
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class BreakdownElementGuidanceSection extends AbstractSection {
	private FormToolkit toolkit;

	private Button ctrl_add_1, ctrl_remove_1;

	private Table ctrl_table_1;

	private TableViewer viewer_1;

	// element
	private BreakdownElement element;

	// action manager
	private IActionManager actionMgr;

	public final String tabName = FilterConstants.GUIDANCE;

	private IFilter generalGuidanceFilter = null;

	private DescriptorPropUtil propUtil;

	/**
	 * Get General guidance filter
	 * 
	 */
	public IFilter getGeneralGuidanceFilter() {
		if (generalGuidanceFilter == null) {
			generalGuidanceFilter = new ProcessGuidanceFilter(
					getConfiguration(), null, tabName) {
				public boolean childAccept(Object obj) {
					if (super.childAccept(obj))
						return true;
					if (obj instanceof GuidanceItemProvider) {
						if (((GuidanceItemProvider) obj).getChildren(obj)
								.isEmpty())
							return false;
						else
							return true;
					}
					Class cls = FilterInitializer.getInstance()
							.getClassForType(helper.getFilterTypeStr());
					if (cls != null) {
						if (cls.isInstance(obj)) {
							return true;
						} else {
							return false;
						}
					}
					if ((obj instanceof Checklist) || (obj instanceof Concept)
							|| (obj instanceof Example)
							|| (obj instanceof Guideline)
							|| (obj instanceof ReusableAsset)
							|| (obj instanceof SupportingMaterial)
							|| (obj instanceof Template)
							|| (obj instanceof Report)
							|| (obj instanceof ToolMentor)
							|| (obj instanceof EstimationConsiderations))
						return true;

					return false;

				}
			};
		}else {
			((ProcessGuidanceFilter) generalGuidanceFilter).setMethodConfiguration(getConfiguration());
		}
		return generalGuidanceFilter;
	}

	

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
	 */
	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage) {

		super.createControls(parent, tabbedPropertySheetPage);
		init();

		parent.setLayout(new GridLayout());
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));

		// create guidance section
		createGuidanceSection(parent);

		// add listeners
		addListeners();

		// update controls
		updateControls();

	}

	/**
	 * Initialize
	 */
	private void init() {
		// get activity object
		element = (BreakdownElement) getElement();

		// get toolkit
		toolkit = getWidgetFactory();

		// get action manager
		actionMgr = EPFPropertySheetPage.getActionManager();
		
		propUtil = DescriptorPropUtil.getDesciptorPropUtil(actionMgr);
	}


	/**
	 *  Update controls based on editable flag. Controls can become editable or un-editable
	 */
	public void updateControls() {
		ctrl_add_1.setEnabled(editable);
		
		IStructuredSelection selection = (IStructuredSelection) viewer_1
				.getSelection();
		if (selection.size() > 0 && editable) {
			ctrl_remove_1.setEnabled(true);
		} else {
			ctrl_remove_1.setEnabled(false);
		}
	}


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof BreakdownElement) {
				element = (BreakdownElement) getElement();

				initContentProvider();
				initLabelProvider();
				
				viewer_1.refresh();

				// hide/show controls
				updateControls();
			}

		} catch (Exception ex) {
			logger.logError("Error refreshing activity guidance section: ", ex); //$NON-NLS-1$
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.AbstractSection#dispose()
	 */
	public void dispose() {
		super.dispose();
	}

	/**
	 * Create guidance section on the given composite
	 * @param composite
	 */
	private void createGuidanceSection(Composite composite) {
		int tableHeight = 50;
		String sectionTitle = null;
		String sectionDesc = null;
		String tableTitle = null;

		// GENERAL GUIDANCE
		{
			sectionTitle = PropertiesResources.Activity_GeneralGuidanceTitle; 
			sectionDesc = PropertiesResources.Activity_GeneralGuidanceDescription; 
			tableTitle = PropertiesResources.Activity_Selected_GeneralGuidance; 

			if (isSyncFree()) {
				sectionDesc = sectionDesc + " " + PropertiesResources.Process_SyncFree_FontStyle; //$NON-NLS-1$
			}
			Section section = FormUI.createSection(toolkit, composite,
					sectionTitle, sectionDesc);

			// create composite
			Composite sectionComposite = FormUI.createComposite(toolkit,
					section, 2, false);

			Composite pane1 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.FILL_BOTH);
			FormUI.createLabel(toolkit, pane1, tableTitle);

			ctrl_table_1 = FormUI.createTable(toolkit, pane1, tableHeight);
			viewer_1 = new TableViewer(ctrl_table_1);
			
			initContentProvider();
			initLabelProvider();

			viewer_1.setInput(element);

			// create buttons for table2
			Composite pane2 = FormUI.createComposite(toolkit, sectionComposite,
					GridData.VERTICAL_ALIGN_CENTER
							| GridData.HORIZONTAL_ALIGN_CENTER);

			ctrl_add_1 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Add);
			ctrl_remove_1 = FormUI.createButton(toolkit, pane2,
					PropertiesResources.Process_Remove);

			toolkit.paintBordersFor(pane1);
		}
	}
	
	protected void initContentProvider() {
		IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
				getAdapterFactory()) {
			public Object[] getElements(Object object) {
				List<MethodElement> elements = new ArrayList<MethodElement>();
				elements.addAll(getSelectedGuidances());

				if (element instanceof Descriptor) {
					Descriptor des = (Descriptor) element;
	
					if (isSyncFree() && !propUtil.isNoAutoSyn(des)) {
						elements.addAll((des).getGuidanceExclude());
					}
	
					MethodElement linkedElement = ProcessUtil
							.getAssociatedElement(des);
	
					if (linkedElement != null) {
						Process process = ProcessUtil.getProcess(des
								.getSuperActivities());
						if (ProcessScopeUtil.getInstance().isConfigFree(process)) {
							Map<EReference, EReference> refMap = LibraryEditUtil.getInstance().getGuidanceRefMap(
											linkedElement.eClass());
							Set<Object> set = new HashSet<Object>();
							for (EReference ref : refMap.keySet()) {
								Object value = linkedElement.eGet(ref);
								if (value instanceof List) {
									set.addAll((List) value);
								}
								List<Guidance> locals = des.getGuidanceAdditional(); 
								if (locals != null && !locals.isEmpty()) {
									set.addAll(locals);
								}
							}
							elements.retainAll(set);
						}
					}				
				}

				return getFilteredList(elements).toArray();
			}
		};

		viewer_1.setContentProvider(contentProvider);		
	}
	
	protected void initLabelProvider() {		
		ILabelProvider labelProvider = null;
		
		if (isSyncFree()) {
			labelProvider = new GuidanceSyncFreeLabelProvider(
					TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory(),
					(Descriptor)element, getConfiguration());  
		} else {
			labelProvider = new AdapterFactoryLabelProvider(
					TngAdapterFactory.INSTANCE.getNavigatorView_ComposedAdapterFactory());
		}
		
		viewer_1.setLabelProvider(labelProvider);
	}
	
	/**
	 * Add listeners
	 * 
	 */
	private void addListeners() {
		ItemProviderAdapter adapter = (ItemProviderAdapter) getAdapter();
		Object parent = null;
		if (adapter instanceof IBSItemProvider) {
			IBSItemProvider bsItemProvider = (IBSItemProvider) adapter;
			parent = bsItemProvider.getTopItem();
		} else {
			logger
					.logError("ActivityGuidanceSection::addListeners - IBSItemProvider is null"); //$NON-NLS-1$
			return;
		}

		{
			ctrl_table_1.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					IStructuredSelection selection = (IStructuredSelection) viewer_1
							.getSelection();
					if ((selection.size() > 0) && editable)
						ctrl_remove_1.setEnabled(true);
				}
			});

			viewer_1
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_1
									.getSelection();							
							if ((selection.size() > 0) && editable) {
								if (isSyncFree()) {
									syncFreeUpdateBtnStatus(selection);
								} else {
									ctrl_remove_1.setEnabled(true);
								}
							}
						}
					});

			ctrl_add_1.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					if (isSyncFree()) {
						IStructuredSelection selection = (IStructuredSelection) viewer_1.getSelection();
						if (syncFreeAdd(selection)) { 
							viewer_1.refresh();
							return;
						}
					}
					
					IFilter filter = getGeneralGuidanceFilter();
					List existingElements = null;
					if (isSyncFree()) {
						existingElements = getSelectedGuidances();
						if (! propUtil.isNoAutoSyn((Descriptor)element)) {
							existingElements.addAll(((Descriptor)element).getGuidanceExclude());
						}
					} else {
						existingElements = getSelectedGuidances();
					}					
					ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
							.getWorkbench().getActiveWorkbenchWindow()
							.getShell(), filter, element,
							FilterConstants.GUIDANCE, existingElements);

					fd.setTitle(FilterConstants.GUIDANCE);
					fd.setInput(UmaUtil.getMethodLibrary((EObject) element));
					fd.setBlockOnOpen(true);
					fd.setTypes(getFilterTypes());	
					fd.setEnableProcessScope(true);
					fd.setSection(getSection());
					fd.open();
					addGuidances(fd.getSelectedItems());
					viewer_1.refresh();
				}
			});

			ctrl_remove_1.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					if (isSyncFree()) {
						IStructuredSelection selection = (IStructuredSelection) viewer_1.getSelection();
						if (syncFreeRemove(selection)) {
							viewer_1.refresh();
							ctrl_remove_1.setEnabled(false);
							return;
						}							
					} 
					
					IStructuredSelection selection = (IStructuredSelection) viewer_1
							.getSelection();
					if (selection.size() > 0) {
						// update the model
						ArrayList rmItems = new ArrayList();
						rmItems.addAll(selection.toList());
						removeGuidances(rmItems);
						viewer_1.refresh();

						// clear the selection
						viewer_1.setSelection(null, true);
					}
					ctrl_remove_1.setEnabled(false);
				}
			});
		}
	}
	
	private void addGuidances(List<Guidance> addItems) {
		addGuidances(addItems, false);
	}
	
	/**
	 * Add guidances to the element
	 * @param addItems
	 * 				list of guidances to add
	 */
	private void addGuidances(List<Guidance> addItems, boolean calledForExculded) {
		// update the model
		AddGuidanceToBreakdownElementCommand command = new AddGuidanceToBreakdownElementCommand(
				element, addItems, calledForExculded);
		actionMgr.execute(command);
	}
	
	private void removeGuidances(List<Guidance> rmItems) {
		removeGuidances(rmItems, true);
	}

	/**
	 * Remove guidances from the element
	 * @param rmItems
	 * 				list of guidances to remove
	 */
	private void removeGuidances(List<Guidance> rmItems, boolean localUse) {
		// update the model
		if (!rmItems.isEmpty()) {
			for (Iterator it = rmItems.iterator(); it.hasNext();) {
				Guidance item = (Guidance) it.next();

				// guidances for activity
				if (item instanceof Checklist) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Checklists(),
							item, -1);
				} else if (item instanceof Concept) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Concepts(), item,
							-1);
				} else if (item instanceof Example) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Examples(), item,
							-1);
				} else if (item instanceof SupportingMaterial) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE
									.getBreakdownElement_SupportingMaterials(), item,
							-1);
				} else if (item instanceof Guideline) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Guidelines(),
							item, -1);
				} else if (item instanceof ReusableAsset) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_ReusableAssets(),
							item, -1);
				}else if (item instanceof Template) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Templates(),
							item, -1);
				}else if (item instanceof Report) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Reports(),
							item, -1);
				}else if (item instanceof ToolMentor) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Toolmentor(),
							item, -1);
				}else if (item instanceof EstimationConsiderations) {
					actionMgr.doAction(IActionManager.REMOVE, element,
							UmaPackage.eINSTANCE.getBreakdownElement_Estimationconsiderations(),
							item, -1);
				} else {
					logger
							.logError("Can't remove Guidance: " + item.getType().getName() + ":" + item.getName()); //$NON-NLS-1$ //$NON-NLS-2$
				}
				
				if (isSyncFree()) {
					if (localUse) {
						actionMgr.doAction(IActionManager.REMOVE, element,
								UmaPackage.eINSTANCE.getDescriptor_GuidanceAdditional(),
								item, -1);
						if (element instanceof TaskDescriptor) {
							TaskDescriptor td = (TaskDescriptor) element;
							TaskDescriptor greenParent = (TaskDescriptor) propUtil.getGreenParentDescriptor(td);
							if (greenParent != null) {
								EReference aRef = UmaPackage.eINSTANCE.getDescriptor_GuidanceAdditional();
								List<Guidance> parentAdditionalList = (List<Guidance>) greenParent.eGet(aRef);
								propUtil.removeGreenRefDelta(td, item, aRef, true);
								if (parentAdditionalList != null && parentAdditionalList.contains(item)) {
									propUtil.addGreenRefDelta(td, item, aRef, false);
								}
							}
						}
					} else {
						actionMgr.doAction(IActionManager.ADD, element,
								UmaPackage.eINSTANCE.getDescriptor_GuidanceExclude(),
								item, -1);
						
						//for Green parent
						Descriptor parent = propUtil.getGreenParentDescriptor((Descriptor)element);
						if ((parent != null) && (parent instanceof TaskDescriptor)) {
							TaskDescriptor greenParent = (TaskDescriptor)parent;
							EReference ref = propUtil.getGuidanceEReference(item);
							EReference eRef = LibraryEditUtil.getInstance().getExcludeFeature(ref);
							List<MethodElement> parentExecludeList = (List<MethodElement>) greenParent.eGet(eRef);
							
							propUtil.removeGreenRefDelta((Descriptor) element, item, eRef, false);
							if (parentExecludeList != null && !parentExecludeList.contains(item)) {
								propUtil.addGreenRefDelta((Descriptor) element, item, eRef, true);
							}
						}
					}				
				}
			}
		}
	}

	/**
	 * Get selected guidances
	 * @return
	 * 			list of existing selected guidances
	 */
	private List<Guidance> getSelectedGuidances() {
		List<Guidance> itemList = new ArrayList();

		itemList.addAll(element.getChecklists());
		itemList.addAll(element.getConcepts());
		itemList.addAll(element.getExamples());
		itemList.addAll(element.getGuidelines());
		itemList.addAll(element.getReusableAssets());
		itemList.addAll(element.getSupportingMaterials());
		itemList.addAll(element.getTemplates());
		itemList.addAll(element.getReports());
		itemList.addAll(element.getEstimationconsiderations());
		itemList.addAll(element.getToolmentor());


		return itemList;
	}

	/**
	 * Return list of filter types
	 */
	protected String[] getFilterTypes() {
		String[] str = new String[12];
		int i = 0;
		str[i++] = FilterConstants.GUIDANCE;
		str[i++] = FilterConstants.space + FilterConstants.CHECKLISTS;
		str[i++] = FilterConstants.space + FilterConstants.CONCEPTS;
		str[i++] = FilterConstants.space
				+ FilterConstants.ESTIMATE_CONSIDERATIONS;
		str[i++] = FilterConstants.space + FilterConstants.EXAMPLES;
		str[i++] = FilterConstants.space + FilterConstants.GUIDELINES;
		str[i++] = FilterConstants.space + FilterConstants.REPORTS;
		str[i++] = FilterConstants.space + FilterConstants.REUSABLE_ASSETS;
		str[i++] = FilterConstants.space + FilterConstants.SUPPORTING_MATERIALS;
		str[i++] = FilterConstants.space + FilterConstants.TEMPLATES;
		str[i++] = FilterConstants.space + FilterConstants.TOOL_MENTORS;
		str[i++] = FilterConstants.space + FilterConstants.WHITE_PAPERS;
		return str;
	}
	
	protected boolean isSyncFree() {
		return propUtil.isDescriptor(element) && ProcessUtil.isSynFree();
	}
	
	protected boolean syncFreeAdd(IStructuredSelection selection) {
		if (selection.size() == 0) {
			return false;			
		} 
				
		boolean result = propUtil.CheckSelectionForGuidance(selection.toList(), (Descriptor)element, getConfiguration());	
		
		if (! result) {
			return true;
		}
		
		Object testObj = selection.getFirstElement();
		EReference ref = propUtil.getGuidanceEReference((Guidance)testObj);
		if (propUtil.isDynamicAndExclude(testObj, (Descriptor)element, ref, getConfiguration())) {				
			addGuidances(selection.toList(), true);
			return true;
		} 
		
		return false;
	}
	
	protected boolean syncFreeRemove(IStructuredSelection selection) {
		if (selection.size() == 0) {
			return true;			
		} 
		
		boolean result = propUtil.CheckSelectionForGuidance(selection.toList(), (Descriptor)element, getConfiguration());
		if (! result) {
			return true;
		}

		Object testObj = selection.getFirstElement();
		EReference ref = propUtil.getGuidanceEReference((Guidance)testObj);		
		if (propUtil.isDynamicAndExclude(testObj, (Descriptor)element, ref, getConfiguration())) {
			return true;
		} 
		
		if (propUtil.isGuidanceDynamic(testObj, (Descriptor)element, getConfiguration())) {
			removeGuidances(selection.toList(), false);
			return true;
		} 
				
		return false;
	}
	
	protected void syncFreeUpdateBtnStatus(IStructuredSelection selection) {		
		boolean result = propUtil.CheckSelectionForGuidance(selection.toList(), (Descriptor)element, getConfiguration());
		
		if (!result) {
			ctrl_add_1.setEnabled(false);
			ctrl_remove_1.setEnabled(false);
		} else {
			Object testObj = selection.getFirstElement();
			EReference ref = propUtil.getGuidanceEReference((Guidance)testObj);
			if (propUtil.isDynamicAndExclude(testObj, (Descriptor)element, ref, getConfiguration())) {
				ctrl_add_1.setEnabled(true);
				ctrl_remove_1.setEnabled(false);
			} else {
				ctrl_add_1.setEnabled(true);
				ctrl_remove_1.setEnabled(true);
			}
		}		
	}
	
	public class GuidanceSyncFreeLabelProvider extends AdapterFactoryLabelProvider implements ITableFontProvider {
		private DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
		private Font systemFont = Display.getCurrent().getSystemFont();
		private	Font boldFont = null;
		private Font boldAndItalicFont = null;
		
		private Descriptor desc;
		private MethodConfiguration config;

		public GuidanceSyncFreeLabelProvider(AdapterFactory adapterFactory, Descriptor desc, MethodConfiguration config) {
			super(adapterFactory);
			this.desc = desc;		
			this.config = config;
			boldFont = createFont(SWT.BOLD);
			boldAndItalicFont = createFont(SWT.BOLD | SWT.ITALIC);
		}
	    
	    public Font getFont(Object obj, int columnIndex) {
			if (propUtil.isGuidanceFromGreenParentLocalList(obj, desc, config)) {
				return boldAndItalicFont;
			}
			
		 	if (!propUtil.isGuidanceDynamic(obj, desc, config)) {
		 		return boldFont;
	    	}
			
	    	return systemFont;
	    }	    	
	    
	    public String getColumnText(Object obj, int columnIndex) {
	    	String original = super.getColumnText(obj, columnIndex);
	    	
	    	EReference ref = propUtil.getGuidanceEReference((Guidance)obj);
	    	
	    	if (propUtil.isDynamicAndExclude(obj, desc, ref, config)) {
	    		return "--<" + original + ">";	    		 //$NON-NLS-1$ //$NON-NLS-2$
	    	}
	    	
	    	return original;	    	
	    }
	    
	    public void dispose() {
	    	super.dispose();
	    	
	    	if (boldFont != null) {
	    		boldFont.dispose();
	    	}
	    	
	    	if (boldAndItalicFont != null) {
	    		boldAndItalicFont.dispose();
	    	}
	    }
	    
	    private Font createFont(int style) {
			FontData[] fontdata = systemFont.getFontData();
			for (FontData data : fontdata) {
				data.setStyle(style);
			}
			
			return new Font(Display.getCurrent(), fontdata);    	
	    }	    
	}
	
}
