/*******************************************************************************
 * Copyright (c) 2010 SAP AG, Walldorf.
 * 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:
 *     SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.platform.discovery.ui.internal.view;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.platform.discovery.core.api.ISearchContext;
import org.eclipse.platform.discovery.core.api.SearchEvent;
import org.eclipse.platform.discovery.core.internal.IDestinationsManager;
import org.eclipse.platform.discovery.core.internal.ISearchConsoleView;
import org.eclipse.platform.discovery.core.internal.console.ISearchConsoleController;
import org.eclipse.platform.discovery.core.internal.console.ISearchConsoleControllerOutputView;
import org.eclipse.platform.discovery.runtime.api.GroupingHierarchy;
import org.eclipse.platform.discovery.runtime.api.ISearchDestination;
import org.eclipse.platform.discovery.runtime.api.ISearchParameters;
import org.eclipse.platform.discovery.runtime.api.ISearchSubdestination;
import org.eclipse.platform.discovery.runtime.api.SearchFailedException;
import org.eclipse.platform.discovery.runtime.api.SearchFailedForKnownReasonException;
import org.eclipse.platform.discovery.runtime.internal.DestinationCategoryNotFoundException;
import org.eclipse.platform.discovery.runtime.internal.ISearchProviderConfiguration;
import org.eclipse.platform.discovery.runtime.internal.ProviderNotFoundException;
import org.eclipse.platform.discovery.runtime.internal.SearchProviderConfigurationFactory;
import org.eclipse.platform.discovery.runtime.internal.model.descriptions.IDestinationCategoryDescription;
import org.eclipse.platform.discovery.runtime.internal.model.descriptions.IObjectTypeDescription;
import org.eclipse.platform.discovery.runtime.internal.model.descriptions.ISearchProviderDescription;
import org.eclipse.platform.discovery.ui.api.IGenericViewCustomization;
import org.eclipse.platform.discovery.ui.api.IMasterDiscoveryView;
import org.eclipse.platform.discovery.ui.api.ISearchConsoleCustomization;
import org.eclipse.platform.discovery.ui.api.ISearchParametersUI;
import org.eclipse.platform.discovery.ui.api.ISearchParametersUI.IConsoleContext;
import org.eclipse.platform.discovery.ui.api.IViewUiContext;
import org.eclipse.platform.discovery.ui.api.impl.DefaultSessionIds;
import org.eclipse.platform.discovery.ui.internal.SearchParametersUI;
import org.eclipse.platform.discovery.ui.internal.SlidingComposite;
import org.eclipse.platform.discovery.ui.internal.SlidingComposite.ORIENTATION;
import org.eclipse.platform.discovery.ui.internal.plugin.DiscoveryUIMessages;
import org.eclipse.platform.discovery.ui.internal.search.advancedparams.AdvancedSearchParamsDisplayer;
import org.eclipse.platform.discovery.ui.internal.search.advancedparams.IAdvancedSearchParamsDisplayer;
import org.eclipse.platform.discovery.ui.internal.util.ControlBackgroundImageManager;
import org.eclipse.platform.discovery.ui.internal.view.impl.AbstractDiscoveryView;
import org.eclipse.platform.discovery.ui.internal.view.impl.ITabbedSessionDisplayer;
import org.eclipse.platform.discovery.ui.internal.view.impl.SearchParameters;
import org.eclipse.platform.discovery.ui.internal.view.result.impl.ContributedUIFactory;
import org.eclipse.platform.discovery.ui.internal.view.result.impl.TabbedSessionDisplayer;
import org.eclipse.platform.discovery.util.internal.logging.ILogger;
import org.eclipse.platform.discovery.util.internal.logging.Logger;
import org.eclipse.platform.discovery.util.internal.property.IPropertyAttributeListener;
import org.eclipse.platform.discovery.util.internal.property.Property;
import org.eclipse.platform.discovery.util.internal.property.PropertyAttributeChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;


/**
 * The search console view implementation. The view consists of two parts - upper and bottom.<br>
 * The upper part contains UI components which will define the input parameters of the search process. This includes
 * <ul>
 * <li>the object types list</li>
 * <li>the search destinations selection component</li>
 * <li>the keywords text</li>
 * <li>the subdestinations selection button. It is disabled in case there are no subdestinations for the combination of the currently selected object type - destination - search provider</li>
 * <li>UI contributed by the active search provider defined by the combination object type - destination.</li>
 *</ul>
 * The upper part reveals its UI components consecutively according to what the user selects. Initially, only the object type list is displayed. When an object type is selected by the user, the destinations list appear and it contains the destinations which are relevant to the selected object type.
 * Once destinations are selected, the keywords text and the subdestinations selection button is displayed<br>
 * When the view is opened it starts in a "loading" state. Once it is ready to operate (e.g. all necessary listeners are registered by a controller) the {@link #initializationCompleted()} method should be invoked to put the the view in a "ready" state
 * 
 * @author Danail Branekov
 * 
 */
