/*******************************************************************************
 * Copyright (c) 2004, 2015 Tasktop Technologies and others.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * https://www.eclipse.org/legal/epl-2.0
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.bugzilla.ui.editor;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.commons.workbench.WorkbenchUtil;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCustomField;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaOperation;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryConnector;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryResponse;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaStatus;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaTaskDataHandler;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaUserMatchResponse;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaVersion;
import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration;
import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider;
import org.eclipse.mylyn.internal.tasks.ui.editors.PersonAttributeEditor;
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorActionPart;
import org.eclipse.mylyn.tasks.core.RepositoryResponse;
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMetaData;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelEvent;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelListener;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobEvent;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.keys.IBindingService;

/**
 * @author Rob Elves
 * @author Frank Becker
 * @since 3.0
 */
public class BugzillaTaskEditorPage extends AbstractTaskEditorPage {

	public static final String ID_PART_BUGZILLA_PLANNING = "org.eclipse.mylyn.bugzilla.ui.editors.part.planning"; //$NON-NLS-1$

	public static final String ID_PART_BUGZILLA_FLAGS = "org.eclipse.mylyn.bugzilla.ui.editors.part.flags"; //$NON-NLS-1$

	public static final String PATH_FLAGS = "flags"; //$NON-NLS-1$

	private final Map<TaskAttribute, AbstractAttributeEditor> attributeEditorMap;

	private TaskDataModelListener productListener;

	private final List<ControlDecoration> errorDecorations = new ArrayList<ControlDecoration>();

	private final List<PersonAttributeEditor> editorsWithError = new ArrayList<PersonAttributeEditor>(3);

	public BugzillaTaskEditorPage(TaskEditor editor) {
		this(editor, BugzillaCorePlugin.CONNECTOR_KIND);
	}

	/**
	 * Call this constructor if extending the Bugzilla connector
	 *
	 * @param editor
	 * @param connectorKind
	 */
	public BugzillaTaskEditorPage(TaskEditor editor, String connectorKind) {
		super(editor, connectorKind);
		this.attributeEditorMap = new HashMap<TaskAttribute, AbstractAttributeEditor>();
		setNeedsPrivateSection(true);
		setNeedsSubmitButton(true);
	}

