package org.sakaiproject.wontovlab.tool.jsf;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIData;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.custom.fileupload.UploadedFile;
import org.sakaiproject.wontovlab.logic.ExternalLogic;
import org.sakaiproject.wontovlab.logic.MaterialLogic;
import org.sakaiproject.wontovlab.model.Drug;
import org.sakaiproject.wontovlab.model.Equipment;
import org.sakaiproject.wontovlab.model.Material;
import org.sakaiproject.wontovlab.model.Solution;

/**
 * This is a backing bean for the JSF app which handles the events and
 * sends the information from the logic layer to the UI
 * @author Sakai App Builder -AZ
 */
public class MaterialBean 
{

	private static Log log = LogFactory.getLog(MaterialBean.class);
	public Locale locale = new Locale("pt", "BR");
	private ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);

	private ExternalLogic externalLogic;
	
	private static final String EQUIPMENT_DEFAULT_TYPE = "";
	private static final String EQUIPMENT_DEFAULT_DESCRIPTION = "";
	private static final String DRUG_DEFAULT_PHYSICAL_STATE = "";
	private static final String DRUG_DEFAULT_CONCENTRATION = "";
	private static final String DRUG_DEFAULT_DESCRIPTION = "";
	private static final String SOLUTION_DEFAULT_DESCRIPTION = "";
	private static final String SOLUTION_DEFAULT_CONCENTRATION = "";
	private static final String MATERIAL_DEFAULT_DOMAIN_ONTOLOGY_REFERENCE = "";
	
	private UIData dataTableDrug;
	private UIData dataTableEquipment;
	private UIData dataTableSolution;
	
	private DataModel listDrug;
	private DataModel listEquipment;
	private DataModel listSolution;
	
	private MaterialWrapper currentMaterial;
	
	private int firstScoreRowDrug;
	private int firstScoreRowEquipment;
	private int firstScoreRowSolution;

	private MaterialLogic materialLogic;

	private String soRadioInsertForm="drug";
	
	private String equipmentType = EQUIPMENT_DEFAULT_TYPE;
	private String equipmentDescription = EQUIPMENT_DEFAULT_DESCRIPTION;
	private String drugPhysicalState = DRUG_DEFAULT_PHYSICAL_STATE;
	private String drugConcentration = DRUG_DEFAULT_CONCENTRATION;
	private String drugDescription = DRUG_DEFAULT_DESCRIPTION;
	private String solutionDescription = SOLUTION_DEFAULT_DESCRIPTION;
	private String solutionConcentration = SOLUTION_DEFAULT_CONCENTRATION;
	private String materialDomainOntologyReference = MATERIAL_DEFAULT_DOMAIN_ONTOLOGY_REFERENCE;
	
	
	private boolean visibleInsertForm=false;
	private boolean visibleDescriptionForm=false;
	private boolean visibleListForm=true;
	
	private UploadedFile materialImage = null;
	
	private String imageName;

	private Map<Long,Object> allMaterialsMap;
	
	private Long selectedEquipment = new Long(-1);
	private Long selectedDrug =  new Long(-1);
	private Long selectedSolution =  new Long(-1);
	
	private String selectedNewMaterialdomainOntologyReference = null;
	

	

	public String getSelectedNewMaterialdomainOntologyReference() {
		return selectedNewMaterialdomainOntologyReference;
	}

	public void setSelectedNewMaterialdomainOntologyReference(
			String selectedNewMaterialdomainOntologyReference) {
		this.selectedNewMaterialdomainOntologyReference = selectedNewMaterialdomainOntologyReference;
	}

	public String getMaterialDomainOntologyReference() {
		return materialDomainOntologyReference;
	}

	public void setMaterialDomainOntologyReference(
			String materialDomainOntologyReference) {
		this.materialDomainOntologyReference = materialDomainOntologyReference;
	}

	public Long getSelectedEquipment() {
		return selectedEquipment;
	}

	public void setSelectedEquipment(Long selectedEquipment) {
		this.selectedEquipment = selectedEquipment;
	}

	public Long getSelectedDrug() {
		return selectedDrug;
	}

	public void setSelectedDrug(Long selectedDrug) {
		this.selectedDrug = selectedDrug;
	}

	public Long getSelectedSolution() {
		return selectedSolution;
	}

	public void setSelectedSolution(Long selectedSolution) {
		this.selectedSolution = selectedSolution;
	}

	public Map<Long, Object> getAllMaterialsMap() {
		return allMaterialsMap;
	}

	public void setAllMaterialsMap(Map<Long, Object> allMaterialsMap) {
		this.allMaterialsMap = allMaterialsMap;
	}

	public UIData getDataTableSolution() {
		return dataTableSolution;
	}

	public void setDataTableSolution(UIData dataTableSolution) {
		this.dataTableSolution = dataTableSolution;
	}

	public void setListSolution(DataModel listSolution) {
		this.listSolution = listSolution;
	}

	public int getFirstScoreRowSolution() {
		return firstScoreRowSolution;
	}


	public String getSolutionDescription() {
		return solutionDescription;
	}

	public void setSolutionDescription(String solutionDescription) {
		this.solutionDescription = solutionDescription;
	}

	public String getSolutionConcentration() {
		return solutionConcentration;
	}

	public void setSolutionConcentration(String solutionConcentration) {
		this.solutionConcentration = solutionConcentration;
	}

	public String getImageName() {
		return imageName;
	}

	public void setImageName(String imageName) {
		this.imageName = imageName;
	}

	public UploadedFile getMaterialImage() {
		return materialImage;
	}

	public void setMaterialImage(UploadedFile materialImage) {
		this.materialImage = materialImage;
	}

	public boolean isVisibleListForm() {
		return visibleListForm;
	}

	public boolean isVisibleDescriptionForm() {
		return visibleDescriptionForm;
	}

	public boolean isVisibleInsertForm() {
		return visibleInsertForm;
	}

	public MaterialWrapper getCurrentMaterial() {
		return currentMaterial;
	}

	public void setCurrentMaterial(MaterialWrapper currentMaterial) {
		this.currentMaterial = currentMaterial;
	}

	public String getSoRadioInsertForm() {
		return soRadioInsertForm;
	}

	public void setSoRadioInsertForm(String soRadioInsertForm) {
		this.soRadioInsertForm = soRadioInsertForm;
	}

	public String getEquipmentType() {
		return equipmentType;
	}

	public void setEquipmentType(String equipmentType) {
		this.equipmentType = equipmentType;
	}

	public String getEquipmentDescription() {
		return equipmentDescription;
	}

	public void setEquipmentDescription(String equipmentDescription) {
		this.equipmentDescription = equipmentDescription;
	}

	public String getDrugPhysicalState() {
		return drugPhysicalState;
	}

	public void setDrugPhysicalState(String drugPhysicalState) {
		this.drugPhysicalState = drugPhysicalState;
	}

	public String getDrugConcentration() {
		return drugConcentration;
	}

	public void setDrugConcentration(String drugConcentration) {
		this.drugConcentration = drugConcentration;
	}

	public String getDrugDescription() {
		return drugDescription;
	}

	public void setDrugDescription(String drugDescription) {
		this.drugDescription = drugDescription;
	}

	public UIData getDataTableDrug() {
		return dataTableDrug;
	}

	public void setDataTableDrug(UIData dataTableDrug) {
		this.dataTableDrug = dataTableDrug;
	}

	public UIData getDataTableEquipment() {
		return dataTableEquipment;
	}

	public void setDataTableEquipment(UIData dataTableEquipment) {
		this.dataTableEquipment = dataTableEquipment;
	}

	public void setListDrug(DataModel listDrug) {
		this.listDrug = listDrug;
	}


	public void setListEquipment(DataModel listEquipment) {
		this.listEquipment = listEquipment;
	}

	public MaterialLogic getMaterialLogic()
	{
		return materialLogic;
	}
	
	
	public void setMaterialLogic(MaterialLogic materialLogic) {
		this.materialLogic = materialLogic;
	}

	
	public void setExternalLogic(ExternalLogic externalLogic) {
		this.externalLogic = externalLogic;
	}


	public MaterialBean() 
	{
	}
	
	public void setInit(boolean x) {
				
		//populando um MAP com todos os materiais do sistema. Ele será usado posteriormente para nao ficar consultando o banco de dados frequentemente
		allMaterialsMap = new HashMap<Long, Object>();
		
		List l = materialLogic.listMaterial(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId());
		
		for (int i = 0; i < l.size(); i++) {
			allMaterialsMap.put( ((Material) l.get(i)).getMaterialId(), l.get(i) );
		}

					
				
	}	
	

	public boolean getCanCreate()
	{
		return materialLogic.canCreateMaterial(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId());
	}
	
	public String processActionList() 
	{
		log.debug("in process action list experiments...");

		visibleDescriptionForm=false;
		visibleInsertForm=false;
		visibleListForm=true;
		
		return "listMaterial";
	}
	
	public String processActionDetail() 
	{
/*		log.debug("in process detailing weblab...");
		currentMaterial = (ExperimentWrapper) dataTable.getRowData();
		
		// set the values to those of the selected item
		experimentName = currentMaterial.getExperiment().getName();
		experimentDescription = currentMaterial.getExperiment().getDescription();
		
		//Verifying if there is a image related to this weblab
		imageName = materialLogic.getExperimentImageName(currentMaterial.getExperiment());
		*/
		return "detailExperiment";
	}
	
	public String processActionBackDetail() 
	{
/*		log.debug("in process back detailing weblab...");
		
		// set the values to those of the selected item
		experimentName = currentMaterial.getExperiment().getName();
		experimentDescription = currentMaterial.getExperiment().getDescription();
		
		//Verifying if there is a image related to this weblab
		imageName = materialLogic.getExperimentImageName(currentMaterial.getExperiment());
		*/
		return "detailExperiment";
	}
	
	public String getCurrentUserDisplayName() {
		return externalLogic.getUserDisplayName(externalLogic.getCurrentUserId());
	}

	public String processActionAdd()
	{
		log.debug("in process action add...");
		FacesContext fc = FacesContext.getCurrentInstance();

		Long materialId = null; //guardará o id de drug ou equipment, dependendo do que foi selecionado. E sera usado mais abaixo para passar como parametro para image
		
		// Test for empty items and don't add them
		if  (soRadioInsertForm.equals("drug")) {
			if (drugDescription != null && !drugDescription.trim().equals("")) {

					String message;
					Drug drug;
			
					if (currentMaterial == null) 
					{
						drug = new Drug();
						// ownerId, locationId, and dateCreated are set in the logic.saveItem
						message = "Droga adicionada com sucesso: " + drugDescription;
					} 
					else {
						drug = currentMaterial.getDrug();
						message = "Droga adicionada com sucesso: " + drugDescription;
					}
			
					drug.setConcentration(new Float(0));
					drug.setDescription(drugDescription);
					drug.setPhysicalState("");
					drug.setOwnerId(externalLogic.getCurrentUserId());
					drug.setDomainOntologyReference(selectedNewMaterialdomainOntologyReference);
					
					materialLogic.saveDrug(drug);
					
					//This variable is loaded when the user logs in TIDIA, so, it is necessary to update it with the new material added
					allMaterialsMap.put( drug.getMaterialId(), drug );
			
			
			materialId = drug.getMaterialId();
			// Reset text
			drugConcentration = DRUG_DEFAULT_CONCENTRATION;
			drugDescription = DRUG_DEFAULT_DESCRIPTION;
			drugPhysicalState = DRUG_DEFAULT_PHYSICAL_STATE;
			
			} 
		}
		
		
		if  (soRadioInsertForm.equals("equipment")) {
			if (equipmentDescription != null && !equipmentDescription.trim().equals("")) {
				
				String message;
				Equipment equipment;
				
				if (currentMaterial == null) 
				{
					equipment = new Equipment();
					// ownerId, locationId, and dateCreated are set in the logic.saveItem
					message = "Equipamento adicionado com sucesso: " + equipmentDescription;
				} 
				else {
					equipment = currentMaterial.getEquipment();
					message = "Equipamento adicionado com sucesso: " + equipmentDescription;
				}
		
				equipment.setDescription(equipmentDescription);
				equipment.setType("");
				equipment.setOwnerId(externalLogic.getCurrentUserId());
				equipment.setDomainOntologyReference(selectedNewMaterialdomainOntologyReference);
				
				materialLogic.saveEquipment(equipment);
				
				//This variable is loaded when the user logs in TIDIA, so, it is necessary to update it with the new material added
				allMaterialsMap.put( equipment.getMaterialId(), equipment );

				materialId = equipment.getMaterialId();
				
				// Reset text
				equipmentDescription = EQUIPMENT_DEFAULT_DESCRIPTION;
				equipmentType = EQUIPMENT_DEFAULT_TYPE;
			}
		}
		
		if  (soRadioInsertForm.equals("solution")) {
			if (solutionDescription != null && !solutionDescription.trim().equals("")) {
				
				String message;
				Solution solution;
				
				if (currentMaterial == null) 
				{
					solution = new Solution();
					// ownerId, locationId, and dateCreated are set in the logic.saveItem
					message = "Solução adicionada com sucesso: " + solutionDescription;
				} 
				else {
					solution = currentMaterial.getSolution();
					message = "Solução adicionada com sucesso: " + solutionDescription;
				}
		
				solution.setDescription(solutionDescription);
				solution.setConcentration(new Float(0));
				solution.setOwnerId(externalLogic.getCurrentUserId());
				solution.setDomainOntologyReference(selectedNewMaterialdomainOntologyReference);
				
				materialLogic.saveSolution(solution);
				
				//This variable is loaded when the user logs in TIDIA, so, it is necessary to update it with the new material added
				allMaterialsMap.put( solution.getMaterialId(), solution );

				materialId = solution.getMaterialId();
				
				// Reset text
				solutionDescription = SOLUTION_DEFAULT_DESCRIPTION;
				solutionConcentration = SOLUTION_DEFAULT_CONCENTRATION;
			}
		}
			
		
		if (materialImage != null) {
			try {
				System.out.println("*************************************** NOME DA IMAGEM: " + materialImage.getName());
				materialLogic.saveMaterialImage(materialId , materialImage.getName(), materialImage.getInputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			} else {
				fc.addMessage("Image", new FacesMessage(FacesMessage.SEVERITY_INFO, "Nenhuma imagem foi selecionada", "Nenhuma imagem foi selecionada"));
			}
		
		visibleInsertForm=false;
		visibleListForm=true;
		
    	selectedDrug = new Long(-1);
    	selectedEquipment = new Long(-1);
    	selectedSolution = new Long(-1);
		
		return "addedMaterial";
	}

	public void processActionNew() 
	{
		currentMaterial = null;
		
		soRadioInsertForm="drug";
		
		// set the values to the new defaults
		drugConcentration = DRUG_DEFAULT_CONCENTRATION;
		drugDescription = DRUG_DEFAULT_DESCRIPTION;
		drugPhysicalState = DRUG_DEFAULT_PHYSICAL_STATE;
		equipmentDescription = EQUIPMENT_DEFAULT_DESCRIPTION;
		equipmentType = EQUIPMENT_DEFAULT_TYPE;
		
		boolean auxiliar=visibleInsertForm;
		if (auxiliar == true) {
			visibleInsertForm=false;
			visibleListForm=true;
		}else{
			visibleInsertForm=true;
			visibleListForm=false;
		}
		
		System.out.println("===========" + visibleInsertForm);
		
	}
	
	public String processActionReturn() {
		visibleDescriptionForm = false;
		visibleListForm = true;
		return "materialList";
	}
	
	
	
	public String processActionDeleteDrug() 
	{
		log.debug("in process action delete drug...");
		currentMaterial = (MaterialWrapper) dataTableDrug.getRowData(); // gets the user selected item
		String drugDescription = currentMaterial.getDrug().getDescription();
		FacesContext fc = FacesContext.getCurrentInstance();
		
		materialLogic.removeDrug(currentMaterial.getDrug());
				
		String message = "Removido: " + drugDescription;
		fc.addMessage("weblabs", new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
		
		currentMaterial = null;
		
		return "deletedDrug";
	}

	public String processActionDeleteEquipment() 
	{
		log.debug("in process action delete equipment...");
		currentMaterial = (MaterialWrapper) dataTableEquipment.getRowData(); // gets the user selected item
		String equipmentDescription = currentMaterial.getEquipment().getDescription();
		FacesContext fc = FacesContext.getCurrentInstance();
		
		materialLogic.removeEquipment(currentMaterial.getEquipment());
				
		String message = "Removido: " + equipmentDescription;
		fc.addMessage("weblabs", new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
		
		currentMaterial = null;
		
		return "deletedEquipment";
	}
	
	public String processActionDeleteSolution() 
	{
		log.debug("in process action delete solution...");
		currentMaterial = (MaterialWrapper) dataTableSolution.getRowData(); // gets the user selected item
		String solutionDescription = currentMaterial.getSolution().getDescription();
		FacesContext fc = FacesContext.getCurrentInstance();
		
		materialLogic.removeSolution(currentMaterial.getSolution());
				
		String message = "Removido: " + solutionDescription;
		fc.addMessage("weblabs", new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
		
		currentMaterial = null;
		
		return "deletedSolution";
	}
	

	
	public String processActionDescriptionDrug() {
		visibleDescriptionForm = true;
		visibleListForm = false;
		
		currentMaterial = (MaterialWrapper) dataTableDrug.getRowData(); // gets the user selected item
		
		// set the values to those of the selected item
		drugPhysicalState = currentMaterial.getDrug().getPhysicalState();
		drugConcentration = currentMaterial.getDrug().getConcentration().toString();
		drugDescription = currentMaterial.getDrug().getDescription();
		materialDomainOntologyReference = currentMaterial.getDrug().getDomainOntologyReference();

		soRadioInsertForm = "drug";
		return "updateMaterial";
	}
	
	public String processActionDescriptionEquipment() {
		visibleDescriptionForm = true;
		visibleListForm = false;
		
		currentMaterial = (MaterialWrapper) dataTableEquipment.getRowData(); // gets the user selected item
		
		// set the values to those of the selected item
		equipmentDescription = currentMaterial.getEquipment().getDescription();
		equipmentType = currentMaterial.getEquipment().getType();
		materialDomainOntologyReference = currentMaterial.getEquipment().getDomainOntologyReference();

		soRadioInsertForm = "equipment";
		return "updateMaterial";
	}
	
	public String processActionDescriptionSolution() {
		visibleDescriptionForm = true;
		visibleListForm = false;
		
		currentMaterial = (MaterialWrapper) dataTableSolution.getRowData(); // gets the user selected item
		
		// set the values to those of the selected item
		solutionDescription = currentMaterial.getSolution().getDescription();
		solutionConcentration = currentMaterial.getSolution().getConcentration().toString();
		materialDomainOntologyReference = currentMaterial.getSolution().getDomainOntologyReference();

		soRadioInsertForm = "solution";
		return "updateMaterial";
	}
	

	
	public String processActionUpdateDrug() 
	{
		
		log.debug("in process action update...");
		currentMaterial = (MaterialWrapper) dataTableDrug.getRowData(); // gets the user selected item
		
		// set the values to those of the selected item
		drugPhysicalState = currentMaterial.getDrug().getPhysicalState();
		drugConcentration = currentMaterial.getDrug().getConcentration().toString();
		drugDescription = currentMaterial.getDrug().getDescription();

		visibleInsertForm = true;
		soRadioInsertForm = "drug";
		return "updateMaterial";

	}
	
	public String processActionUpdateEquipment() 
	{
		
		log.debug("in process action update...");
		currentMaterial = (MaterialWrapper) dataTableEquipment.getRowData(); // gets the user selected item
		
		// set the values to those of the selected item
		equipmentDescription = currentMaterial.getEquipment().getDescription();
		equipmentType = currentMaterial.getEquipment().getType();

		visibleInsertForm = true;
		soRadioInsertForm = "equipment";
		return "updateMaterial";

	}
	
	public String processActionUpdateSolution() 
	{
		log.debug("in process action update...");
		currentMaterial = (MaterialWrapper) dataTableSolution.getRowData(); // gets the user selected item
		
		// set the values to those of the selected item
		solutionDescription = currentMaterial.getSolution().getDescription();
		solutionConcentration = currentMaterial.getSolution().getConcentration().toString();

		visibleInsertForm = true;
		soRadioInsertForm = "solution";
		return "updateMaterial";

	}
	
	
   
	public DataModel getListDrug() 
    {
    	log.debug("wrapping drugs for JSF datatable...");

		listDrug = new ListDataModel(retrieveListDrugs());
		
		return listDrug;
    }
	
	public DataModel getListEquipment() 
    {
    	log.debug("wrapping equipment for JSF datatable...");
		
		listEquipment = new ListDataModel(retrieveListEquipments());
				
		return listEquipment;
    }
	
	public DataModel getListSolution()
	{
    	log.debug("wrapping solutions for JSF datatable...");

		listSolution = new ListDataModel(retrieveListSolutions());
		
		return listSolution;
	}
	
    
	
    private List retrieveListDrugs()
    {
    	List<MaterialWrapper> wrappedMaterials = new ArrayList<MaterialWrapper>();
		List drugs = materialLogic.listDrug(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId());

		for (Iterator iter = drugs.iterator(); iter.hasNext(); ) 
		{
			MaterialWrapper wrapper = new MaterialWrapper((Drug) iter.next());
			// Mark the item if the current user owns it and can delete it
			if( materialLogic.canEditMaterial(wrapper.getDrug(), externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
			{
				wrapper.setCanEdit(true);
			} 
			else 
			{
				wrapper.setCanEdit(false);
			}
			
			if( materialLogic.canDeleteMaterial(wrapper.getDrug(), externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
			{
				wrapper.setCanDelete(true);
			} 
			else 
			{
				wrapper.setCanDelete(false);
			}
			
			
			wrappedMaterials.add(wrapper);
		}
		Collections.sort(wrappedMaterials, new Comparator<MaterialWrapper>()
		{
			public int compare(MaterialWrapper w1, MaterialWrapper w2)
			{
				return w1.getDrug().getMaterialId().compareTo(w2.getDrug().getMaterialId());
			}
		});
		
		
		return wrappedMaterials;
    }
    
    private List retrieveListEquipments()
    {
    	List<MaterialWrapper> wrappedEquipments = new ArrayList<MaterialWrapper>();
		List equipments = materialLogic.listEquipment(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId());
		
		for (Iterator iter = equipments.iterator(); iter.hasNext(); ) 
		{
			MaterialWrapper wrapper = new MaterialWrapper((Equipment) iter.next());
			// Mark the item if the current user owns it and can delete it
			if( materialLogic.canEditMaterial(wrapper.getEquipment(), externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
			{
				wrapper.setCanEdit(true);
			} 
			else 
			{
				wrapper.setCanEdit(false);
			}
			
			if( materialLogic.canDeleteMaterial(wrapper.getEquipment(), externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
			{
				wrapper.setCanDelete(true);
			} 
			else 
			{
				wrapper.setCanDelete(false);
			}
			
			
			wrappedEquipments.add(wrapper);
		}
		Collections.sort(wrappedEquipments, new Comparator<MaterialWrapper>()
		{
			public int compare(MaterialWrapper w1, MaterialWrapper w2)
			{
				return w1.getEquipment().getMaterialId().compareTo(w2.getEquipment().getMaterialId());
			}
		});
		
		return wrappedEquipments;
    }
    
    private List retrieveListSolutions()
    {
    	List<MaterialWrapper> wrappedMaterials = new ArrayList<MaterialWrapper>();
		List solutions = materialLogic.listSolution(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId());

		for (Iterator iter = solutions.iterator(); iter.hasNext(); ) 
		{
			MaterialWrapper wrapper = new MaterialWrapper((Solution) iter.next());
			// Mark the item if the current user owns it and can delete it
			if( materialLogic.canEditMaterial(wrapper.getSolution(), externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
			{
				wrapper.setCanEdit(true);
			} 
			else 
			{
				wrapper.setCanEdit(false);
			}
			
			if( materialLogic.canDeleteMaterial(wrapper.getSolution(), externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
			{
				wrapper.setCanDelete(true);
			} 
			else 
			{
				wrapper.setCanDelete(false);
			}
			
			
			wrappedMaterials.add(wrapper);
		}
		Collections.sort(wrappedMaterials, new Comparator<MaterialWrapper>()
		{
			public int compare(MaterialWrapper w1, MaterialWrapper w2)
			{
				return w1.getSolution().getMaterialId().compareTo(w2.getSolution().getMaterialId());
			}
		});
		
		return wrappedMaterials;
    }

    
    
    public boolean isListDrugsEmpty()
    {
    	if (listDrug == null)
    	{
    		listDrug = new ListDataModel(retrieveListDrugs());
    	}
    	
    	return (listDrug == null || listDrug.getRowCount() == 0) ? true : false; 
    }
    
    public boolean isListEquipmentsEmpty()
    {
    	if (listEquipment == null)
    	{
    		listEquipment = new ListDataModel(retrieveListEquipments());
    	}
    	
    	return (listEquipment == null || listEquipment.getRowCount() == 0) ? true : false; 
    }
    
    public boolean isListSolutionsEmpty()
    {
    	if (listSolution == null)
    	{
    		listSolution = new ListDataModel(retrieveListSolutions());
    	}
    	
    	return (listSolution == null || listSolution.getRowCount() == 0) ? true : false; 
    }
    
    
    public void teste() {
    	List<Material> l = new ArrayList<Material>();
    	l = materialLogic.listMaterial(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId());
    	
    	for (int i = 0; i < l.size(); i++) {
    		
    		System.out.println("-----------> " + l.get(i).getDescription());
    		
    		if (l.get(i) instanceof Drug)
    		{
    			System.out.println("E Droga: id ====> " + ((Drug) l.get(i)).getMaterialId());
    			System.out.println("Descrição Droga: " + ((Drug) l.get(i)).getDescription());
    		}
    		
    		if (l.get(i) instanceof Equipment)
    		{
    			System.out.println("E equipamento: id ====> " + ((Equipment)l.get(i)).getMaterialId());
    			System.out.println("Descrição Equip: " + ((Equipment) l.get(i)).getDescription());
    		}
    	}
    }
    
    // Paging drug
    

    public void changePagingStateDrug(ValueChangeEvent valueChange) 
    {
    	log.error("changePagingState: old=" + valueChange.getOldValue() + ", new=" + valueChange.getNewValue());
    	FacesContext.getCurrentInstance().renderResponse();
    }
        
    public int getFirstRowDrug() 
    {
    	if (log.isDebugEnabled()) log.debug("getFirstRow " + firstScoreRowDrug);
    	return firstScoreRowDrug;
    }
    
    public void setFirstRowDrug(int firstRow) 
    {
    	if (log.isDebugEnabled()) log.debug("setFirstRow from " + firstScoreRowDrug + " to " + firstRow);
    	firstScoreRowDrug = firstRow;
    }
    
    public int getRowCountDrug()
    {
    	return retrieveListDrugs().size();
    }
    

    //paging equipment
    

    public void changePagingStateEquipment(ValueChangeEvent valueChange) 
    {
    	log.error("changePagingState: old=" + valueChange.getOldValue() + ", new=" + valueChange.getNewValue());
    	FacesContext.getCurrentInstance().renderResponse();
    }
        
    public int getFirstRowEquipment() 
    {
    	if (log.isDebugEnabled()) log.debug("getFirstRow " + firstScoreRowEquipment);
    	return firstScoreRowEquipment;
    }
    
    public void setFirstRowEquipment(int firstRow) 
    {
    	if (log.isDebugEnabled()) log.debug("setFirstRow from " + firstScoreRowEquipment + " to " + firstRow);
    	firstScoreRowEquipment = firstRow;
    }
    
    public int getRowCountEquipment()
    {
    	return retrieveListEquipments().size();
    }

    //paging solution
    
    public void changePagingStateSolution(ValueChangeEvent valueChange) 
    {
    	log.error("changePagingState: old=" + valueChange.getOldValue() + ", new=" + valueChange.getNewValue());
    	FacesContext.getCurrentInstance().renderResponse();
    }
        
    public int getFirstRowSolution() 
    {
    	if (log.isDebugEnabled()) log.debug("getFirstRow " + firstScoreRowSolution);
    	return firstScoreRowSolution;
    }
    
    public void setFirstRowSolution(int firstRow) 
    {
    	if (log.isDebugEnabled()) log.debug("setFirstRow from " + firstScoreRowSolution + " to " + firstRow);
    	firstScoreRowSolution = firstRow;
    }
    
    public int getRowCountSolution()
    {
    	return retrieveListSolutions().size();
    }

    

}