public class SearchConsoleView extends AbstractDiscoveryView<ISearchConsoleControllerOutputView, ISearchConsoleController> implements ISearchConsoleView, ICustomizableView, IMasterDiscoveryView, ISearchConsoleControllerOutputView
{	
	/**
	 * Constant for identifying the gap between UI controls in form layouts
	 */
	public static final int UI_IN_CONTROL_SPACING = 5;
	
	protected ISearchProviderSelector searchProviderSelector;
	
	private IAdvancedSearchParamsDisplayer advancedSearchParamsDisplayer;
	private ITabbedSessionDisplayer<ISearchContext> sdm;
	private IProgressMonitor viewProgressMonitor;
	private String defaultSessionId;
	
	private ISearchParametersUI searchParametersUI;
	private Button searchButton;

	private Hyperlink manageConfigurationHyperlink;
	private SlidingComposite slidingComposite;
	private Composite fixedSearchParamComposite;
	private Composite advancedSearchParamsComposite;
	
	private Composite bottomComposite;
	private Composite upperComposite;
	private final Cursor hyperlinkCursor;
	private final Property<Point> upperCompositeSizeProperty;
	private final Property<ORIENTATION> currentOrientation;
	
	private ControlBackgroundImageManager upperCompositeGradientManager;

	private ISearchConsoleController controller;

	private IDestinationsManager destManager;
	
	public SearchConsoleView()
	{
		super();
		upperCompositeSizeProperty = new Property<Point>();
		upperCompositeSizeProperty.set(new Point(0, 0));
		hyperlinkCursor = new Cursor(PlatformUI.getWorkbench().getDisplay(), SWT.CURSOR_HAND);
		this.currentOrientation = new Property<ORIENTATION>();
		this.currentOrientation.set(ORIENTATION.VERTICAL); //assume default value
	}
	
