package org.openforis.calc.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.openforis.calc.model.ObservationUnit.Type;
import org.openforis.calc.model.ObservationUnitMetadata;
import org.openforis.calc.model.VariableMetadata;
import org.openforis.calc.persistence.InterviewCategoricalValueDao;
import org.openforis.calc.persistence.InterviewDao;
import org.openforis.calc.persistence.InterviewNumericValueDao;
import org.openforis.calc.persistence.PlotFactDao;
import org.openforis.calc.persistence.PlotSectionViewDao;
import org.openforis.calc.persistence.SpecimenCategoricalValueDao;
import org.openforis.calc.persistence.SpecimenDao;
import org.openforis.calc.persistence.SpecimenNumericValueDao;
import org.openforis.calc.persistence.SpecimenViewDao;
import org.openforis.commons.io.flat.FlatDataStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * 
 * @author G. Miceli
 * @author M. Togna
 *
 */
@Service
public class ObservationService extends CalcService {

	@Autowired
	private PlotSectionViewDao plotSectionViewDao;
	@Autowired
	private SpecimenDao specimenDao;
	@Autowired
	private SpecimenNumericValueDao specimenNumericValueDao;
	@Autowired
	private SpecimenCategoricalValueDao specimenCategoricalValueDao;
	@Autowired
	private SpecimenViewDao specimenViewDao;
	@Autowired
	private InterviewDao interviewDao;
	@Autowired
	private InterviewNumericValueDao interviewNumericValueDao;
	@Autowired
	private InterviewCategoricalValueDao interviewCategoricalValueDao;
	@Autowired
	private PlotFactDao specimenFactDao;
	@Autowired
	private TaxonService taxonService;
	
	public enum PlotDistributionCalculationMethod {
		SHARED_PLOT, PRIMARY_SECTION_ONLY;
	}

	public FlatDataStream getSpecimenDataStream(String surveyName, String observationUnitName, String[] fieldNames) {
		ObservationUnitMetadata unitMetadata = getObservationUnitMetadata(surveyName, observationUnitName);
		Collection<VariableMetadata> variables = unitMetadata.getVariableMetadata();
		ObservationUnitMetadata obsUnitParent = unitMetadata.getObsUnitParent();
		Collection<VariableMetadata> parentVariables = null;
		if( obsUnitParent != null ){
			parentVariables = obsUnitParent.getVariableMetadata();
		}
		return specimenViewDao.streamAll(variables, parentVariables, fieldNames, unitMetadata.getObsUnitId());
	}
	
	@Deprecated
	public FlatDataStream getPlotCategoryDistributionStream(String surveyName, String observationUnitName, PlotDistributionCalculationMethod plotDistributionCalculationMethod){
		ObservationUnitMetadata unitMetadata = getObservationUnitMetadata(surveyName, observationUnitName);
		Collection<VariableMetadata> variables = unitMetadata.getVariableMetadata();
		boolean useShares = plotDistributionCalculationMethod == PlotDistributionCalculationMethod.SHARED_PLOT;
		return plotSectionViewDao.streamCategoryDistribution(variables, unitMetadata.getObsUnitId(), useShares);
	}

	@Transactional
	synchronized 
	public void updateSpecimenNumericValue(String surveyName, String obsUnitName, FlatDataStream dataStream, List<String> variableNames) throws IOException {
		List<VariableMetadata> variables = new ArrayList<VariableMetadata>(variableNames.size());
		ObservationUnitMetadata unitMetadata = getObservationUnitMetadata(surveyName, obsUnitName);
		for ( String variableName : variableNames ) {
			VariableMetadata varMetadata = unitMetadata.getVariableMetadataByName(variableName);
			if( varMetadata != null ) {
				variables.add( varMetadata );
			}
		}
		// Integer obsUnitId = varMetadata.getObsUnitId();
		specimenNumericValueDao.updateCurrentValue(unitMetadata.getObsUnitId(), dataStream, variables);
	}
	
	@Deprecated
	@Transactional
	synchronized
	public void updateSpecimenExpFactor(String surveyName, String obsUnitName, FlatDataStream dataStream) throws IOException {
//		ObservationUnitMetadata unitMetadata = getObservationUnitMetadata(surveyName, obsUnitName);
		specimenDao.batchUpdateExpFactor( dataStream );
	}
	

	@Transactional
	synchronized 
	public void removeData(String surveyName, String obsUnitName) throws IOException {
		ObservationUnitMetadata unit = getObservationUnitMetadata(surveyName, obsUnitName);
		if ( unit == null ) {
			return;
		}
		Type type = unit.getObsUnitTypeEnum();
		switch (type) {
		case INTERVIEW:
			interviewNumericValueDao.deleteByObsUnit(unit.getId());
			break;

		default:
			break;
		} 
	}
}

@@ -526,20 +526,199 @@
 nce.Plot
-Fact
+CategoricalValueDao;%0Aimport org.openforis.calc.persistence.PlotFactDao;%0Aimport org.openforis.calc.persistence.PlotNumericVariableDao;%0Aimport org.openforis.calc.persistence.PlotSection
 Dao;%0Aimp
@@ -1420,32 +1420,222 @@
 ao;%0A%09@Autowired%0A
+%09private PlotSectionDao plotSectionDao;%0A%09@Autowired%0A%09private PlotNumericVariableDao plotNumericVariableDao;%0A%09@Autowired%0A%09private PlotCategoricalValueDao plotCategoricalValueDao;%0A%09@Autowired%0A
 %09private Specime
@@ -4802,98 +4802,439 @@
 ;%0A%09%09
-switch (type) %7B%0A%09%09case INTERVIEW:%0A%09%09%09interviewNumericValueDao.deleteByObsUnit(unit.getId()
+int unitId = unit.getId();%0A%09%09switch (type) %7B%0A%09%09case PLOT:%0A%09%09%09plotNumericVariableDao.deleteByObsUnit(unitId);%0A%09%09%09plotCategoricalValueDao.deleteByObsUnit(unitId);%0A%09%09%09break;%0A%09%09case SPECIMEN:%0A%09%09%09specimenNumericValueDao.deleteByObsUnit(unitId);%0A%09%09%09specimenCategoricalValueDao.deleteByObsUnit(unitId);%0A%09%09%09break;%0A%09%09case INTERVIEW:%0A%09%09%09interviewNumericValueDao.deleteByObsUnit(unitId);%0A%09%09%09interviewCategoricalValueDao.deleteByObsUnit(unitId
 );%0A%09
@@ -5242,17 +5242,16 @@
 %09break;%0A
-%0A
 %09%09defaul

Delete all data for one obs unit