package org.gcube.portlets.user.speciesdiscovery.client.window;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import org.gcube.portlets.user.speciesdiscovery.client.ConstantsSpeciesDiscovery;
import org.gcube.portlets.user.speciesdiscovery.client.SearchController;
import org.gcube.portlets.user.speciesdiscovery.client.SpeciesDiscovery;
import org.gcube.portlets.user.speciesdiscovery.client.advancedsearch.AdvancedSearchPanelManager;
import org.gcube.portlets.user.speciesdiscovery.client.cluster.TablesForResultRow;
import org.gcube.portlets.user.speciesdiscovery.client.cluster.TablesForTaxonomyRow;
import org.gcube.portlets.user.speciesdiscovery.client.event.CreateOccurrenceJobEvent;
import org.gcube.portlets.user.speciesdiscovery.client.event.CreateTaxonomyJobEvent;
import org.gcube.portlets.user.speciesdiscovery.client.event.CreateTaxonomyJobEvent.TaxonomyJobType;
import org.gcube.portlets.user.speciesdiscovery.client.event.ShowOccurrencesMapEvent;
import org.gcube.portlets.user.speciesdiscovery.client.externalsystem.OtherInformationSystemsEnum;
import org.gcube.portlets.user.speciesdiscovery.client.externalsystem.OtherMappingSystemsEnum;
import org.gcube.portlets.user.speciesdiscovery.client.gridview.OccurrenceJobGridManager;
import org.gcube.portlets.user.speciesdiscovery.client.resources.Resources;
import org.gcube.portlets.user.speciesdiscovery.client.util.GridField;
import org.gcube.portlets.user.speciesdiscovery.client.util.OccurencesGridFields;
import org.gcube.portlets.user.speciesdiscovery.client.util.Util;
import org.gcube.portlets.user.speciesdiscovery.client.util.stream.DataSourceManager;
import org.gcube.portlets.user.speciesdiscovery.client.util.stream.ResultRowDataSource;
import org.gcube.portlets.user.speciesdiscovery.client.util.stream.StreamPagingLoader;
import org.gcube.portlets.user.speciesdiscovery.client.util.stream.StreamPagingToolBar;
import org.gcube.portlets.user.speciesdiscovery.shared.DataSourceModel;
import org.gcube.portlets.user.speciesdiscovery.shared.OccurrencesSaveEnum;
import org.gcube.portlets.user.speciesdiscovery.shared.OccurrencesStatus;
import org.gcube.portlets.user.speciesdiscovery.shared.ResultRow;
import org.gcube.portlets.user.speciesdiscovery.shared.SaveFileFormat;
import org.gcube.portlets.user.speciesdiscovery.shared.SearchType;
import org.gcube.portlets.user.speciesdiscovery.shared.SpeciesCapability;
import org.gcube.portlets.user.speciesdiscovery.shared.TaxonomyRow;
import org.gcube.portlets.user.speciesdiscovery.shared.cluster.ClusterCommonNameDataSource;
import org.gcube.portlets.user.speciesdiscovery.shared.cluster.ClusterStructuresForResultRow;
import org.gcube.portlets.user.speciesdiscovery.shared.cluster.ClusterStructuresForTaxonomyRow;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.ButtonArrowAlign;
import com.extjs.gxt.ui.client.Style.ButtonScale;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.IconAlign;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.Style.VerticalAlignment;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.BoxComponentEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.WindowEvent;
import com.extjs.gxt.ui.client.event.WindowListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.ColumnData;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.extjs.gxt.ui.client.widget.layout.FitData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.layout.TableData;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.tips.ToolTipConfig;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Anchor;

/**
 * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
 *
 */
public class ViewDetailsWindow extends Window {

	protected final ViewDetailsWindow INSTANCE;
	
	protected StreamPagingLoader loader;
	protected int count = 0;
	private int numberOfSelectedRow = 0;
	private ContentPanel container = new ContentPanel();
	private TabPanel tabPanel = new TabPanel();
	private TabItem tabItemOccrs = new TabItem(ConstantsSpeciesDiscovery.OCCURRENCEPOINTS);
	private TabItem tabItemDetails = new TabItem(ConstantsSpeciesDiscovery.DETAILS);
	private ContentPanel panelDetails = new ContentPanel();
	private ContentPanel panelOccurrences = new ContentPanel();
	
	private int width = 900;
	private int height = 600;
	private int widthPanelOccurrences = 1200;
	private int heightPanelOccurrences  = height-70;
	public final static String FIVEPX = "5px";

	
	private SearchController searchController;
	private ToolBar toolbarOccurrences;
	private DataSourceManager dataSourceManager;
	private AbstractImagePrototype imageYes = AbstractImagePrototype.create(Resources.INSTANCE.getCheckYes());
	private AbstractImagePrototype imageNo = AbstractImagePrototype.create(Resources.INSTANCE.getCheckNo());
	
	private AbstractImagePrototype imgAttention = AbstractImagePrototype.create(Resources.INSTANCE.getAttention());
	
	private ToolBar toolbarTaxonomy;
	private SearchType searchType;
	private boolean isSearchByCommonName = false;
	private Timer timerGetCountOfOccurrences;
	
	private List<String> lastlistDataSourceFound = null;
	private String lastScientificName = null;
	
	public ViewDetailsWindow(SearchController searchController, SpeciesCapability capability, SearchType searchType) {
		
		INSTANCE = this;
		this.setCollapsible(false);
		this.setMaximizable(true);
//		this.setHideCollapseTool(true);
		this.searchController = searchController;
		this.dataSourceManager = DataSourceManager.getInstance();
		this.searchType = searchType;
		
		if(searchType.equals(SearchType.BY_COMMON_NAME))
			isSearchByCommonName = true;
		
		container.setHeaderVisible(false);
		container.setBodyBorder(false);
		container.setLayout(new FitLayout());

		setSize(width, height);
		setPlain(true);
		setModal(false);
		setBlinkModal(false);
		setHeading("View Details");
		setLayout(new FitLayout());
		addWindowListener(new WindowListener() {
			@Override
			public void windowHide(WindowEvent we) {

				//loader is null if items are taxonomy
				if(loader!=null)
					loader.reset();
				
				if(timerGetCountOfOccurrences!=null)
					stopTimerGetCountOfOccurrences(500);
				
			}
		});
		
		addListener(Events.Resize, new Listener<BoxComponentEvent>() {
			  public void handleEvent(BoxComponentEvent event) {
				  windowResize(INSTANCE.getWidth(), INSTANCE.getHeight());
			  }
		});
		
		tabPanel = new TabPanel();
		tabPanel.setBorders(false);
		
		if(capability.getName().compareTo(SpeciesCapability.RESULTITEM.getName())==0){
			this.toolbarOccurrences = createToolbarOccurrences();
			createTabItemDisplayResultItem();
		}
		else if(capability.getName().compareTo(SpeciesCapability.TAXONOMYITEM.getName())==0){
			this.toolbarTaxonomy = createToolbarTaxonomy();
			cretateTabItemDisplayTaxonomyItem();
		}

		container.add(tabPanel,new FitData(4));
		add(container);
		
		show();

	}
	
