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.ui.forms.editor.init(IEditorSite, 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) {
						editor.getActionManager().doAction(IActionManager.ADD,
								contentElement,
								UmaPackage.eINSTANCE.getTask_ToolMentors(),
								(ToolMentor) item, -1);
					}else if (item instanceof EstimationConsiderations) {
						actionMgr.doAction(IActionManager.ADD, contentElement,
								UmaPackage.eINSTANCE.getTask_EstimationConsiderations(),
								item, -1);
					}
				}
				// 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);
					} else if (item instanceof ToolMentor) {
						actionMgr
								.doAction(IActionManager.ADD, contentElement,
										UmaPackage.eINSTANCE
												.getWorkProduct_ToolMentors(),
										item, -1);
					} else if (item instanceof Report) {
						actionMgr.doAction(IActionManager.ADD, contentElement,
								UmaPackage.eINSTANCE.getWorkProduct_Reports(),
								item, -1);
					} 
//					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);
					}
				}

				// Guidance for content element.
				if (item instanceof Checklist) {
					editor.getActionManager()
							.doAction(
									IActionManager.ADD,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Checklists(),
									(Checklist) item, -1);
				} else if (item instanceof Concept) {
					editor.getActionManager().doAction(
							IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_ConceptsAndPapers(),
							(Concept) item, -1);
				} else if (item instanceof Example) {
					editor.getActionManager().doAction(IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Examples(),
							(Example) item, -1);
				} else if (item instanceof SupportingMaterial) {
					editor.getActionManager().doAction(
							IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_SupportingMaterials(),
							(SupportingMaterial) item, -1);
				} else if (item instanceof Guideline) {
					editor.getActionManager()
							.doAction(
									IActionManager.ADD,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Guidelines(),
									(Guideline) item, -1);
				} else if (item instanceof ReusableAsset) {
					editor.getActionManager().doAction(IActionManager.ADD,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Assets(),
							(ReusableAsset) item, -1);
				} 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$ //$NON-NLS-2$
				}
			}
			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);
					} 
//					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);
					}
				}
				// 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);
					} else if (item instanceof Template) {
						actionMgr.doAction(IActionManager.REMOVE,
								contentElement, UmaPackage.eINSTANCE
										.getWorkProduct_Templates(), item, -1);
					} else if (item instanceof ToolMentor) {
						actionMgr
								.doAction(IActionManager.REMOVE,
										contentElement, UmaPackage.eINSTANCE
												.getWorkProduct_ToolMentors(),
										item, -1);
					} 
//					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);
					}
				}
				// Guidance for the method element.
				if (item instanceof Checklist) {
					editor.getActionManager()
							.doAction(
									IActionManager.REMOVE,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Checklists(),
									item, -1);
				} else if (item instanceof Concept) {
					editor.getActionManager().doAction(
							IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_ConceptsAndPapers(),
							(Concept) item, -1);
				} else if (item instanceof Example) {
					editor.getActionManager().doAction(IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Examples(),
							(Example) item, -1);
				} else if (item instanceof SupportingMaterial) {
					editor.getActionManager().doAction(
							IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE
									.getContentElement_SupportingMaterials(),
							(SupportingMaterial) item, -1);
				} else if (item instanceof Guideline) {
					editor.getActionManager()
							.doAction(
									IActionManager.REMOVE,
									contentElement,
									UmaPackage.eINSTANCE
											.getContentElement_Guidelines(),
									(Guideline) item, -1);
				} else if (item instanceof ReusableAsset) {
					editor.getActionManager().doAction(IActionManager.REMOVE,
							contentElement,
							UmaPackage.eINSTANCE.getContentElement_Assets(),
							(ReusableAsset) item, -1);
				} 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$ //$NON-NLS-2$
				}
			}
			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();
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @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;
	}
	
	protected String getMultipleSelectDescription(int count) {
		return super.getMultipleSelectDescription(count, AuthoringUIResources.categoryGuidancesPage_multipleSelectDescription);
	}
	
	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;
	}

	protected String getSectionName() {
		return AuthoringUIResources.categoryGuidancesPage_sectionName;
	}

	protected String getSelectedLabel() {
		return AuthoringUIResources.categoryGuidancesPage_selectedLabel;
	}
	
	protected String getSelectedLabel2() {
		return AuthoringUIResources.categoryGuidancesPage_selectedLabel;
	}
	
	protected String getSelectedLabel3() {
		return AuthoringUIResources.categoryGuidancesPage_selectedLabel;
	}


}
