package org.gcube.portlets.user.speciesdiscovery.shared.cluster;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.gcube.portlets.user.speciesdiscovery.shared.ResultRow;
import org.gcube.portlets.user.speciesdiscovery.shared.SearchResult;
import org.gcube.portlets.user.speciesdiscovery.shared.util.NormalizeString;

//import com.extjs.gxt.ui.client.widget.Html;

/**
 * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
 *
 */
public class ClusterStructuresForResultRow implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1205113606387863736L;
	
	private ArrayList<String> listResultRowID;
	private Map<String, ResultRow> hashResult = new HashMap<String, ResultRow>();
	private ArrayList<String> listFoundDataSources = new ArrayList<String>();
	private HashMap<String,ClusterCommonNameDataSource<ResultRow>> hashClusterCommonNamesDataSources = new HashMap<String,ClusterCommonNameDataSource<ResultRow>>(); //HASH scientific name - cluster
	private HashMap<String, ArrayList<String>> hashScientificNameResultRowID = new HashMap<String, ArrayList<String>>(); //HASH scientific name - result row ID
	private boolean isReduced;
	private int totalRow;

	public ClusterStructuresForResultRow(){}

	public ClusterStructuresForResultRow(SearchResult<ResultRow> result, boolean isReduced, int totalRow){

		//Create hashMap ID - resultRow
		for (ResultRow row : result.getResults()) {
			hashResult.put(row.getIdToString(), row);
		}
		
		this.isReduced = isReduced;
		this.totalRow = totalRow;
		
		createStructures(result.getResults());
		createStructuresForCommonName();
	}
	
	public void createStructuresForCommonName(){

		if(hashScientificNameResultRowID.size()>0){

			for(String scientificName : hashScientificNameResultRowID.keySet()){
				
				ArrayList<String> listResultRowServiceID = hashScientificNameResultRowID.get(scientificName); //get RR serviceID

				ClusterCommonNameDataSource<ResultRow> cluster = new ClusterCommonNameDataSource<ResultRow>(); //NEW CLUSTER

				for(int i=0; i<listResultRowServiceID.size(); i++){
					ResultRow row = hashResult.get(listResultRowServiceID.get(i));
					cluster.updateHashCommonNamesDataSources(row);
				}

				hashClusterCommonNamesDataSources.put(scientificName, cluster);
			}
		}
		
	}
	
	public void createStructures(ArrayList<ResultRow> arrayListRR){

		if(arrayListRR.size()>0){

			for (ResultRow row : arrayListRR) {

				String keyScientificName = "Name not found";
				
				if(row.getParents().get(0)!=null){
					
					keyScientificName = row.getParents().get(0).getName();
					if(keyScientificName== null || keyScientificName.isEmpty())
						keyScientificName = "Undefined";
					else
						keyScientificName = NormalizeString.lowerCaseUpFirstChar(keyScientificName);
					
					if(hashScientificNameResultRowID.get(keyScientificName)==null){
						
						listResultRowID = new ArrayList<String>(); //USED FOR CLUSTER COMMON NAMES
					}
					else{
						
						listResultRowID = hashScientificNameResultRowID.get(keyScientificName); //USED FOR CLUSTER COMMON NAMES
					}
				}
				
				String dataSource = row.getDataSourceName();

				if(dataSource==null || dataSource.isEmpty())
					dataSource = "Data Source not found";
				
				if(listFoundDataSources.indexOf(dataSource)==-1)
					listFoundDataSources.add(dataSource);
				
				listResultRowID.add(row.getIdToString()+"");
				//USED FOR CLUSTER COMMON NAMES
				hashScientificNameResultRowID.put(keyScientificName, listResultRowID);
			}
		}	
	}
	
	public HashMap<String, ArrayList<String>> getHashClusterScientificNameResultRowID() {
		return hashScientificNameResultRowID;
	}

	public List<String> getListFoundDataSources() {
		return listFoundDataSources;
	}

	public HashMap<String, ClusterCommonNameDataSource<ResultRow>> getHashClusterCommonNamesDataSources() {
		return hashClusterCommonNamesDataSources;
	}

	public List<ResultRow> getResult() {
		return new ArrayList<ResultRow>(hashResult.values());
	}
	
	public ResultRow getResultRowByRowID(String key) {
		return hashResult.get(key);
	}

	public boolean isReduced() {
		return isReduced;
	}

	public void setReduced(boolean isReduced) {
		this.isReduced = isReduced;
	}

	public int getTotalRow() {
		return totalRow;
	}

	public void setTotalRow(int totalRow) {
		this.totalRow = totalRow;
	}

}