	@Override
	public void createPartControl(final Composite parent)
	{
		super.createPartControl(parent);
		slidingComposite = new SlidingComposite(parent, formToolkit)
		{
			@Override
			protected void configureUpperComposite(final Composite upperComposite)
			{
				SearchConsoleView.this.configureUpperComposite(upperComposite, getFormToolkit());
			};

			@Override
			protected void configureBottomComposite(Composite bottomComposite)
			{
				SearchConsoleView.this.bottomComposite = bottomComposite;
				sdm = createSessionsDisplayer();
				bottomComposite.setLayout(new FillLayout());
			}

			@Override
			protected void onOrientationChange(final ORIENTATION newOrientation)
			{
				currentOrientation.set(newOrientation);
			}

		};
		
		this.viewProgressMonitor = slidingComposite.getProgressMonitor();
		this.getProgressMonitor().beginTask(DiscoveryUIMessages.INITIALIZATION_IN_PROGRESS_TASK, IProgressMonitor.UNKNOWN);
		
		this.upperCompositeSizeProperty.registerValueListener(new IPropertyAttributeListener<Point>()
		{
			@Override
			public void attributeChanged(final PropertyAttributeChangedEvent<Point> event)
			{
				slidingComposite.upperCompositeSizeChanged(event);
			}
		}, false);

		fixedSearchParamComposite.addTraverseListener(new TraverseListener()
		{
			@Override
			public void keyTraversed(TraverseEvent e)
			{
				if (searchButton.isEnabled() && e.detail == SWT.TRAVERSE_RETURN)
				{
					search();
				}
			}
		});
		
		advancedSearchParamsDisplayer.registerSizePropertyChangeListener(new IPropertyAttributeListener<Point>()
		{
			@Override
			public void attributeChanged(PropertyAttributeChangedEvent<Point> event)
			{
				final Point newSize = computeUpperCompositeSize(fixedSearchParamComposite.getSize(), event.getNewAttribute(), searchButton.getSize(), currentOrientation.get());
				upperCompositeSizeProperty.set(newSize);
			}
		}, false);
		
		currentOrientation.registerValueListener(new OrientationChangedListener(), true);
		parent.layout(true, true);
		upperCompositeSizeProperty.set(upperComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
	}
	
	protected ITabbedSessionDisplayer<ISearchContext> createSessionsDisplayer() {
		final TabbedSessionDisplayer<ISearchContext> sd = new TabbedSessionDisplayer<ISearchContext>(bottomComposite, new ContributedUIFactory(SearchConsoleView.this), SWT.FLAT | SWT.MULTI);
		sd.getControl().setSelectionBackground(new Color[]{getGradientStart(), getGradientEnd()},new int [] { 80 } , true);
		return sd;
	}
	
	protected ISearchProviderConfiguration getSearchProviderConfiguration()
	{
		return new SearchProviderConfigurationFactory().getSearchProviderConfiguration(Platform.getExtensionRegistry());
	}

	@Override
	public void setFocus()
	{
		if(this.bottomComposite != null)
		{
			this.bottomComposite.setFocus();
		}
	}

	@Override
	public void showDestinationsCategories(List<IDestinationCategoryDescription> categories)
	{
		searchProviderSelector.setDestinations(categories);
	}

	@Override
	public void showObjectTypes(List<IObjectTypeDescription> objectTypes)
	{
		searchProviderSelector.setObjectTypes(objectTypes);
	}

	@Override
	public void showResult(final ISearchContext searchContext)
	{
		final String sessionId = searchContext.session().getId();
		if(searchContext.session().getId().equals(this.defaultSessionId))
		{
			sdm.setSessionUnclosable(sessionId);
		}
		
		sdm.display(searchContext.session());
		this.slidingComposite.notifyBottomCompositeContentChanged(DiscoveryUIMessages.SearchConsoleView_SearchFinished, DiscoveryUIMessages.SearchConsoleView_SearchResultsAvailable);
	}
	
	@Override
	public void registerViewCustomization(final IGenericViewCustomization customization)
	{
		if(!(customization instanceof ISearchConsoleCustomization))
		{
			throw new IllegalArgumentException("The view customization must be instance of ISearchConsoleCustomization"); //$NON-NLS-1$
		}
		
		super.registerViewCustomization(customization);
	}
	

	private void createHyperLink(final Composite parent, final FormToolkit formToolkit)
	{
		manageConfigurationHyperlink = new Hyperlink(parent, SWT.NONE );
		manageConfigurationHyperlink.setText(DiscoveryUIMessages.SearchConsoleView_MANAGED_CONFIGS_LINK);
		manageConfigurationHyperlink.setForeground(formToolkit.getHyperlinkGroup().getActiveForeground());
		manageConfigurationHyperlink.setUnderlined(true);
		manageConfigurationHyperlink.setCursor(hyperlinkCursor);
		
		manageConfigurationHyperlink.addHyperlinkListener(new IHyperlinkListener()
		{
			public void linkActivated(HyperlinkEvent e) {
				destManager.manageDestinations(parent.getShell(), searchProviderSelector.getActiveDestinationCategory());
			}
			
			public void linkEntered(HyperlinkEvent e) {
			}
			public void linkExited(HyperlinkEvent e) {
			}
		});
		
		final FormData linkFormData = new FormData();
		linkFormData.top = new FormAttachment(searchProviderSelector.getControl(), UI_IN_CONTROL_SPACING);
		linkFormData.right = new FormAttachment(100, -UI_IN_CONTROL_SPACING);
		manageConfigurationHyperlink.setLayoutData(linkFormData);

	}
	
	private void configureUpperComposite(final Composite upComposite, final FormToolkit formToolkit)
	{
		this.upperComposite = upComposite;
		this.upperComposite.setBackgroundMode(SWT.INHERIT_DEFAULT);
		upperCompositeGradientManager = createGradient(this.upperComposite);
		final int leftLabelsSize = getLongestLabelSize(getLeftSideLabels());
		
		fixedSearchParamComposite  = new Composite(this.upperComposite, SWT.NONE);
		fixedSearchParamComposite.setLayout(new FormLayout());
		fixedSearchParamComposite.setLayoutData(createFixedParamsFormData(currentOrientation.get()));
		
		final ISearchProviderSelector.IConsoleContext selectorContext = new ISearchProviderSelector.IConsoleContext() {
			
			@Override
			public int secondColumnLeftOffset() {
				return leftLabelsSize;
			}
			
			@Override
			public ISearchProviderConfiguration searchProviderConfiguration() {
				return getSearchProviderConfiguration();
			}
			
			@Override
			public void notifyComplete(boolean complete) {
				final ISearchProviderDescription selectedProvider = searchProviderSelector.getSelectedSearchProvider();
				final ISearchDestination selectedDestination = searchProviderSelector.getSelectedDestination();
				searchParametersUI.searchProviderSelected(selectedProvider);

				advancedSearchParamsDisplayer.update(getSelectedObjectType(), selectedDestination, getEnvironment(), uiContext());
				advancedSearchParamsComposite.setLayoutData(createAdvancedOptionsFormData(fixedSearchParamComposite, currentOrientation.get(), advancedSearchParamsDisplayer.isEnabled()));
				if (selectedDestination == null || getSelectedActiveSearchProviderDescription() == null)
				{
					controller.searchDestinationSelected(searchProviderSelector.getSelectedObjectType(), null);
				} else
				{
					controller.searchDestinationSelected(searchProviderSelector.getSelectedObjectType(), selectedDestination);
				}
				upperComposite.layout(true, true);
			}
		};
		
		searchProviderSelector = new SearchProviderSelector(fixedSearchParamComposite, formToolkit, selectorContext);
		searchProviderSelector.getControl().setLayoutData(createSearchProviderSelectorLayoutData());
		
		createHyperLink(fixedSearchParamComposite, formToolkit);
		createSearchParametersUI(fixedSearchParamComposite, formToolkit);
		
		advancedSearchParamsComposite =  new Composite(upperComposite , SWT.NONE);
		adaptAdvancedSearchParamsComposite(advancedSearchParamsComposite, fixedSearchParamComposite, false);		
		advancedSearchParamsDisplayer = createAdvancedSearchParamsDisplayer(advancedSearchParamsComposite, formToolkit);	
		
		searchButton = new Button(this.upperComposite, SWT.PUSH | SWT.FLAT);
		searchButton.setText(DiscoveryUIMessages.SEARCH_BUTTON_LABEL);
		FormData buttonData = createSearchButtonCompositeFormData(currentOrientation.get());
		searchButton.setLayoutData(buttonData);
		searchButton.setEnabled(false);
		
		installSearchButtonListener();
	
		upperComposite.layout();
	}
	
	private FormData createSearchProviderSelectorLayoutData() {
		final FormData data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(100, 0);
		return data;
	}

	private void createSearchParametersUI(final Composite parent, final FormToolkit toolkit)
	{
		final Composite searchParametersUIComposite = new Composite(parent, SWT.NONE);// formToolkit.createComposite(parent);
		searchParametersUIComposite.setLayoutData(createSearchParametersLayoutData());
		searchParametersUI = new SearchParametersUI();
		final IConsoleContext context = new IConsoleContext() {
			@Override
			public IObjectTypeDescription selectedObjectType() {
				return getSelectedObjectType();
			}
			
			@Override
			public ISearchProviderConfiguration searchProviderConfiguration() {
				return getSearchProviderConfiguration();
			}
			
			@Override
			public ISearchProviderDescription searchProvider() {
				return getSelectedActiveSearchProviderDescription();
			}
			
			@Override
			public ISearchDestination searchDestination() {
				return getSelectedDestination();
			}
			
			@Override
			public void notifySubdestinationActivationChange(ISearchSubdestination subDestination, boolean newActivationState) {
				getSearchProviderConfiguration().activateSubdestination(getSelectedObjectType(), getSelectedDestinationCategory(), getSelectedActiveSearchProviderDescription(), subDestination, newActivationState);
			}
			
			@Override
			public void notifyComplete(final boolean complete) {
				searchButton.setEnabled(complete);
			}
			
			@Override
			public IDestinationCategoryDescription destinationCategory() {
				return getSelectedDestinationCategory();
			}

			@Override
			public int secondColumnLeftOffset() {
				return getLongestLabelSize(getLeftSideLabels());
			}
		};
		searchParametersUI.createUI(searchParametersUIComposite, toolkit, context);
	}

	
	private FormData createSearchParametersLayoutData() {
		final FormData data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(100, 0);
		data.top = new FormAttachment(manageConfigurationHyperlink, UI_IN_CONTROL_SPACING);
		return data;
	}

	private void adjustUpperCompositeLayoutData(final ORIENTATION orientation)
	{
		fixedSearchParamComposite.setLayoutData(createFixedParamsFormData(orientation));
		searchButton.setLayoutData(createSearchButtonCompositeFormData(orientation));
		advancedSearchParamsComposite.setLayoutData(createAdvancedOptionsFormData(fixedSearchParamComposite, orientation, advancedSearchParamsDisplayer.isEnabled()));
	}
	
	private FormData createFixedParamsFormData(final ORIENTATION orientation)
	{
		final FormData fixedData = new FormData();
		fixedData.left = new FormAttachment(0, 0);
		if (orientation == ORIENTATION.VERTICAL)
		{
			fixedData.right = new FormAttachment(100, 0);
		}
		else
		{
			fixedData.width = fixedSearchParamComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
		}
		return fixedData;
	}
	
	private FormData createSearchButtonCompositeFormData(final ORIENTATION orientation)
	{
		final FormData buttonData = new FormData();
		if(orientation == ORIENTATION.VERTICAL){
			buttonData.top = new FormAttachment(advancedSearchParamsComposite, UI_IN_CONTROL_SPACING);
			buttonData.right = new FormAttachment(100, -UI_IN_CONTROL_SPACING);
		}
		else{
			buttonData.top = new FormAttachment(fixedSearchParamComposite, UI_IN_CONTROL_SPACING);
			buttonData.right = new FormAttachment(0, this.fixedSearchParamComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).x);
		}
		return buttonData;
	}