	protected void windowResize(int width,int height){
		
		if(width>widthPanelOccurrences)
			panelOccurrences.setWidth(width-20);
		else
			panelOccurrences.setWidth(widthPanelOccurrences);
		
		if(height>heightPanelOccurrences)
			panelOccurrences.setHeight(height-70);
		else
			panelOccurrences.setHeight(heightPanelOccurrences);
		
	}
	
	
	private void cretateTabItemDisplayTaxonomyItem() {

		tabItemDetails.setScrollMode(Scroll.AUTO);
		
		ContentPanel cpDetailsTaxonomy = new ContentPanel();
		cpDetailsTaxonomy.setHeaderVisible(false);
		cpDetailsTaxonomy.setBodyBorder(false);
		cpDetailsTaxonomy.add(panelDetails);
		cpDetailsTaxonomy.setTopComponent(this.toolbarTaxonomy);
		tabItemDetails.add(cpDetailsTaxonomy);

		panelDetails.setHeaderVisible(false);
		panelDetails.setBodyBorder(false);
//		panelDetails.setStyleAttribute("padding", FIVEPX);
		
		panelDetails.setStyleAttribute("padding-left", FIVEPX);
		panelDetails.setStyleAttribute("padding-right", FIVEPX);
		panelDetails.setStyleAttribute("padding-bottom", FIVEPX);
		
		panelDetails.setStyleAttribute("margin-left", FIVEPX);
		panelDetails.setStyleAttribute("margin-right", FIVEPX);
		panelDetails.setStyleAttribute("margin-bottom", FIVEPX);
		
//		panelDetails.setTopComponent(this.toolbarTaxonomy);
		
		tabItemDetails.add(panelDetails);
		
		setFocusWidget(getButtonBar().getItem(0));

		tabItemDetails.mask("Loading...", ConstantsSpeciesDiscovery.LOADINGSTYLE);
		enableToolbarTaxonomy(false);
		
		loadStructuresAndFillingPage(SpeciesCapability.TAXONOMYITEM);
		
		tabPanel.add(tabItemDetails);
		
		
	}

	private void createTabItemDisplayResultItem() {
		
		tabItemOccrs.setToolTip(new ToolTipConfig("Show Occurrences", "Shows occurences points from selected results."));
		
		tabItemDetails.setScrollMode(Scroll.AUTO);
		
		panelDetails.setHeaderVisible(false);
		panelDetails.setBodyBorder(false);
		panelDetails.setStyleAttribute("padding", FIVEPX);
		panelDetails.setStyleAttribute("margin", FIVEPX);
		
//		panelDetails.add(createButtonSaveAsHtml());

		panelOccurrences.setHeaderVisible(false);
		panelOccurrences.setBodyBorder(false);
//		panelOccurences.setStyleAttribute("padding", FIVEPX);
		panelOccurrences.setScrollMode(Scroll.AUTO);
		panelOccurrences.setSize(widthPanelOccurrences, heightPanelOccurrences);
		panelOccurrences.setLayout(new FitLayout());
		panelOccurrences.setTopComponent(this.toolbarOccurrences);

		tabItemDetails.add(panelDetails);
		tabItemOccrs.add(panelOccurrences);

		setFocusWidget(getButtonBar().getItem(0));

		createOccurrencesWindow();
		
		tabItemDetails.mask("Loading...",ConstantsSpeciesDiscovery.LOADINGSTYLE);
		enableToolbarOccurrence(false);

//		loadNumberOfSelectedRowAndDetailsFilling(SpeciesCapability.RESULTITEM);
		
		loadStructuresAndFillingPage(SpeciesCapability.RESULTITEM);
		
		tabPanel.add(tabItemDetails);
		tabPanel.add(tabItemOccrs);
		
	}
	
	private void enableToolbarOccurrence(boolean bool){
		toolbarOccurrences.setEnabled(bool);
	}
	