	@Override
	protected Set<TaskEditorPartDescriptor> createPartDescriptors() {
		Set<TaskEditorPartDescriptor> descriptors = super.createPartDescriptors();
		boolean hasPartComments = false;
		boolean hasPartNewComment = false;
		boolean hasPartDescription = false;
		// remove unnecessary default editor parts
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_PEOPLE)) {
				descriptors.remove(taskEditorPartDescriptor);
				break;
			}
		}
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_COMMENTS)) {
				descriptors.remove(taskEditorPartDescriptor);
				hasPartComments = true;
				break;
			}
		}
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_NEW_COMMENT)) {
				descriptors.remove(taskEditorPartDescriptor);
				hasPartNewComment = true;
				break;
			}
		}
		for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
			if (taskEditorPartDescriptor.getId().equals(ID_PART_DESCRIPTION)) {
				descriptors.remove(taskEditorPartDescriptor);
				hasPartDescription = true;
				break;
			}
		}

		// Add Bugzilla Planning part
		try {
			TaskData data = TasksUi.getTaskDataManager().getTaskData(getTask());
			if (data != null) {
				// Add Bugzilla Flag part
				Map<String, TaskAttribute> attributes = data.getRoot().getAttributes();
				for (TaskAttribute attribute : attributes.values()) {
					if (BugzillaAttribute.KIND_FLAG.equals(attribute.getMetaData().getKind())) {
						descriptors.add(new TaskEditorPartDescriptor(ID_PART_BUGZILLA_FLAGS) {
							@Override
							public AbstractTaskEditorPart createPart() {
								return new BugzillaFlagPart();
							}
						}.setPath(ID_PART_ATTRIBUTES + "/" + PATH_FLAGS)); //$NON-NLS-1$
						break;
					}
				}

				TaskAttribute attrEstimatedTime = data.getRoot()
						.getMappedAttribute(BugzillaAttribute.ESTIMATED_TIME.getKey());
				if (attrEstimatedTime != null) {
					descriptors.add(new TaskEditorPartDescriptor(ID_PART_BUGZILLA_PLANNING) {
						@Override
						public AbstractTaskEditorPart createPart() {
							return new BugzillaPlanningEditorPart();
						}
					}.setPath(ID_PART_ATTRIBUTES + "/" + PATH_PLANNING)); //$NON-NLS-1$
				}
			}
			if (hasPartDescription) {
				descriptors.add(new TaskEditorPartDescriptor(ID_PART_DESCRIPTION) {
					@Override
					public AbstractTaskEditorPart createPart() {
						BugzillaTaskEditorDescriptionPart part = new BugzillaTaskEditorDescriptionPart();
						if (getModel().getTaskData().isNew()) {
							part.setExpandVertically(true);
							part.setSectionStyle(ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED);
						}
						return part;
					}
				}.setPath(PATH_COMMENTS));

			}
			if (hasPartComments) {
				descriptors.add(new TaskEditorPartDescriptor(ID_PART_COMMENTS) {
					@Override
					public AbstractTaskEditorPart createPart() {
						return new BugzillaTaskEditorCommentPart();
					}
				}.setPath(PATH_COMMENTS));

			}
		} catch (CoreException e) {
			// ignore
		}

		if (hasPartNewComment) {
			// Add the updated Bugzilla new comment part
			descriptors.add(new TaskEditorPartDescriptor(ID_PART_NEW_COMMENT) {
				@Override
				public AbstractTaskEditorPart createPart() {
					return new BugzillaTaskEditorNewCommentPart();
				}
			}.setPath(PATH_COMMENTS));
		}
		// Add the updated Bugzilla people part
		descriptors.add(new TaskEditorPartDescriptor(ID_PART_PEOPLE) {
			@Override
			public AbstractTaskEditorPart createPart() {
				return new BugzillaPeoplePart();
			}
		}.setPath(PATH_PEOPLE));

		return descriptors;
	}

	@Override
	protected AttributeEditorFactory createAttributeEditorFactory() {
		AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite()) {
			@Override
			public AbstractAttributeEditor createEditor(String type, final TaskAttribute taskAttribute) {
				AbstractAttributeEditor editor;
				if (IBugzillaConstants.EDITOR_TYPE_KEYWORDS.equals(type)) {
					editor = new BugzillaKeywordAttributeEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_REMOVECC.equals(type)) {
					editor = new BugzillaCcAttributeEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_VOTES.equals(type)) {
					editor = new BugzillaVotesEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_FLAG.equals(type)) {
					editor = new FlagAttributeEditor(getModel(), taskAttribute);
				} else if (IBugzillaConstants.EDITOR_TYPE_SEEALSO.equals(type)) {
					editor = new BugzillaSeeAlsoAttributeEditor(getModel(), taskAttribute);
				} else {
					editor = super.createEditor(type, taskAttribute);
					if (TaskAttribute.TYPE_BOOLEAN.equals(type)) {
						editor.setDecorationEnabled(false);
					}
				}

				if (editor != null && taskAttribute.getId().startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) {
					editor.setLayoutHint(new LayoutHint(editor.getLayoutHint()) {

						@Override
						public int getPriority() {
							return super.getPriority() * 10;
						}
					});
				}

				TaskAttributeMetaData properties = taskAttribute.getMetaData();
				if (editor != null && IBugzillaConstants.EDITOR_TYPE_FLAG.equals(properties.getType())) {
					editor.setLayoutHint(new LayoutHint(editor.getLayoutHint()) {

						@Override
						public int getPriority() {
							return super.getPriority() * 5;
						}
					});
				}
				if (editor != null && BugzillaAttribute.NEWCC.getKey().equals(taskAttribute.getId())) {
					editor.setLayoutHint(new LayoutHint(RowSpan.SINGLE, ColumnSpan.SINGLE));
				}
				BugzillaTaskEditorPage.this.addToAttributeEditorMap(taskAttribute, editor);
				return editor;
			}
		};
		return factory;
	}

	@Override
	public void doSubmit() {
		TaskAttribute summaryAttribute = getModel().getTaskData().getRoot().getMappedAttribute(TaskAttribute.SUMMARY);
		if (summaryAttribute != null && summaryAttribute.getValue().length() == 0) {
			getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_short_summary_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart part = getPart(ID_PART_SUMMARY);
			if (part != null) {
				part.setFocus();
			}
			return;
		}

		TaskAttribute componentAttribute = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(BugzillaAttribute.COMPONENT.getKey());
		if (componentAttribute != null && componentAttribute.getValue().length() == 0) {
			getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_select_a_component_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart part = getPart(ID_PART_ATTRIBUTES);
			if (part != null) {
				part.setFocus();
			}
			return;
		}

		TaskAttribute descriptionAttribute = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(TaskAttribute.DESCRIPTION);
		if (descriptionAttribute != null && descriptionAttribute.getValue().length() == 0
				&& getModel().getTaskData().isNew()) {
			getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_description_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart descriptionPart = getPart(ID_PART_DESCRIPTION);
			if (descriptionPart != null) {
				descriptionPart.setFocus();
			}
			return;
		}
		TaskAttribute targetMilestoneAttribute = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(BugzillaAttribute.TARGET_MILESTONE.getKey());
		if (targetMilestoneAttribute != null && targetMilestoneAttribute.getValue().length() == 0
				&& getModel().getTaskData().isNew()) {
			getTaskEditor().setMessage(
					Messages.BugzillaTaskEditorPage_Please_enter_a_target_milestone_before_submitting,
					IMessageProvider.ERROR);
			AbstractTaskEditorPart descriptionPart = getPart(ID_PART_ATTRIBUTES);
			if (descriptionPart != null) {
				descriptionPart.setFocus();
			}
			return;
		}

		TaskAttribute attributeOperation = getModel().getTaskData()
				.getRoot()
				.getMappedAttribute(TaskAttribute.OPERATION);
		if (attributeOperation != null) {
			if ("duplicate".equals(attributeOperation.getValue())) { //$NON-NLS-1$
				TaskAttribute originalOperation = getModel().getTaskData()
						.getRoot()
						.getAttribute(TaskAttribute.PREFIX_OPERATION + attributeOperation.getValue());
				String inputAttributeId = originalOperation.getMetaData()
						.getValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID);
				if (inputAttributeId != null && !inputAttributeId.equals("")) { //$NON-NLS-1$
					TaskAttribute inputAttribute = attributeOperation.getTaskData()
							.getRoot()
							.getAttribute(inputAttributeId);
					if (inputAttribute != null) {
						String dupValue = inputAttribute.getValue();
						if (dupValue == null || dupValue.equals("")) { //$NON-NLS-1$
							getTaskEditor().setMessage(
									Messages.BugzillaTaskEditorPage_Please_enter_a_bugid_for_duplicate_of_before_submitting,
									IMessageProvider.ERROR);
							AbstractTaskEditorPart part = getPart(ID_PART_ACTIONS);
							if (part != null) {
								part.setFocus();
							}
							return;
						}
					}
				}
			}
		}

		if (getModel().getTaskData().isNew()) {
			TaskAttribute productAttribute = getModel().getTaskData()
					.getRoot()
					.getMappedAttribute(TaskAttribute.PRODUCT);
			if (productAttribute != null && productAttribute.getValue().length() > 0) {
				getModel().getTaskRepository().setProperty(IBugzillaConstants.LAST_PRODUCT_SELECTION,
						productAttribute.getValue());
			}
			TaskAttribute componentSelectedAttribute = getModel().getTaskData()
					.getRoot()
					.getMappedAttribute(TaskAttribute.COMPONENT);
			if (componentSelectedAttribute != null && componentSelectedAttribute.getValue().length() > 0) {
				getModel().getTaskRepository().setProperty(IBugzillaConstants.LAST_COMPONENT_SELECTION,
						componentSelectedAttribute.getValue());
			}
		}

		// Force the most recent known good token onto the outgoing task data to ensure submit
		// bug#263318
		TaskAttribute attrToken = getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.TOKEN.getKey());
		if (attrToken != null) {
			String tokenString = getModel().getTask().getAttribute(BugzillaAttribute.TOKEN.getKey());
			if (tokenString != null) {
				attrToken.setValue(tokenString);
			}
		}
		for (ControlDecoration decoration : errorDecorations) {
			decoration.hide();
			decoration.dispose();
		}
		errorDecorations.clear();
		editorsWithError.clear();
		if (!checkCanSubmit(IMessageProvider.ERROR)) {
			return;
		}
		getTaskEditor().setMessage("", IMessageProvider.NONE); //$NON-NLS-1$
		super.doSubmit();
	}

	@Override
	protected void createParts() {
		attributeEditorMap.clear();
		super.createParts();
		checkCanSubmit(IMessageProvider.INFORMATION);
	}

	@Override
	protected TaskDataModel createModel(TaskEditorInput input) throws CoreException {
		TaskDataModel model = super.createModel(input);
		productListener = new ProductSelectionListener();
		model.addModelListener(productListener);
		return model;
	}

	/**
	 * @since 3.1
	 */
	private void addToAttributeEditorMap(TaskAttribute attribute, AbstractAttributeEditor editor) {
		if (attributeEditorMap.containsKey(attribute)) {
			attributeEditorMap.remove(attribute);
		}
		attributeEditorMap.put(attribute, editor);
	}

	/**
	 * @since 3.1
	 */
	private AbstractAttributeEditor getEditorForAttribute(TaskAttribute attribute) {
		return attributeEditorMap.get(attribute);
	}

	private void refresh(TaskAttribute attributeComponent) {
		AbstractAttributeEditor editor = getEditorForAttribute(attributeComponent);
		if (editor != null) {
			try {
				editor.refresh();
			} catch (UnsupportedOperationException e) {
				// ignore
			}
		}
	}

	private class ProductSelectionListener extends TaskDataModelListener {
		@Override
		public void attributeChanged(TaskDataModelEvent event) {
			TaskAttribute taskAttribute = event.getTaskAttribute();
			if (taskAttribute != null) {
				if (taskAttribute.getId().equals(BugzillaAttribute.PRODUCT.getKey())) {
					RepositoryConfiguration repositoryConfiguration = null;
					try {
						BugzillaRepositoryConnector connector = (BugzillaRepositoryConnector) TasksUi
								.getRepositoryConnector(getModel().getTaskRepository().getConnectorKind());
						repositoryConfiguration = connector.getRepositoryConfiguration(getModel().getTaskRepository(),
								false, new NullProgressMonitor());
					} catch (CoreException e) {
						StatusHandler.log(new RepositoryStatus(getTaskRepository(), IStatus.ERROR,
								BugzillaUiPlugin.ID_PLUGIN, 0, "Failed to obtain repository configuration", e)); //$NON-NLS-1$
						getTaskEditor().setMessage("Problem occured when updating attributes", IMessageProvider.ERROR); //$NON-NLS-1$
						return;
					}

					TaskAttribute attributeComponent = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.COMPONENT.getKey());
					if (attributeComponent != null) {
						List<String> optionValues = repositoryConfiguration
								.getProductOptionValues(BugzillaAttribute.COMPONENT, taskAttribute.getValue());
						Collections.sort(optionValues);
						attributeComponent.clearOptions();
						for (String option : optionValues) {
							attributeComponent.putOption(option, option);
						}
						if (optionValues.size() > 0) {
							attributeComponent.setValue(optionValues.get(0));
						}
						refresh(attributeComponent);
					}

					TaskAttribute attributeTargetMilestone = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.TARGET_MILESTONE.getKey());
					if (attributeTargetMilestone != null) {
						List<String> optionValues = repositoryConfiguration
								.getProductOptionValues(BugzillaAttribute.TARGET_MILESTONE, taskAttribute.getValue());
						Collections.sort(optionValues);
						attributeTargetMilestone.clearOptions();
						for (String option : optionValues) {
							attributeTargetMilestone.putOption(option, option);
						}
						String defaultMilestones = repositoryConfiguration
								.getDefaultMilestones(taskAttribute.getValue());
						if (defaultMilestones != null) {
							attributeTargetMilestone.setValue(defaultMilestones);
						} else if (optionValues.size() == 1) {
							attributeTargetMilestone.setValue(optionValues.get(0));
						} else {
							attributeTargetMilestone.setValue("---"); //$NON-NLS-1$
						}
						refresh(attributeTargetMilestone);
					}

					TaskAttribute attributeVersion = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.VERSION.getKey());
					if (attributeVersion != null) {
						List<String> optionValues = repositoryConfiguration
								.getProductOptionValues(BugzillaAttribute.VERSION, taskAttribute.getValue());
						Collections.sort(optionValues);
						attributeVersion.clearOptions();
						for (String option : optionValues) {
							attributeVersion.putOption(option, option);
						}
						if (optionValues.size() == 1) {
							attributeVersion.setValue(optionValues.get(0));
						} else {
							attributeVersion.setValue("unspecified"); //$NON-NLS-1$
						}
						refresh(attributeVersion);
					}

					TaskAttribute attributeDefaultAssignee = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
					if (attributeDefaultAssignee != null) {
						attributeDefaultAssignee.setValue("1"); //$NON-NLS-1$
						refresh(attributeDefaultAssignee);
					}
					if (taskAttribute.getTaskData().isNew()) {
						BugzillaVersion bugzillaVersion = repositoryConfiguration.getInstallVersion();
						if (bugzillaVersion == null) {
							bugzillaVersion = BugzillaVersion.MIN_VERSION;
						}
						if (bugzillaVersion.compareMajorMinorOnly(BugzillaVersion.BUGZILLA_4_0) >= 0) {
							AbstractTaskEditorPart part = getPart(ID_PART_ACTIONS);
							boolean unconfirmedAllowed = repositoryConfiguration
									.getUnconfirmedAllowed(taskAttribute.getValue());
							TaskAttribute unconfirmedAttribute = taskAttribute.getTaskData().getRoot().getAttribute(
									TaskAttribute.PREFIX_OPERATION + BugzillaOperation.unconfirmed.toString());
							if (unconfirmedAttribute != null) {
								unconfirmedAttribute.getMetaData().setReadOnly(!unconfirmedAllowed);
							}
							if (part != null) {
								TaskEditorActionPart actionPart = (TaskEditorActionPart) part;
								actionPart.refreshOperations();
							}
						}
					}
/*
 * 					add confirm_product_change to avoid verification page on submit
 */
					TaskAttribute attributeConfirmeProductChange = taskAttribute.getTaskData()
							.getRoot()
							.getMappedAttribute(BugzillaAttribute.CONFIRM_PRODUCT_CHANGE.getKey());
					if (attributeConfirmeProductChange == null) {
						attributeConfirmeProductChange = BugzillaTaskDataHandler.createAttribute(
								taskAttribute.getTaskData().getRoot(), BugzillaAttribute.CONFIRM_PRODUCT_CHANGE);
					}
					if (attributeConfirmeProductChange != null) {
						attributeConfirmeProductChange.setValue("1"); //$NON-NLS-1$
					}
				}
			}
		}
	}

	@Override
	protected void handleTaskSubmitted(SubmitJobEvent event) {
		if (event.getJob().getStatus() != null) {
			switch (event.getJob().getStatus().getCode()) {
			case BugzillaStatus.ERROR_CONFIRM_MATCH:
			case BugzillaStatus.ERROR_MATCH_FAILED:
				showError((BugzillaStatus) event.getJob().getStatus());
				return;
			}
		}
		if (event.getJob().getResponse() != null
				&& event.getJob().getResponse() instanceof BugzillaRepositoryResponse) {
			final RepositoryResponse response = event.getJob().getResponse();
			if (response instanceof BugzillaRepositoryResponse) {
				final BugzillaRepositoryResponse bugzillaResponse = (BugzillaRepositoryResponse) response;
				if (bugzillaResponse.getResponseData().size() > 0) {
					getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Changes_Submitted_Message,
							IMessageProvider.INFORMATION, new HyperlinkAdapter() {
								@Override
								public void linkActivated(HyperlinkEvent event) {
									showSubmitResponse(bugzillaResponse);
								}

							});
				} else {
					getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Changes_Submitted_Message,
							IMessageProvider.INFORMATION);
				}
			}
		} else {
			super.handleTaskSubmitted(event);
		}
	}

	@Override
	public void refresh() {
		super.refresh();
		checkCanSubmit(IMessageProvider.INFORMATION);
	}

	private boolean checkCanSubmit(final int type) {
		final TaskRepository taskRepository = getModel().getTaskRepository();
		String username = taskRepository.getUserName();
		if (username == null || username.length() == 0) {
			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
				public void run() {
					getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Anonymous_can_not_submit_Tasks, type,
							new HyperlinkAdapter() {
								@Override
								public void linkActivated(HyperlinkEvent e) {
									TasksUiUtil.openEditRepositoryWizard(taskRepository);
									refresh();
								}
							});
				}
			});
			return false;
		}
		if (!getModel().getTaskData().isNew()) {
			TaskAttribute exporter = getModel().getTaskData()
					.getRoot()
					.getAttribute(BugzillaAttribute.EXPORTER_NAME.getKey());
			if (exporter == null || exporter.getValue().equals("")) { //$NON-NLS-1$
				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
					public void run() {
						getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_submit_disabled_please_refresh, type,
								new HyperlinkAdapter() {
									@Override
									public void linkActivated(HyperlinkEvent e) {
										TasksUiUtil.openEditRepositoryWizard(taskRepository);
										refresh();
									}
								});
					}
				});
				return false;
			}
		}
		return true;
	}

	private void showError(BugzillaStatus bugzillaStatus) {
		int count = 0;
		BugzillaUserMatchResponse response = bugzillaStatus.getUserMatchResponse();
		FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
		FieldDecoration fieldDecoration = registry.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
		FieldDecoration fieldDecorationWarning = registry.getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
		StringBuilder fields = new StringBuilder();
		StringBuilder detail = new StringBuilder();

		count += decorateControlsAndUpdateMessages(response.getAssignedToMsg(), response.getAssignedToProposals(),
				getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.ASSIGNED_TO.getKey()), fields, detail,
				fieldDecoration, fieldDecorationWarning);
		count += decorateControlsAndUpdateMessages(response.getQaContactMsg(), response.getQaContactProposals(),
				getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.QA_CONTACT.getKey()), fields, detail,
				fieldDecoration, fieldDecorationWarning);
		count += decorateControlsAndUpdateMessages(response.getNewCCMsg(), response.getNewCCProposals(),
				getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.NEWCC.getKey()), fields, detail,
				fieldDecoration, fieldDecorationWarning);
		updateTaskEditorPageMessageWithError(bugzillaStatus, detail.toString(), count == 1, fields.toString());
	}

	private int decorateControlsAndUpdateMessages(String message, List<String> proposals, TaskAttribute attribute,
			StringBuilder fields, StringBuilder detail, FieldDecoration fieldDecoration,
			FieldDecoration fieldDecorationWarning) {
		if (attribute == null || (message == null && proposals.size() == 0)) {
			return 0;
		}
		Map<String, String> newPersonProposalMap = new HashMap<String, String>();
		if (fields.length() > 0) {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_N,
					attribute.getMetaData().getLabel()));
		} else {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_1,
					attribute.getMetaData().getLabel()));
		}
		detail.append(attribute.getMetaData().getLabel() + "\n"); //$NON-NLS-1$
		if (message != null && !message.equals("")) { //$NON-NLS-1$
			detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, message));
		} else {
			for (String proposalValue : proposals) {
				detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, proposalValue));
				newPersonProposalMap.put(proposalValue, proposalValue);
			}
		}
		AbstractAttributeEditor editor = getEditorForAttribute(attribute);
		if (editor != null) {
			decorateEditorWithError(fieldDecoration, fieldDecorationWarning, message, newPersonProposalMap, editor);
		}
		return 1;
	}

	private int decorateControlsAndUpdateMessages(String message, Map<String, List<String>> proposals,
			TaskAttribute attribute, StringBuilder fields, StringBuilder detail, FieldDecoration fieldDecoration,
			FieldDecoration fieldDecorationWarning) {
		if (attribute == null || (message == null && proposals.size() == 0)) {
			return 0;
		}
		Map<String, String> newPersonProposalMap = new HashMap<String, String>();
		if (fields.length() > 0) {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_N,
					attribute.getMetaData().getLabel()));
		} else {
			fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_1,
					attribute.getMetaData().getLabel()));
		}
		detail.append(attribute.getMetaData().getLabel() + "\n"); //$NON-NLS-1$
		if (message != null && !message.equals("")) { //$NON-NLS-1$
			detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, message));
		} else {
			for (String key : proposals.keySet()) {
				detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Proposal_Detail, key));

				for (String proposalValue : proposals.get(key)) {
					detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, proposalValue));
					newPersonProposalMap.put(proposalValue, proposalValue);
				}
			}
		}
		AbstractAttributeEditor editor = getEditorForAttribute(attribute);
		if (editor != null) {
			decorateEditorWithError(fieldDecoration, fieldDecorationWarning, message, newPersonProposalMap, editor);
		}
		return 1;
	}

	/**
	 * @param bugzillaStatus
	 * @param resultDetail
	 * @param oneError
	 * @param fieldString
	 */
	private void updateTaskEditorPageMessageWithError(BugzillaStatus bugzillaStatus, String resultDetail,
			boolean oneError, String fieldString) {
		String resultString;
		final String titleString;
		switch (bugzillaStatus.getCode()) {
		case BugzillaStatus.ERROR_CONFIRM_MATCH:
			if (oneError) {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_one,
						Messages.BugzillaTaskEditorPage_Confirm, fieldString);
			} else {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_more,
						Messages.BugzillaTaskEditorPage_Confirm, fieldString);
			}
			titleString = Messages.BugzillaTaskEditorPage_ConfirmDetailTitle;
			break;
		case BugzillaStatus.ERROR_MATCH_FAILED:
			if (oneError) {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_one,
						Messages.BugzillaTaskEditorPage_Error, fieldString);
			} else {
				resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_more,
						Messages.BugzillaTaskEditorPage_Error, fieldString);
			}
			titleString = Messages.BugzillaTaskEditorPage_ErrorDetailTitle;
			break;
		default:
			throw new RuntimeException("unexpected BugzillaStatus: " + bugzillaStatus.getCode()); //$NON-NLS-1$
		}

		final String resultDetailString = resultDetail;
		getTaskEditor().setMessage(resultString, IMessageProvider.ERROR, new HyperlinkAdapter() {
			@Override
			public void linkActivated(HyperlinkEvent event) {
				BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(WorkbenchUtil.getShell(),
						titleString, resultDetailString);
				dialog.open();
			}
		});
	}

	/**
	 * @param fieldDecoration
	 * @param message
	 * @param newPersonProposalMap
	 * @param editor
	 */
	private void decorateEditorWithError(FieldDecoration fieldDecoration, FieldDecoration fieldDecorationWarning,
			String message, Map<String, String> newPersonProposalMap, AbstractAttributeEditor editor) {
		final Control control = editor.getControl();

		final ControlDecoration decoration = new ControlDecoration(control, SWT.LEFT | SWT.DOWN);
		decoration.setImage(
				newPersonProposalMap.size() == 1 ? fieldDecorationWarning.getImage() : fieldDecoration.getImage());
		IBindingService bindingService = PlatformUI.getWorkbench().getService(IBindingService.class);
		if (message != null && !message.equals("")) { //$NON-NLS-1$
			decoration.setDescriptionText(message);
			errorDecorations.add(decoration);
		} else {
			decoration.setDescriptionText(
					NLS.bind(Messages.BugzillaTaskEditorPage_Content_Assist_for_Error_Available, bindingService
							.getBestActiveBindingFormattedFor(ContentAssistCommandAdapter.CONTENT_PROPOSAL_COMMAND)));
			errorDecorations.add(decoration);

			final PersonAttributeEditor personEditor = ((PersonAttributeEditor) editor);
			final PersonProposalProvider personProposalProvider = (PersonProposalProvider) personEditor
					.getContentAssistCommandAdapter().getContentProposalProvider();
			personProposalProvider.setErrorProposals(newPersonProposalMap);

			editorsWithError.add(personEditor);
			if (newPersonProposalMap.size() == 1) {
				personEditor.setValue(newPersonProposalMap.keySet().iterator().next());

			}
			personEditor.getText().addModifyListener(new ModifyListener() {

				public void modifyText(ModifyEvent e) {
					decoration.hide();
					errorDecorations.remove(decoration);
					decoration.dispose();
					personProposalProvider.setErrorProposals(null);
				}
			});
		}
	}

	/**
	 * @param bugzillaResponse
	 */
	private void showSubmitResponse(final BugzillaRepositoryResponse bugzillaResponse) {
		StringBuilder message = new StringBuilder();
		for (String iterable_map : bugzillaResponse.getResponseData().keySet()) {
			if (message.length() > 0) {
				message.append("\n"); //$NON-NLS-1$
			}
			message.append(NLS.bind(Messages.BugzillaTaskEditorPage_Bug_Line, iterable_map));
			Map<String, List<String>> responseMap = bugzillaResponse.getResponseData().get(iterable_map);
			for (String iterable_list : responseMap.keySet()) {
				message.append(NLS.bind(Messages.BugzillaTaskEditorPage_Action_Line, iterable_list));
				List<String> responseList = responseMap.get(iterable_list);
				for (String string : responseList) {
					message.append(NLS.bind(Messages.BugzillaTaskEditorPage_Email_Line, string));
				}
			}
		}
		BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(WorkbenchUtil.getShell(),
				Messages.BugzillaTaskEditorPage_submitted_Changes_Details, message.toString());
		dialog.open();
	}

}