	/**
	 * @param enabled true if the custom parameters are enabled, false otherwise
	 */
	private FormData createAdvancedOptionsFormData(final Composite fixedSearchParamComposite, final ORIENTATION orientation, final boolean enabled) {
		final FormData fd = new FormData();
		if(orientation == ORIENTATION.VERTICAL){
			fd.top = new FormAttachment(fixedSearchParamComposite);
			fd.left = new FormAttachment(0, 0);
			fd.right = new FormAttachment(100, 0);
			fd.height = enabled ? SWT.DEFAULT : 0;
			fd.width = SWT.DEFAULT;
		}
		else{
			fd.top = new FormAttachment(0, 0);
			fd.left = new FormAttachment(fixedSearchParamComposite, UI_IN_CONTROL_SPACING);
			fd.right = new FormAttachment(100, 0);
			fd.width = enabled ? SWT.DEFAULT : 0;
			fd.height = SWT.DEFAULT;
		}
		
		return fd;
	}

	/**
	 * @param enabled <code>true</code> in case custom search parameters section is enabled, <code>false</code> otherwise
	 * @return
	 */
	private Composite adaptAdvancedSearchParamsComposite(Composite advancedSearchParamsComposite, Composite fixedSearchParamComposite, boolean enabled) {
		advancedSearchParamsComposite.setLayout(new FormLayout());
		final FormData fd = createAdvancedOptionsFormData(fixedSearchParamComposite, currentOrientation.get(), enabled);
		advancedSearchParamsComposite.setLayoutData(fd);
		return advancedSearchParamsComposite;
	}