	private void enableToolbarTaxonomy(boolean bool){
		toolbarTaxonomy.setEnabled(bool);
	}
	
	
	public void loadStructuresAndFillingPage(final SpeciesCapability capability){
		
		final long startTime = System.currentTimeMillis();
		
		if(capability.getName().compareTo(SpeciesCapability.RESULTITEM.getName())==0)
			SpeciesDiscovery.taxonomySearchService.loadStructuresForResultRowClustering(new AsyncCallback<ClusterStructuresForResultRow>() {

				@Override
				public void onFailure(Throwable caught) {
					Info.display("Sorry", "Error retriving selected results");
					tabItemDetails.unmask();
					enableToolbarOccurrence(true);
					
				}

				@Override
				public void onSuccess(ClusterStructuresForResultRow result) {
					
					int size = result.getResult().size();

					long returnedTime = System.currentTimeMillis();
					
					long loadTime = returnedTime-startTime;
					
					Log.trace("fillPageDetailsForOccurences: " +size +" cluster result row was loaded in "+  loadTime +" msc");
					
					String items = size>0?"items":"item"; 
					
					String msg = "";
	
					if(result.getTotalRow()>size){
						msg = ConstantsSpeciesDiscovery.ROW_LIMIT_REACHED + " - ";
						tabItemDetails.setIcon(imgAttention);
						tabItemDetails.setToolTip(ConstantsSpeciesDiscovery.THE_MAX_NUMBER_OF_ITEMS_DISPLAYABLE_IS+ConstantsSpeciesDiscovery.LIMIT_ITEM_DETAILS);
					}
					
					msg+= tabItemDetails.getText() + " ("+size +" "+ items+")";
					tabItemDetails.setText(msg);

					createCommonNameDetailsPageForResultRow(searchController.getLastSearchEvent().getSearchTerm(), result);
					
					enableToolbarOccurrence(true);
					tabItemDetails.unmask();
					
					long avilableTime = System.currentTimeMillis()-returnedTime;
					
					Log.trace("fillPageDetailsForOccurences: " +size +" view details result row are available in "+  avilableTime +" msc");
					
				}


			});
		
		else if(capability.getName().compareTo(SpeciesCapability.TAXONOMYITEM.getName())==0){

			SpeciesDiscovery.taxonomySearchService.loadStructuresForTaxonomyClustering(new AsyncCallback<ClusterStructuresForTaxonomyRow>() {

				@Override
				public void onFailure(Throwable caught) {
					Info.display("Sorry", "Error retriving selected results");
					tabItemDetails.unmask();
					enableToolbarTaxonomy(true);
					
				}

				@Override
				public void onSuccess(ClusterStructuresForTaxonomyRow result) {
					
					int size = result.getResult().size();
					
					long returnedTime = System.currentTimeMillis();
					
					long loadTime = returnedTime-startTime;

					Log.trace("fillPageDetailsForTaxonomy: " +size +" cluster taxonomy row was loaded in "+  loadTime +" msc");
					
//					TablesForTaxonomyRow tableClassification = new TablesForTaxonomyRow(result, DEFAULTLANGUAGE, tabPanel, isSearchByCommonName, searchController.getEventBus());
					
					String items = size>0?"items":"item"; 
					
					String msg = "";
					
					if(result.getTotalRow()>size){
						msg = ConstantsSpeciesDiscovery.ROW_LIMIT_REACHED + " - ";
						tabItemDetails.setIcon(imgAttention);
						tabItemDetails.setToolTip(ConstantsSpeciesDiscovery.THE_MAX_NUMBER_OF_ITEMS_DISPLAYABLE_IS+ConstantsSpeciesDiscovery.LIMIT_ITEM_DETAILS);
					}
					
					msg+= tabItemDetails.getText() + " ("+size +" "+ items+")";
					tabItemDetails.setText(msg);
					
					
					createCommonNameDetailsPageForTaxonomyRow(result, searchController.getLastSearchEvent().getSearchTerm());
					enableToolbarTaxonomy(true);
					tabItemDetails.unmask();
					
					long avilableTime = returnedTime-loadTime;
					
					Log.trace("fillPageDetailsForTaxonomy: " +size +" view details taxonomy row are available in "+  avilableTime +" msc");
				}

				
			});
		}
	}
	
	private void createCommonNameDetailsPageForTaxonomyRow(ClusterStructuresForTaxonomyRow result,String searchTerm) {
		HashMap<String, ArrayList<String>> hashTaxonomyRowID = result.getHashClusterScientificNameTaxonomyRowID();
//		ArrayList<String> listDataSourceFound = tableClassification.getListFoundDataSources();
		HashMap<String,ClusterCommonNameDataSource<TaxonomyRow>> hashClusterCommonNamesDataSources = result.getHashClusterCommonNamesDataSources();
		
//		HashMap<String, ArrayList<GxtClassificationModel>> hashHTMLTables = result.getHashClassificationTables();
		
		String title = getSearchTitle();
		panelDetails.add(new Html(title));
			
//		for (String dataSource : listDataSourceFound) {
//			  System.out.println("############# Data Source found " + dataSource);
//		}
		
		List<String> listKey = new ArrayList<String>(hashTaxonomyRowID.keySet());
		Collections.sort(listKey);
		
		
		final Anchor anchorIndex = new Anchor();
		anchorIndex.setName("indexOfContents");
		
		panelDetails.add(new Html("<p style=\"font-size:12px;\"><b> Index of Contents"+anchorIndex+"</b></p><br/>"));
		panelDetails.add(createIndexOfContents(listKey));
		
		//update last list data source found
		lastlistDataSourceFound = result.getListFoundDataSources();
		
		//Create panels about
		panelDetails.add(new Html("<hr><br/>"));
		VerticalPanel verticaPanelAbouts = createPanelAbout(SpeciesCapability.TAXONOMYITEM, result.getListFoundDataSources());
		panelDetails.add(verticaPanelAbouts);
		panelDetails.add(new Html("<br/>"));
		
		for (final String scientificName : listKey) {
			
			Anchor anchor = new Anchor("[top index]");
			anchor.setName(scientificName);
			
			anchor.addClickHandler(new ClickHandler() {
			    public void onClick(ClickEvent event) {
			         com.google.gwt.user.client.Window.Location.assign("#indexOfContents");
			    }
			});
			
			LayoutContainer titleContainer = new LayoutContainer();
			titleContainer.setLayout(new ColumnLayout());
			titleContainer.setWidth(width-80);
			
			LayoutContainer left = new LayoutContainer();
		    FormLayout layout = new FormLayout();
		    left.setLayout(layout);
		    
		    LayoutContainer right = new LayoutContainer();
		    layout = new FormLayout();
		    right.setLayout(layout);
	

		    HorizontalPanel hp = new HorizontalPanel();
		    hp.setTableWidth("100%");
		    TableData td = new TableData();
		    td.setHorizontalAlign(HorizontalAlignment.RIGHT);
		    hp.add(anchor, td);
		    

			titleContainer.add(left, new ColumnData(.8));
			titleContainer.add(right, new ColumnData(.2));
			
//			HorizontalPanel hp = new HorizontalPanel();
//			hp.setHorizontalAlign(HorizontalAlignment.CENTER);
//			hp.setStyleAttribute("margin", FIVEPX);
			
			this.lastScientificName = scientificName;
			
			left.add(new Html("<p style=\"margin-right:5px; font-size:14px;\"><b>" + ConstantsSpeciesDiscovery.SCIENTIFICNAME + ": " + scientificName + "</b></p>"));
			right.add(hp);
			
			panelDetails.add(titleContainer);
			panelDetails.add(new Html("<br/><br/>"));
			panelDetails.add(createExternalLinks(scientificName));
			
			String commonNamesTitle = "<p style=\"font-size:12px;\"><b>Common Names (Data Source/s)</b></p>";
			panelDetails.add(new Html(commonNamesTitle));
			
			ClusterCommonNameDataSource<TaxonomyRow> cluster = hashClusterCommonNamesDataSources.get(scientificName);
			
			String tableCommonName = createTableWithCheckCommonNameDataSource(cluster.getHashMapCommonNameDataSources(), cluster.getListDataSourcesFound());
			panelDetails.add(new Html("<br/>"+tableCommonName+"<br/>"));
			
			ArrayList<String> arrayTaxonomyID = hashTaxonomyRowID.get(scientificName);
			
			for(int i=0; i<arrayTaxonomyID.size(); i++ ){
				TaxonomyRow taxonomy = result.getTaxonomyRowByKey(arrayTaxonomyID.get(i));
				String dataSource = taxonomy.getDataProviderName();
				
				TablesForTaxonomyRow tables = new TablesForTaxonomyRow(tabPanel, searchController.getEventBus());
	
				HorizontalPanel horizontalPanel = new HorizontalPanel();
				horizontalPanel.add(new Html("<br/><p style=\"font-size:12px;\"><b> Scientific Classification of "+ scientificName + " on " +dataSource+ " Data Source</b> </p> "));
				horizontalPanel.setVerticalAlign(VerticalAlignment.BOTTOM);
				
				DataSourceModel ds = AdvancedSearchPanelManager.getInstance().findDataSourceByCapabilityAndName(SpeciesCapability.TAXONOMYITEM, dataSource);
				
				Anchor createAbout = createAbout(ds,true);
				if(createAbout!=null){
					createAbout.getElement().getStyle().setMarginLeft(25, Unit.PX);
					horizontalPanel.add(createAbout);
				}
				
				panelDetails.add(horizontalPanel);
				panelDetails.add(tables.getPanelClassificationForTaxonomy(taxonomy, dataSource, false));
				
				tables.setParents(taxonomy.getParents());
				panelDetails.add(tables.getHTMLTableForTaxonomyWithRef(taxonomy, false, dataSource));
			}
		}
		
		panelDetails.layout(true);
		
	}
	
