package org.eclipse.epf.authoring.ui.forms;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.authoring.ui.filters.GuidanceFilter;
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.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.util.MethodElementUtil;
import org.eclipse.epf.uma.Checklist;
import org.eclipse.epf.uma.Concept;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.Domain;
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.Practice;
import org.eclipse.epf.uma.Report;
import org.eclipse.epf.uma.ReusableAsset;
import org.eclipse.epf.uma.Roadmap;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.SupportingMaterial;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.Template;
import org.eclipse.epf.uma.TermDefinition;
import org.eclipse.epf.uma.Tool;
import org.eclipse.epf.uma.ToolMentor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.Whitepaper;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductType;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.forms.editor.FormEditor;

/**
 * Class for Guidance tab page in the content element editor.
 * Class ContentElementGuidancePage replaces CategoryGuidancePage and handles
 * all contentelement's guidance tab feature.  
 * 
 * @author Shashidhar Kannoori
 * @author Kelvin Low
 * @author Shilpa Toraskar
 * @since 1.0
 * 
 */
public class ContentElementGuidancePage extends AssociationFormPage {

	private static final String FORM_PAGE_ID = "categoryGuidancesPage"; //$NON-NLS-1$

	/**
	 * Creates a new instance.
	 */
	public ContentElementGuidancePage(FormEditor editor) {
		super(editor, FORM_PAGE_ID, AuthoringUIText.GUIDANCE_PAGE_TITLE);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) {
		super.init(site, input);
		setAllowChange1(true);
		setAllowChange2(true);
		setUseCategory2(false);
		setUseCategory3(false);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#initContentProviderSelected()
	 */
	protected void initContentProviderSelected() {
		contentProviderSelected = new AdapterFactoryContentProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()) {
			public Object[] getElements(Object object) {
				List list = MethodElementUtil
						.getSelectedGuidances(contentElement);
				List local = new ArrayList();
				for (Iterator it = list.iterator(); it.hasNext();) {
					Object obj = it.next();
					if (!(obj instanceof Practice
							|| (obj instanceof ToolMentor && contentElement instanceof Tool) || obj
							.equals(contentElement
									.getVariabilityBasedOnElement()))) {
						local.add(obj);
					}
				}
				return local.toArray();
			}
		};
		viewer_selected.setContentProvider(contentProviderSelected);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#addItemsToModel1(ArrayList)
	 */
	protected void addItemsToModel1(ArrayList addItems) {
		// Update the model.
		IActionManager actionMgr = editor.getActionManager();
		if (!addItems.isEmpty()) {
			for (Iterator it = addItems.iterator(); it.hasNext();) {
				Guidance item = (Guidance) it.next();

				// Consolidating the separate form page code
				// to accomodate better filtering.
				if (contentElement instanceof Task) {
//					if (item instanceof Estimate) {
//						editor.getActionManager().doAction(IActionManager.SET,
//								contentElement,
//								UmaPackage.eINSTANCE.getTask_Estimate(),
//								(Estimate) item, -1);
//					} else 
					if (item instanceof ToolMentor) {
						actionMgr.doAction(IActionManager.ADD,
								contentElement,
								UmaPackage.eINSTANCE.getTask_ToolMentors(),
								(ToolMentor) item, -1);
						continue;
					} else if (item instanceof EstimationConsiderations) {
						actionMgr.doAction(IActionManager.ADD, contentElement,
								UmaPackage.eINSTANCE.getTask_EstimationConsiderations(),
								item, -1);
						continue;
					}
				}
				// In case of WorkProduct, WorkProduct is associated to ToolMentor,
				// Estimate, Report and Template guidance
				if (contentElement instanceof WorkProduct) {
					if (item instanceof Template) {
						actionMgr
								.doAction(IActionManager.ADD, contentElement,
										UmaPackage.eINSTANCE
												.getWorkProduct_Templates(),
										item, -1);
						continue;
					} else if (item instanceof ToolMentor) {
						actionMgr
								.doAction(IActionManager.ADD, contentElement,
										UmaPackage.eINSTANCE
												.getWorkProduct_ToolMentors(),
										item, -1);
						continue;
					} else if (item instanceof Report) {
						actionMgr.doAction(IActionManager.ADD, contentElement,
								UmaPackage.eINSTANCE.getWorkProduct_Reports(),
								item, -1);
						continue;
					} 
//					else if (item instanceof Estimate) {
//						actionMgr.doAction(IActionManager.SET, contentElement,
//								UmaPackage.eINSTANCE.getWorkProduct_Estimate(),
//								item, -1);
//					}
					else if (item instanceof EstimationConsiderations) {
						actionMgr.doAction(IActionManager.ADD, contentElement,
								UmaPackage.eINSTANCE.getWorkProduct_EstimationConsiderations(),
								item, -1);
						continue;
					}
				}

				// Guidance for content element.
				if (item instanceof Checklist) {
					editor.getActionManager()
							.doAction(
									IActionManager.ADD,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Checklists(),
									(Checklist) item, -1);
					continue;
				} else if (item instanceof Concept) {
					editor.getActionManager().doAction(
							IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_ConceptsAndPapers(),
							(Concept) item, -1);
					continue;
				} else if (item instanceof Example) {
					editor.getActionManager().doAction(IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Examples(),
							(Example) item, -1);
					continue;
				} else if (item instanceof SupportingMaterial) {
					editor.getActionManager().doAction(
							IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_SupportingMaterials(),
							(SupportingMaterial) item, -1);
					continue;
				} else if (item instanceof Guideline) {
					editor.getActionManager()
							.doAction(
									IActionManager.ADD,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Guidelines(),
									(Guideline) item, -1);
					continue;
				} else if (item instanceof ReusableAsset) {
					editor.getActionManager().doAction(IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Assets(),
							(ReusableAsset) item, -1);
					continue;
				} else {
					AuthoringUIPlugin
							.getDefault()
							.getLogger()
							.logError(
									"Unable to add guidance " + item.getType().getName() + ":" + item.getName() + //$NON-NLS-1$ //$NON-NLS-2$
											"to " //$NON-NLS-1$
											+ contentElement.getType()
													.getName()
											+ ":" + contentElement.getName()); //$NON-NLS-1$ 
				}
			}
			setDirty(true);
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#removeItemsFromModel1(ArrayList)
	 */
	protected void removeItemsFromModel1(ArrayList rmItems) {
		// Update the model.
		IActionManager actionMgr = editor.getActionManager();
		if (!rmItems.isEmpty()) {
			for (Iterator it = rmItems.iterator(); it.hasNext();) {
				Guidance item = (Guidance) it.next();

				// In case of Task, Task is associated to ToolMentor and
				// Estimate guidance
				if (contentElement instanceof Task) {
					if (item instanceof ToolMentor) {
						editor.getActionManager().doAction(
								IActionManager.REMOVE, contentElement,
								UmaPackage.eINSTANCE.getTask_ToolMentors(),
								item, -1);
						continue;
					} 
//					else if (item instanceof Estimate) {
//						editor.getActionManager().doAction(IActionManager.SET,
//								contentElement,
//								UmaPackage.eINSTANCE.getTask_Estimate(), null,
//								-1);
//					}
					else if (item instanceof EstimationConsiderations) {
						editor.getActionManager().doAction(IActionManager.REMOVE,
								contentElement,
								UmaPackage.eINSTANCE.getTask_EstimationConsiderations(), item,
								-1);
						continue;
					}
				}
				// In case of WorkProduct, WorkProduct is associated to ToolMentor,
				// Estimate, Report and Template guidance
				if (contentElement instanceof WorkProduct) {
					if (item instanceof Report) {
						actionMgr.doAction(IActionManager.REMOVE,
								contentElement, UmaPackage.eINSTANCE
										.getWorkProduct_Reports(), item, -1);
						continue;
					} else if (item instanceof Template) {
						actionMgr.doAction(IActionManager.REMOVE,
								contentElement, UmaPackage.eINSTANCE
										.getWorkProduct_Templates(), item, -1);
						continue;
					} else if (item instanceof ToolMentor) {
						actionMgr
								.doAction(IActionManager.REMOVE,
										contentElement, UmaPackage.eINSTANCE
												.getWorkProduct_ToolMentors(),
										item, -1);
						continue;
					} 
//					else if (item instanceof Estimate) {
//						actionMgr.doAction(IActionManager.SET, contentElement,
//								UmaPackage.eINSTANCE.getWorkProduct_Estimate(),
//								null, -1);
//					}
					else if (item instanceof EstimationConsiderations) {
						editor.getActionManager().doAction(IActionManager.REMOVE,
								contentElement,
								UmaPackage.eINSTANCE.getWorkProduct_EstimationConsiderations(), item,
								-1);
						continue;
					}
				}
				// Guidance for the method element.
				if (item instanceof Checklist) {
					editor.getActionManager()
							.doAction(
									IActionManager.REMOVE,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Checklists(),
									item, -1);
					continue;
				} else if (item instanceof Concept) {
					editor.getActionManager().doAction(
							IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_ConceptsAndPapers(),
							(Concept) item, -1);
					continue;
				} else if (item instanceof Example) {
					editor.getActionManager().doAction(IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Examples(),
							(Example) item, -1);
					continue;
				} else if (item instanceof SupportingMaterial) {
					editor.getActionManager().doAction(
							IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_SupportingMaterials(),
							(SupportingMaterial) item, -1);
					continue;
				} else if (item instanceof Guideline) {
					editor.getActionManager()
							.doAction(
									IActionManager.REMOVE,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Guidelines(),
									(Guideline) item, -1);
					continue;
				} else if (item instanceof ReusableAsset) {
					editor.getActionManager().doAction(IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Assets(),
							(ReusableAsset) item, -1);
					continue;
				} else {
					AuthoringUIPlugin
							.getDefault()
							.getLogger()
							.logError(
									"Unable to remove guidance " + item.getType().getName() + ":" + item.getName() + //$NON-NLS-1$ //$NON-NLS-2$
											"from " //$NON-NLS-1$
											+ contentElement.getType()
													.getName()
											+ ":" + contentElement.getName()); //$NON-NLS-1$ 
				}
			}
			setDirty(true);
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.DescriptionFormPage#getContentElement()
	 */
	protected Object getContentElement() {
		return contentElement;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.DescriptionFormPage#getTabString()
	 */
	protected String getTabString() {
		return FilterConstants.GUIDANCE;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.DescriptionFormPage#getFilter()
	 */
	protected IFilter getFilter() {
		return filter = new GuidanceFilter();
	}

	/**
	 * 
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#getFilterTypes()
	 *      Types are returned in order to display in the filter dialog for
	 *      search based on type.
	 */
	protected String[] getFilterTypes() {
		
		String[] str;
		if (contentElement instanceof Task) {
			str = new String[11];
		} else if (contentElement instanceof WorkProduct) {
			str = new String[13];
		} else
			str = new String[9];
		int i = 0;
		str[i++] = FilterConstants.GUIDANCE;
		str[i++] = FilterConstants.space + FilterConstants.CHECKLISTS;
		str[i++] = FilterConstants.space + FilterConstants.CONCEPTS;
		str[i++] = FilterConstants.space + FilterConstants.EXAMPLES;
		str[i++] = FilterConstants.space + FilterConstants.GUIDELINES;
		str[i++] = FilterConstants.space + FilterConstants.REUSABLE_ASSETS;
		str[i++] = FilterConstants.space + FilterConstants.SUPPORTING_MATERIALS;
		if (contentElement instanceof Task) {
			str[i++] = FilterConstants.space + FilterConstants.TOOL_MENTORS;
			str[i++] = FilterConstants.space + FilterConstants.ESTIMATE_CONSIDERATIONS;
			// TODO Estimate contentelement
		} else if (contentElement instanceof WorkProduct) {
			str[i++] = FilterConstants.space + FilterConstants.REPORTS;
			str[i++] = FilterConstants.space + FilterConstants.TEMPLATES;
			str[i++] = FilterConstants.space + FilterConstants.TOOL_MENTORS;
			str[i++] = FilterConstants.space + FilterConstants.ESTIMATE_CONSIDERATIONS;
			// TODO Estimate contentelement
		}
		str[i++] = FilterConstants.CONTENT_PACKAGES;
		str[i++] = FilterConstants.METHO_PLUGINS;
		return str;
	}
	
	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#getMultipleSelectDescription(int)
	 */
	protected String getMultipleSelectDescription(int count) {
		return super.getMultipleSelectDescription(count, AuthoringUIResources.categoryGuidancesPage_multipleSelectDescription);
	}
	
	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#getSectionDescription()
	 */
	protected String getSectionDescription() {
		
		if(contentElement instanceof RoleSet){
			return AuthoringUIResources.rolesets_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Discipline){
			return AuthoringUIResources.disciplines_guidancepage_sectiondescription;
		}
		if(contentElement instanceof WorkProductType){
			return AuthoringUIResources.workproducttypes_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Domain){
			return AuthoringUIResources.domains_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Tool){
			return AuthoringUIResources.tools_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Role){
			return AuthoringUIResources.roleGuidancePage_sectionDescription;
		}
		if(contentElement instanceof Task){
			return AuthoringUIResources.taskGuidancePage_sectionDescription;
		}
		if(contentElement instanceof WorkProduct){
			return AuthoringUIResources.workProductGuidancePage_sectionDescription;
		}
		if(contentElement instanceof Tool){
			return AuthoringUIResources.tools_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Whitepaper){
			return AuthoringUIResources.whitepaper_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Concept){
			return AuthoringUIResources.concept_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Checklist){
			return AuthoringUIResources.checklist_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Example){
			return AuthoringUIResources.example_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Guideline){
			return AuthoringUIResources.guideline_guidancepage_sectiondescription;
		}
		if(contentElement instanceof SupportingMaterial){
			return AuthoringUIResources.supportingmaterial_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Roadmap){
			return AuthoringUIResources.roadmap_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Practice){
			return AuthoringUIResources.practice_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Report){
			return AuthoringUIResources.report_guidancepage_sectiondescription;
		}
		if(contentElement instanceof ReusableAsset){
			return AuthoringUIResources.reusableasset_guidancepage_sectiondescription;
		}
		if(contentElement instanceof Template){
			return AuthoringUIResources.template_guidancepage_sectiondescription;
		}
		if(contentElement instanceof TermDefinition){
			return AuthoringUIResources.termdefinition_guidancepage_sectiondescription;
		}
		if(contentElement instanceof EstimationConsiderations){
			return AuthoringUIResources.estimationconsideration_guidancepage_sectiondescription;
		}
		if(contentElement instanceof ToolMentor){
			return AuthoringUIResources.toolmentor_guidancepage_sectiondescription;
		}
		if(contentElement instanceof CustomCategory){
			return AuthoringUIResources.customcategory_guidancepage_sectiondescription;
		}
		
		if(contentElement != null)
			return AuthoringUIResources.bind(AuthoringUIResources.categoryGuidancesPage_sectionDescription, contentElement.getType().getName().toLowerCase());
		
		return null;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#getSectionName()
	 */
	protected String getSectionName() {
		return AuthoringUIResources.categoryGuidancesPage_sectionName;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#getSelectedLabel()
	 */
	protected String getSelectedLabel() {
		return AuthoringUIResources.categoryGuidancesPage_selectedLabel;
	}
	
	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#getSelectedLabel2()
	 */
	protected String getSelectedLabel2() {
		return AuthoringUIResources.categoryGuidancesPage_selectedLabel;
	}
	
	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#getSelectedLabel3()
	 */
	protected String getSelectedLabel3() {
		return AuthoringUIResources.categoryGuidancesPage_selectedLabel;
	}


}