	private void search()
	{
		try
		{
			final ISearchParameters params = new SearchParameters(getSelectedObjectType().getId(), getSelectedDestination(), searchParametersUI.getKeyword(), searchParametersUI.getGroupingHierarchy(), activeSubdestinations());
			advancedSearchParamsDisplayer.setParams(params);
			final SearchEvent searchEvent = new SearchEvent(params, DefaultSessionIds.mainSearchSessionId, DiscoveryUIMessages.SEARCH_RESULT_TAB, null);
			SearchConsoleView.this.controller.search(searchEvent);
		} catch (ProviderNotFoundException e1)
		{
			throw new IllegalStateException(e1);
		}
		catch(SearchFailedForKnownReasonException exc)
		{
			getEnvironment().errorHandler().showError(null, exc.getLocalizedMessage());
			logger().logDebug(exc.getMessage(), exc);
		}
		catch (SearchFailedException exc)
		{
			getEnvironment().errorHandler().handleException(exc);
		}
	}
	
	private ILogger logger()
	{
		return Logger.instance();
	}
	
	private Set<ISearchSubdestination> activeSubdestinations() throws ProviderNotFoundException
	{
		final Set<ISearchSubdestination> result = new HashSet<ISearchSubdestination>();
		final IObjectTypeDescription objectType = getSelectedObjectType();
		final IDestinationCategoryDescription category = getDestinationCategory(getSelectedDestination());
		final ISearchProviderDescription searchProvider = getSearchProviderConfiguration().getActiveSearchProvider(objectType, category);
		if(searchProvider == null)
		{
			return Collections.emptySet();
		}
		
		for(ISearchSubdestination subd : getSearchProviderConfiguration().getAvailableSearchSubdestinations(objectType, category, searchProvider))
		{
			if(getSearchProviderConfiguration().isSubdestinationActive(subd, objectType, category, searchProvider))
			{
				result.add(subd);
			}
		}
		return result;
	}
	