	private void createCommonNameDetailsPageForResultRow(String searchTerm, ClusterStructuresForResultRow result) {

		HashMap<String, ArrayList<String>> hashResultRowIdTables = result.getHashClusterScientificNameResultRowID();
		HashMap<String, ClusterCommonNameDataSource<ResultRow>> hashClusterCommonNamesDataSources = result.getHashClusterCommonNamesDataSources();
		
		String title = getSearchTitle();
		
		panelDetails.add(new Html(title));

		List<String> listKey = new ArrayList<String>(hashResultRowIdTables.keySet());
		Collections.sort(listKey);
		
		final Anchor anchorIndex = new Anchor();
		anchorIndex.setName("indexOfContents");
		
		panelDetails.add(new Html("<p style=\"font-size:12px;\"><b> Index of Contents"+anchorIndex+"</b></p><br/>"));
		panelDetails.add(createIndexOfContents(listKey));
		
		panelDetails.add(new Html("<hr><br/>"));
		
		//update last list data source found
		lastlistDataSourceFound = result.getListFoundDataSources();
		
		VerticalPanel verticaPanelAbouts = createPanelAbout(SpeciesCapability.RESULTITEM, result.getListFoundDataSources());
		panelDetails.add(verticaPanelAbouts);
		panelDetails.add(new Html("<br/>"));
		
		for (final String scientificName : listKey) {
			
			Anchor anchor = new Anchor("[top index]");
			anchor.setName(scientificName);
			
			anchor.addClickHandler(new ClickHandler() {
			    public void onClick(ClickEvent event) {
			         com.google.gwt.user.client.Window.Location.assign("#indexOfContents");
			    }
			});
			
			LayoutContainer titleContainer = new LayoutContainer();
			titleContainer.setLayout(new ColumnLayout());
			titleContainer.setWidth(width-80);
			
			LayoutContainer left = new LayoutContainer();
		    FormLayout layout = new FormLayout();
		    left.setLayout(layout);
		    
		    LayoutContainer right = new LayoutContainer();
		    layout = new FormLayout();
		    right.setLayout(layout);
	

		    HorizontalPanel hp = new HorizontalPanel();
		    hp.setTableWidth("100%");
		    TableData td = new TableData();
		    td.setHorizontalAlign(HorizontalAlignment.RIGHT);
		    hp.add(anchor, td);
		    

			titleContainer.add(left, new ColumnData(.8));
			titleContainer.add(right, new ColumnData(.2));
			
			this.lastScientificName = scientificName;
			
			left.add(new Html("<p style=\"margin-right:5px; font-size:14px;\"><b>" + ConstantsSpeciesDiscovery.SCIENTIFICNAME + ": " + scientificName + "</b></p>"));
			right.add(hp);
			
			panelDetails.add(titleContainer);
			
			panelDetails.add(new Html("<br/><br/>"));
			
			panelDetails.add(createExternalLinks(scientificName));
			
			String commonNamesTitle = "<p style=\"font-size:12px;\"><b>Common Names (Data Source/s)</b></p>";
			panelDetails.add(new Html(commonNamesTitle));
	
			ClusterCommonNameDataSource<ResultRow> cluster = hashClusterCommonNamesDataSources.get(scientificName);

			String tableCommonName = createTableWithCheckCommonNameDataSource(cluster.getHashMapCommonNameDataSources(), cluster.getListDataSourcesFound());
			panelDetails.add(new Html("<br/>"+tableCommonName+"<br/><br/>"));
			
			ArrayList<String> arrayRowID = hashResultRowIdTables.get(scientificName);
			
			for(int i=0; i<arrayRowID.size(); i++ ){
				ResultRow row = result.getResultRowByRowID(arrayRowID.get(i));
				Html table = TablesForResultRow.getTableForResultRow(row, ResultRowDataSource.getClassification(row.getParents()));
				panelDetails.add(table);
			}
		}
		
		panelDetails.layout(true);
		
		
	}
	

	public ToolBar createToolbarTaxonomy(){
		
		ToolBar toolbar = new ToolBar();
		
		Button btnTaxonomyMenu = new Button(ConstantsSpeciesDiscovery.SAVE_TAXONOMY_ITEMS);  
		Menu formatSubMenu = new Menu();
		btnTaxonomyMenu.setMenu(formatSubMenu);  
		btnTaxonomyMenu.setScale(ButtonScale.SMALL);  
		btnTaxonomyMenu.setIconAlign(IconAlign.TOP);  
		btnTaxonomyMenu.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.getSaveProducts()));
		btnTaxonomyMenu.setToolTip(new ToolTipConfig(ConstantsSpeciesDiscovery.SAVE_TAXONOMY_ITEMS, "Save taxonomy items from selected results."));
		