	private ControlBackgroundImageManager createGradient(final Control control)
	{
		final ControlBackgroundImageManager bgImageManager = new ControlBackgroundImageManager(control);
		bgImageManager.setBackgroundGradient(getGradientStart(), getGradientEnd(), true);
		control.addListener(SWT.Resize , new Listener(){
			@Override
			public void handleEvent(Event event) {
				bgImageManager.setBackgroundGradient(getGradientStart(), getGradientEnd(), true);
			}
		});
		return bgImageManager;
	}
	
	
	private void installSearchButtonListener()
	{
		searchButton.addSelectionListener(new SelectionAdapter()
		{
			@Override
			public void widgetSelected(SelectionEvent e)
			{
				search();
			}
		});
	}

	/**
	 * Returns the destination category of the currently selected destination. Can be null in case there is currently no selected destination 
	 */
	private IDestinationCategoryDescription getSelectedDestinationCategory()
	{
		try
		{
			final ISearchDestination selectedDestination = getSelectedDestination();
			if(selectedDestination != null)
			{
				return getSearchProviderConfiguration().getDestinationCategoriesForDestination(selectedDestination).iterator().next();
			}
			return null;
		} catch (DestinationCategoryNotFoundException e)
		{
			throw new IllegalStateException(e);
		}
	}

	/**
	 * Get the currently selected object type
	 */
	private IObjectTypeDescription getSelectedObjectType()
	{
		return searchProviderSelector.getSelectedObjectType();
	}

	/**
	 * Get the currently selected search destination
	 */
	private ISearchDestination getSelectedDestination()
	{
		return searchProviderSelector.getSelectedDestination();
	}

	/**
	 * Get the active search provider description. May be null
	 */
	private ISearchProviderDescription getSelectedActiveSearchProviderDescription()
	{
		try
		{
			return getSearchProviderConfiguration().getActiveSearchProvider(getSelectedObjectType(), getSelectedDestinationCategory());
		} catch (ProviderNotFoundException e)
		{
			return null;
		}
	}

	public void updateDestinationsSelector()
	{
		searchProviderSelector.updateDestinationsUI();
	}
	
	private int getLongestLabelSize(final List<String> labels)
	{
		int result = 0;
		
		final GC gc = new GC(PlatformUI.getWorkbench().getDisplay());
		try
		{
			for(String l : labels)
			{
				final int extent = gc.textExtent(l).x;
				result = extent > result ? extent : result;
			}
		}
		finally
		{
			gc.dispose();
		}
		
		return result;
	}
	
	private List<String> getLeftSideLabels()
	{
		return Arrays.asList(new String[]{DiscoveryUIMessages.SEARCH_FOR_LIST_VIEWER_LABEL, DiscoveryUIMessages.SEARCH_IN_LIST_VIEWER_LABEL, DiscoveryUIMessages.SEARCH_KEYWORD_LABEL, DiscoveryUIMessages.GROUP_BY_LABEL});
	}
	
	@Override
	public void dispose()
	{
		super.dispose();
		hyperlinkCursor.dispose();
		upperCompositeGradientManager.disposeResources();
	}

	protected IAdvancedSearchParamsDisplayer createAdvancedSearchParamsDisplayer(final Composite parent, final FormToolkit formToolkit)
	{
		final IAdvancedSearchParamsDisplayer displayer = new AdvancedSearchParamsDisplayer(parent, formToolkit){
			@Override
			protected ISearchProviderConfiguration searchProviderConfiguration()
			{
				return getSearchProviderConfiguration();
			}
		};
		return displayer;
		
	}

	private IDestinationCategoryDescription getDestinationCategory(ISearchDestination destination)
	{
		if(destination == null)
		{
			return null;
		}
		
		try
		{
			return getSearchProviderConfiguration().getDestinationCategoriesForDestination(destination).iterator().next();
		} catch (DestinationCategoryNotFoundException e)
		{
			throw new IllegalStateException(e);
		}
	}
	
	public void showGroupingHierarchies(final List<GroupingHierarchy> groupingHierarchies)
	{
		searchParametersUI.showGroupingHierarchies(groupingHierarchies);
	}

	public IProgressMonitor getProgressMonitor()
	{
		return this.viewProgressMonitor;
	}

	public Composite getResultComposite() {
		return bottomComposite;
	}

	public FormToolkit getFormToolkit() {
		return formToolkit;
	}
	
	@Override
	public void setDefaultSessionId(final String sessionId)
	{
		this.defaultSessionId = sessionId;
	}

	@Override
	public void setStatusMessage(final String message)
	{
		this.slidingComposite.setMessage(message);
	}

	private class OrientationChangedListener implements IPropertyAttributeListener<ORIENTATION>
	{
		@Override
		public void attributeChanged(PropertyAttributeChangedEvent<ORIENTATION> event)
		{
			adjustUpperCompositeLayoutData(event.getNewAttribute());
			upperComposite.layout(true, true);
		}
	}
	
	private Point computeUpperCompositeSize(final Point fixedParamsCompositeSize, final Point customParamsCompositeSize, final Point searchButtonSize, final ORIENTATION orientation)
	{
		// The fixed params composite
		final Point size = new Point(fixedParamsCompositeSize.x, fixedParamsCompositeSize.y);

		// The search button size and the space above it
		size.y += UI_IN_CONTROL_SPACING;
		size.y += searchButtonSize.y;

		if (orientation == ORIENTATION.VERTICAL)
		{
			// Add the custom composite "y" and the space above it in vertical orientation
			size.y += customParamsCompositeSize.y + UI_IN_CONTROL_SPACING;
		} else
		{
			// Add the custom composite "x" and the space on its left it in horizontal orientation
			size.x += customParamsCompositeSize.x + UI_IN_CONTROL_SPACING;
			// The "y" of the size should be the greater "Y" of the custom params composite size and the sum of the fixed params and search button heights
			size.y = Math.max(size.y, customParamsCompositeSize.y);
			size.y += UI_IN_CONTROL_SPACING; // spacing below the lowest control
		}

		return size;
	}
	
	@Override
	public void setUiContext(IViewUiContext uiContext)
	{
		super.setUiContext(uiContext);
		uiContext().setSecondColumnPosition(getLongestLabelSize(getLeftSideLabels()));
	}

	@Override
	public void registerController(final ISearchConsoleController controller)
	{
		this.controller = controller;
		searchProviderSelector.setController(controller);
	}

	@Override
	public ISearchConsoleControllerOutputView getControllerView()
	{
		return this;
	}

	@Override
	public void setDestinationsManager(IDestinationsManager destManager) {
		this.destManager = destManager;
	}
	
}