//		btnOccurrencesMenu.addSelectionListener(new SelectionListener<ButtonEvent>() {
//
//			@Override
//			public void componentSelected(ButtonEvent ce) {
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.TAXONOMY_ITEM, SaveFileFormat.DARWIN_CORE_ARCHIVE, count, null));
//				
//			}
//		});
		
		MenuItem darwinCoreArchiveItem = new MenuItem(ConstantsSpeciesDiscovery.DARWIN_CORE_ARCHIVE);
		darwinCoreArchiveItem.setToolTip(new ToolTipConfig(ConstantsSpeciesDiscovery.SAVES_IN_DARWIN_CORE_ARCHIVE_FORMAT));
		darwinCoreArchiveItem.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(MenuEvent ce) {

				searchController.getEventBus().fireEvent(new CreateTaxonomyJobEvent(TaxonomyJobType.BYIDS));
				
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.TAXONOMY_ITEM, SaveFileFormat.DARWIN_CORE_ARCHIVE, count, null));			
			}
		});
		
		formatSubMenu.add(darwinCoreArchiveItem);

		toolbar.add(btnTaxonomyMenu);
		
		return toolbar;
		
		
	}
	
	public ToolBar createToolbarOccurrences(){
		
		ToolBar toolbar = new ToolBar();

		Button btnShowInGisViewer = new Button(ConstantsSpeciesDiscovery.SHOW_IN_GIS_VIEWER);
		btnShowInGisViewer.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.getGisProducts()));
		btnShowInGisViewer.setToolTip(new ToolTipConfig(ConstantsSpeciesDiscovery.SHOW_IN_GIS_VIEWER, "Show occurences points from selected results in a Gis Viewer Map."));
		btnShowInGisViewer.setScale(ButtonScale.SMALL);  
		btnShowInGisViewer.setIconAlign(IconAlign.TOP);  
		btnShowInGisViewer.setArrowAlign(ButtonArrowAlign.BOTTOM); 
		btnShowInGisViewer.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				searchController.getEventBus().fireEvent(new ShowOccurrencesMapEvent(count));
			}
		});
		
		
		Button btnOccurrencesMenu = new Button(ConstantsSpeciesDiscovery.SAVE_OCCURRENCES);  
		Menu formatSubMenu = new Menu();
		btnOccurrencesMenu.setMenu(formatSubMenu);  
		btnOccurrencesMenu.setScale(ButtonScale.SMALL);  
		btnOccurrencesMenu.setIconAlign(IconAlign.TOP);  
		btnOccurrencesMenu.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.getSaveProducts()));
		btnOccurrencesMenu.setToolTip(new ToolTipConfig(ConstantsSpeciesDiscovery.SAVE_OCCURRENCES, ConstantsSpeciesDiscovery.SAVE_OCCURENCES_POINTS_FROM_SELECTED_RESULTS));

		MenuItem csvFormatItem = new MenuItem(ConstantsSpeciesDiscovery.CSV);
		csvFormatItem.setToolTip(new ToolTipConfig(ConstantsSpeciesDiscovery.SAVES_IN_CSV_FILE_FORMAT));
		csvFormatItem.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(MenuEvent ce) {
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.OCCURRENCE_POINT, SaveFileFormat.CSV, count, OccurrencesSaveEnum.STANDARD));	
				
				String searchTerm = OccurrenceJobGridManager.getSearchTermBySearchType(isSearchByCommonName, searchController.getLastSearchEvent().getSearchTerm());
				
				searchController.getEventBus().fireEvent(new CreateOccurrenceJobEvent(SaveFileFormat.CSV, count, OccurrencesSaveEnum.STANDARD, lastlistDataSourceFound, searchTerm,false));	
			}
		});
		
		
		formatSubMenu.add(csvFormatItem);
		
		Menu csvTypeMenu = new Menu();  
	    
	    MenuItem csvStandard = new MenuItem(ConstantsSpeciesDiscovery.PLAIN_CSV);
	    
	    csvStandard.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(MenuEvent ce) {
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.OCCURRENCE_POINT, SaveFileFormat.CSV, count, OccurrencesSaveEnum.STANDARD));	
				
				String searchTerm = OccurrenceJobGridManager.getSearchTermBySearchType(isSearchByCommonName, searchController.getLastSearchEvent().getSearchTerm());
				
				searchController.getEventBus().fireEvent(new CreateOccurrenceJobEvent(SaveFileFormat.CSV, count, OccurrencesSaveEnum.STANDARD, lastlistDataSourceFound, searchTerm,false));
			}
		});
	    
	    
	    MenuItem csvStandardByDataSource = new MenuItem(ConstantsSpeciesDiscovery.PLAIN_CSV_BY_DATA_SOURCE);
	    
	    csvStandardByDataSource.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(MenuEvent ce) {
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.OCCURRENCE_POINT, SaveFileFormat.CSV, count, OccurrencesSaveEnum.STANDARD));	
				
				String searchTerm = OccurrenceJobGridManager.getSearchTermBySearchType(isSearchByCommonName, searchController.getLastSearchEvent().getSearchTerm());
				
				searchController.getEventBus().fireEvent(new CreateOccurrenceJobEvent(SaveFileFormat.CSV, count, OccurrencesSaveEnum.STANDARD, lastlistDataSourceFound, searchTerm,true));
			}
		});
	    
	    
	    MenuItem csvOpenModeller = new MenuItem(ConstantsSpeciesDiscovery.OPEN_MODELLER);
	    
	    csvOpenModeller.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(MenuEvent ce) {
				
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.OCCURRENCE_POINT, SaveFileFormat.CSV, count, OccurrencesSaveEnum.OPENMODELLER));		
				
				String searchTerm = OccurrenceJobGridManager.getSearchTermBySearchType(isSearchByCommonName, searchController.getLastSearchEvent().getSearchTerm());
				
				searchController.getEventBus().fireEvent(new CreateOccurrenceJobEvent(SaveFileFormat.CSV, count, OccurrencesSaveEnum.OPENMODELLER, lastlistDataSourceFound, searchTerm,false));
			}
		});
	    
	    
	    MenuItem csvOpenModellerByDataSource = new MenuItem(ConstantsSpeciesDiscovery.OPEN_MODELLER_BY_DATA_SOURCE);
	    
	    csvOpenModellerByDataSource.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(MenuEvent ce) {
				
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.OCCURRENCE_POINT, SaveFileFormat.CSV, count, OccurrencesSaveEnum.OPENMODELLER));		
				
				String searchTerm = OccurrenceJobGridManager.getSearchTermBySearchType(isSearchByCommonName, searchController.getLastSearchEvent().getSearchTerm());
				
				searchController.getEventBus().fireEvent(new CreateOccurrenceJobEvent(SaveFileFormat.CSV, count, OccurrencesSaveEnum.OPENMODELLER, lastlistDataSourceFound, searchTerm,true));
			}
		});
	    
	    csvTypeMenu.add(csvStandard);  
	    
	    csvTypeMenu.add(csvStandardByDataSource);
	    
	    csvTypeMenu.add(csvOpenModeller); 
	    
	    csvTypeMenu.add(csvOpenModellerByDataSource);
	    
	    csvFormatItem.setSubMenu(csvTypeMenu); 
		
		MenuItem darwinCoreFormatItem = new MenuItem(ConstantsSpeciesDiscovery.DARWIN_CORE);
		darwinCoreFormatItem.setToolTip(new ToolTipConfig(ConstantsSpeciesDiscovery.SAVES_IN_DARWIN_CORE_FILE_FORMAT));
		darwinCoreFormatItem.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(MenuEvent ce) {
//				searchController.getEventBus().fireEvent(new SaveItemsEvent(SearchResultType.OCCURRENCE_POINT, SaveFileFormat.DARWIN_CORE, count, null));			
				
				String searchTerm = OccurrenceJobGridManager.getSearchTermBySearchType(isSearchByCommonName, searchController.getLastSearchEvent().getSearchTerm());
				
				searchController.getEventBus().fireEvent(new CreateOccurrenceJobEvent(SaveFileFormat.DARWIN_CORE, count, null, lastlistDataSourceFound, searchTerm, false));
			}
		});
		formatSubMenu.add(darwinCoreFormatItem);
		
		toolbar.add(btnOccurrencesMenu);
		toolbar.add(new SeparatorToolItem());
		toolbar.add(btnShowInGisViewer);
		return toolbar;
	}
	

	private String getSearchType(){
		
		String searchType = "";
			switch (searchController.getLastSearchEvent().getType()) {
				case BY_COMMON_NAME:
					
					searchType = ConstantsSpeciesDiscovery.BYCOMMONNAME;
					
					break;
					
				case BY_SCIENTIFIC_NAME:
					
					searchType = ConstantsSpeciesDiscovery.BYSCIENTIFICNAME;
					
					break;
			}
		return searchType;
	}
	
	private String getSearchTitle(){

		
		return "<br/><br/><p style=\"font-size:18px;\"><b>" + searchController.getLastSearchEvent().getSearchTerm() + "</b></p>" +
		   "<p style=\"font-family:\"Times New Roman\", Times, serif; font-size:12px; font-style:italic; \">search "+getSearchType()+"</p><br/><hr><br/>";
		
	}
	
	
	/**
	 * 
	 * @param searchValue
	 * @return a vetical panel with external links on input
	 */
	public static VerticalPanel createExternalLinks(final String searchValue){
		
		VerticalPanel vpExternalLink = new VerticalPanel();
		
		// Create Links to Other Information Systems
		Html htmlLinkOIS = new Html("<p style=\"font-size:12px;\"><b>Links to Other Information Systems</b></p>");
		VerticalPanel vpOIS = new VerticalPanel();
		vpOIS.setStyleAttribute("margin", FIVEPX);
		vpOIS.setStyleAttribute("padding", FIVEPX);
		
		
		for (final OtherInformationSystemsEnum infSystem : OtherInformationSystemsEnum.values()) {
			
			Anchor anchor = new Anchor(infSystem.getName());
			anchor.addClickHandler(new ClickHandler() {
				
				@Override
				public void onClick(ClickEvent event) {
					String url = infSystem.getBaseUrl() + searchValue + infSystem.getSuffixUrl();
					new WindowOpenUrl(url, "_blank", null);
					
				}
			});
			
			vpOIS.add(anchor);
		}

		// Create Links to Other Mapping Systems
		Html htmlLinkOMS = new Html("<p style=\"font-size:12px;\"><b>Links to Other Mapping Systems</b></p>");
		VerticalPanel vpOMS = new VerticalPanel();
		vpOMS.setStyleAttribute("margin", FIVEPX);
		vpOMS.setStyleAttribute("padding", FIVEPX);
		
		
		for (final OtherMappingSystemsEnum infSystem : OtherMappingSystemsEnum.values()) {
			
			Anchor anchor = new Anchor(infSystem.getName());
			anchor.addClickHandler(new ClickHandler() {
				
				@Override
				public void onClick(ClickEvent event) {
					String url = infSystem.getBaseUrl() + searchValue + infSystem.getSuffixUrl();
					new WindowOpenUrl(url, "_blank", null);
					
				}
			});
			
			vpOMS.add(anchor);
		}
		
		vpExternalLink.add(htmlLinkOIS);
		vpExternalLink.add(vpOIS);
		
		vpExternalLink.add(htmlLinkOMS);
		vpExternalLink.add(vpOMS);
		
		return vpExternalLink;
	}
	

	protected void initLoader()
	{
		loader = new StreamPagingLoader(ConstantsSpeciesDiscovery.PAGE_SIZE);
		
//		loader = new StreamPagingLoader(PAGE_SIZE);
		loader.setDataSource(dataSourceManager.getDataSourceByResultType(SpeciesCapability.OCCURRENCESPOINTS));

	}
	

	public void createOccurrencesWindow()
	{
		
		List<ColumnConfig> config = new ArrayList<ColumnConfig>();
		
		for (GridField field:OccurencesGridFields.values()) config.add(Util.createColumnConfig(field, 150));
		
		final ColumnModel cm = new ColumnModel(config);
		
		initLoader();
		
		Grid<ModelData> grid = new Grid<ModelData>(loader.getStore(), cm);  
		grid.setBorders(true);
		grid.getView().setEmptyText(ConstantsSpeciesDiscovery.NORESULTS);

		StreamPagingToolBar toolBar = new StreamPagingToolBar();
		toolBar.bind(loader);
		
		panelOccurrences.setBottomComponent(toolBar);

		panelOccurrences.add(grid);  
	}

	public void loadOccurences()
	{
		Log.trace("Loading occurrences");

		count = 0;
		dataSourceManager.setExpectedOccurencePoints(count);

		SpeciesDiscovery.taxonomySearchService.retrieveOccurencesFromSelection(new AsyncCallback<Integer>() {
			
			@Override
			public void onSuccess(Integer expectedPoints) {
				Log.trace("Expected points: "+expectedPoints);
				dataSourceManager.setExpectedOccurencePoints(expectedPoints);
				
				count = expectedPoints.intValue();
				String items = count>0?"items":"item"; 
				tabItemOccrs.setText(tabItemOccrs.getText() + " ("+count +" "+ items+")");
	
				dataSourceManager.setExpectedOccurencePoints(count);
//				count = expectedPoints;
				loader.startLoading(true);
				
				pollingGetCountOfOcccurrences(count);
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Info.display("Error getting occurrences", "Error getting occurrences, retry");	
				Log.trace("Error getting occurrences", caught);
			}
		});
	}
	
	
	private void pollingGetCountOfOcccurrences(final int allItems){
		
		toolbarOccurrences.add(new SeparatorToolItem());
		final Label labelLoading = new Label("loading 0 of "+allItems);
		labelLoading.setStyleAttribute("paddingLeft", "20px");
		labelLoading.setData("count", new Integer(0));
		toolbarOccurrences.add(labelLoading);
		
		timerGetCountOfOccurrences = new Timer() {
		      @Override
		      public void run() {
		    	  
		  		SpeciesDiscovery.taxonomySearchService.getCountOfOccurrencesBatch(new AsyncCallback<OccurrencesStatus>() {

					@Override
					public void onFailure(Throwable caught) {
						Log.error("Error on loading", "An error occurred on count of occurrence point, retry." +caught.getMessage());
						
					}

					@Override
					public void onSuccess(OccurrencesStatus result) {
						
						int currentValue = ((Integer) labelLoading.getData("count")).intValue();
						
						
						if(result.getSize()>currentValue && result.getSize()<allItems)
							labelLoading.setText("loading "+result.getSize()+ " of " + allItems + " and counting...");
					

						if(result.getSize()==allItems){
							setLabelLoadedText(result.getSize(), allItems);
							stopTimerGetCountOfOccurrences(1000);
						}
						
						//case stream completed
						if(result.isResultEOF()){
							Log.trace("EOF of occurrences is true");
							setLabelLoadedText(result.getSize(), allItems);
							stopTimerGetCountOfOccurrences(2000);
						}
						
						labelLoading.setData("count", result.getSize());
						
						Log.trace("loading " + result.getSize() + " occurrences" );
						
						toolbarOccurrences.layout();
					}

					private void setLabelLoadedText(int size, int allItems) {
						
						String msg = "loaded "+size+ " of " + allItems;
						
						if(size<allItems){
							int difference = allItems - size;
							msg+= " (" + difference + " duplicate or not available occurrence points were discarded)";
						}
							
						labelLoading.setText(msg);
						
					}
					
				});

		      }
		    };

		// Schedule the timer to run once in 1 seconds.
		timerGetCountOfOccurrences.scheduleRepeating(ConstantsSpeciesDiscovery.SCHEDULE_MILLIS_COUNT_OCCURRENCES);
		
//		timerGetCountOfOccurrences.run();
		Log.trace("run timerGetCountOfOccurrences");
		
	}
	
	private void stopTimerGetCountOfOccurrences(int delay) {
		
		Log.trace("stop timerGetCountOfOccurrences");
		Timer timer = new Timer() {
			
			@Override
			public void run() {
//				System.out.println("cancel cancel cancel");
				timerGetCountOfOccurrences.cancel();
				
			}
		};
		timer.schedule(delay);
	}
	
	
	private VerticalPanel createPanelAbout(SpeciesCapability capability, List<String> listDataSourcesFound) {
		
		VerticalPanel verticalPanel = new VerticalPanel();
		verticalPanel.setStyleAttribute("margin", FIVEPX);
		verticalPanel.setStyleAttribute("padding", FIVEPX);
		
		verticalPanel.add(new Html("<p style=\"font-size:12px;\"><b> About Data Sources</b></p><br/>"));
		
		for (String dataSoruceName : listDataSourcesFound) {
			 DataSourceModel dataSource = AdvancedSearchPanelManager.getInstance().findDataSourceByCapabilityAndName(capability, dataSoruceName);
			 Anchor createAbout = createAbout(dataSource,false);
			 if(createAbout!=null)
				 verticalPanel.add(createAbout);
		}
		
		return verticalPanel;
	}

	private VerticalPanel createIndexOfContents(List<String> listScientificName){
		
		VerticalPanel verticalPanel = new VerticalPanel();
		verticalPanel.setStyleAttribute("margin", FIVEPX);
		verticalPanel.setStyleAttribute("padding", FIVEPX);

		int i=0;
		
		for (final String scientificName : listScientificName) {
			
			Anchor anchor = new Anchor(++i +". "+scientificName);
			
			anchor.addClickHandler(new ClickHandler() {
			    public void onClick(ClickEvent event) {
			         com.google.gwt.user.client.Window.Location.assign("#"+scientificName);
			    }
			});
			
			verticalPanel.add(anchor);
		}
		
		return verticalPanel;
	}
	
	private Anchor createAbout(final DataSourceModel ds, boolean insertAboutCitation)
	{
		Anchor anchor = null;

		if(ds!=null){
			String anchorValue = "";
			
			if(insertAboutCitation)
				anchorValue = "<nobr>About "+ds.getName()+"</nobr>";
			else
				anchorValue = "<nobr>"+ds.getName()+"</nobr>";
	
			anchor = new Anchor(anchorValue, true);
			
			anchor.addClickHandler(new ClickHandler() {
				
				@Override
				public void onClick(ClickEvent event) {
					ArrayList<DataSourceModel> list = new ArrayList<DataSourceModel>();
					list.add(ds);
					new WindowCredits("About "+ds.getName(), list);
					
				}
			});
		}
		
		return anchor;
	}
	
	
	private String createTableWithCheckCommonNameDataSource(HashMap<String, ArrayList<String>> hashCommonNameDataSources, ArrayList<String> listDataSourceFound){
		
		
		List<String> listCommonNames = new ArrayList<String>(hashCommonNameDataSources.keySet());
		Collections.sort(listCommonNames, String.CASE_INSENSITIVE_ORDER);
		String table;
	    /*
	      To sort an ArrayList object, use Collection.sort method. This is a
	      static method. It sorts an ArrayList object's elements into ascending order.
	    */
	    Collections.sort(listDataSourceFound);
	    
	    
		//USE FOR DEBUG
//	    System.out.println("############# Common Name size " + listCommonNames.size());
//	    System.out.println("############# Data Source  size " + listDataSourceFound.size());
//	    
//	    for (String dataSource : listDataSourceFound) {
//	    	  System.out.println("############# Data Source  " + dataSource);
//		}		
		
	    if(listCommonNames.size()>0){
	    	
		    int[][] checkCommonNameDataSources = new int[listCommonNames.size()][listDataSourceFound.size()];
			
			//Create a matrix common names / data sources with 1 in coincidence values
			for (int i=0; i< listCommonNames.size(); i++) {
				
				String commonName = listCommonNames.get(i);
				
				ArrayList<String> cmDataSources = hashCommonNameDataSources.get(commonName);
				
				for (String dataSource : cmDataSources) {
//					System.out.println("dataSource " + dataSource);
					int index = listDataSourceFound.indexOf(dataSource);
//					System.out.println("i: " + i + " index " + index);
					checkCommonNameDataSources[i][index] = 1;
				}
				
			}
		
		//USE FOR DEBUG
//	    for (int i=0; i<listCommonNames.size(); i++){
//	        for (int j=0; j<listDataSourceFound.size(); j++) {
//	        	System.out.println(" ############ common name " + listCommonNames.get(i) + " i, j " + checkCommonNameDataSources[i][j]);
//	        }
//		}
		
			table = "<table class=\"simpletable\"\"><tr><th>Common names / Data Sources</th>";
			
			for (String dataSource: listDataSourceFound) {
				
				table+="<th>"+dataSource+"</th>";
			}
			
			table+="</tr>";
		    for (int i=0; i<listCommonNames.size(); i++){
		    	
		    	table+=	"<tr><td class=\"commonname\">"+listCommonNames.get(i)+"</td>";
		    	
		        for (int j=0; j<listDataSourceFound.size(); j++) {
		        	
		        	if(checkCommonNameDataSources[i][j]==1)
		        		table+="<td>"+imageYes.getHTML()+"</td>"; 
		        	else
		        		table+="<td>"+imageNo.getHTML()+"</td>"; 
		        }
		    	table+="</tr>";
			}
		    
			table+="</table>";
		}
	    else
	    	 table = "Not found";
		
		
		return table;
		
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void onHide() {
		super.onHide();
		Scheduler.get().scheduleDeferred(new ScheduledCommand() {
			
			@Override
			public void execute() {
				
				if(loader!=null){
					loader.reset();
					SpeciesDiscovery.taxonomySearchService.stopRetrievingOccurrences(new AsyncCallback<Void>() {

						@Override
						public void onFailure(Throwable caught) {
							Log.error("An error occurred in stopRetrievingOccurrences: " + caught);
							
						}

						@Override
						public void onSuccess(Void result) {
							Log.trace("Stop retrieving Occurrences: OK");
							
						}
					});
				}
				
			}
		});
	}
	
	
	//TEST
	public Button createButtonSaveAsHtml(){
		
		ToolBar toolbar = new ToolBar();

		Button btnExportAsHtml = new Button("Export As Html");
		btnExportAsHtml.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.getSaveProducts()));
		btnExportAsHtml.setToolTip(new ToolTipConfig("Show in Gis Viewer", "Show occurences points from selected results in a Gis Viewer Map."));
		btnExportAsHtml.setScale(ButtonScale.SMALL);  
		btnExportAsHtml.setIconAlign(IconAlign.TOP);  
		btnExportAsHtml.setArrowAlign(ButtonArrowAlign.BOTTOM); 
		btnExportAsHtml.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
//				searchController.getEventBus().fireEvent(new ShowOccurrencesMapEvent());
				
				String html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"> <html>" +
						"<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">" +
						"<style type=\"text/css\">" +getCssStyles() +
						"</style>" +
						"<title>"+searchController.getLastSearchEvent().getSearchTerm()+"</title>" +
						"</head>" +
						"	<body>"+panelDetails.getElement().getInnerHTML()+"</body>" +
						"</html> ";
				
//				System.out.println(html);
			}
		});

		return btnExportAsHtml;

	}
	
	
	private String getCssStyles(){

		return ".button-hyperlink .x-btn-text {" +
				"cursor: pointer !important;" +
				"cursor: hand !important;" +
				"border: none !important;" +
				"/* Disable the button-style */" +
				"background-color: transparent !important;" +
				"background: none !important;" +
				"background-image: none !important;" +
				"padding: 0px !important;" +
				"color: #4784C3 !important;" +
				"font-size: 10px;" +
				"font-family: Serif, \"Times New Roman\", Georgia,;" +
				"text-decoration: underline !important;" +
				"}" +
				".button-hyperlink .x-btn-tl,.button-hyperlink.x-btn-tr,.button-hyperlink " +
				".x-btn-tc,.button-hyperlink .x-btn-ml,.button-hyperlink .x-btn-mr,.button-hyperlink " +
				".x-btn-mc,.button-hyperlink .x-btn-bl,.button-hyperlink .x-btn-br,.button-hyperlink .x-btn-bc" +
				"{" +
				"background-image: none !important;" +
				"background: none !important;" +
				"}" +
				".button-hyperlink .x-btn-small .x-btn-mr, .button-hyperlink .x-btn-small .x-btn-ml,.button-hyperlink .x-btn-small .x-btn-mc," +
				".button-hyperlink .x-btn-small .x-btn-br,.button-hyperlink .x-btn-small .x-btn-bl,.button-hyperlink .x-btn-small .x-btn-bc," +
				".button-hyperlink .x-btn-small .x-btn-tc,.button-hyperlink .x-btn-small .x-btn-tr,.button-hyperlink .x-btn-small .x-btn-tl" +
				"{" +
				"background-image: none !important;" +
				"background: none !important;" +
				"}" +
				".button-hyperlink .x-btn-tl i,.button-hyperlink .x-btn-tr i,.button-hyperlink .x-btn-tc i,.button-hyperlink .x-btn-ml i,.button-hyperlink .x-btn-mr i,.button-hyperlink .x-btn-mc i,.button-hyperlink .x-btn-bl i,.button-hyperlink .x-btn-br i,.button-hyperlink .x-btn-bc i" +
				"{" +
				"font-size: 0px;" +
				"}" +
				"table.imagetable {" +
				"font-family: verdana,arial,sans-serif;" +
				"font-size:10px;" +
				"border: 1px solid #e3e3e3;" +
				"background-color: #f2f2f2;" +
				"width: 100%;" +
				"border-radius: 6px;" +
				"-webkit-border-radius: 6px;" +
				"-moz-border-radius: 6px;" +
				"}" +
				"table.imagetable .title {" +
				"background:#b5cfd2;" +
				"border-width: 1px;" +
				"width: 30%;" +
				"padding: 8px;" +
				"border-style: solid;" +
				"border-color: #999999;" +
				"}" +
				"table.imagetable td {" +
				"background:#dcddc0;" +
				"border-width: 1px;" +
				"padding: 8px;" +
				"border-style: solid;" +
				"border-color: #999999;" +
				"}" +
				"table.imagetable th {" +
				"height: 35px;" +
				"font-weight: bold;" +
				"font-size: 12px;" +
				"}";
	}

	public SearchController getSearchController() {
		return searchController;
	}

}
