/*
 * Copyright (c) 2009 University of Tartu
 */
package org.jpmml.manager;

import java.util.*;

import org.dmg.pmml.*;

public class RegressionModelManager extends ModelManager<RegressionModel> {

	private RegressionModel regressionModel = null;

	private RegressionTable regressionTable = null;


	public RegressionModelManager(){
	}

	public RegressionModelManager(PMML pmml){
		this(pmml, find(pmml.getContent(), RegressionModel.class));
	}

	public RegressionModelManager(PMML pmml, RegressionModel regressionModel){
		super(pmml);

		this.regressionModel = regressionModel;
	}

	@Override
	public RegressionModel getModel(){
		ensureNotNull(this.regressionModel);

		return this.regressionModel;
	}

	/**
	 * @throws ModelManagerException If the Model already exists
	 *
	 * @see #getModel()
	 */
	public RegressionModel createModel(MiningFunctionType miningFunction){
		ensureNull(this.regressionModel);

		this.regressionModel = new RegressionModel(new MiningSchema(), miningFunction);

		List<Model> content = getPmml().getContent();
		content.add(this.regressionModel);

		return this.regressionModel;
	}

	public FieldName getTarget(){
		RegressionModel regressionModel = getModel();

		return regressionModel.getTargetFieldName();
	}

	public RegressionModel setTarget(FieldName name){
		RegressionModel regressionModel = getModel();
		regressionModel.setTargetFieldName(name);

		return regressionModel;
	}

	public Double getIntercept(){
		RegressionTable regressionTable = getOrCreateRegressionTable();

		return Double.valueOf(regressionTable.getIntercept());
	}

	public RegressionTable setIntercept(Double intercept){
		RegressionTable regressionTable = getOrCreateRegressionTable();
		regressionTable.setIntercept(intercept.doubleValue());

		return regressionTable;
	}

	public List<NumericPredictor> getNumericPrecictors(){
		RegressionTable regressionTable = getOrCreateRegressionTable();

		return regressionTable.getNumericPredictors();
	}

	public NumericPredictor getNumericPredictor(FieldName name){
		List<NumericPredictor> numericPredictors = getNumericPrecictors();

		for(NumericPredictor numericPredictor : numericPredictors){

			if((numericPredictor.getName()).equals(name)){
				return numericPredictor;
			}
		}

		return null;
	}

	public NumericPredictor addNumericPredictor(FieldName name, Double coefficient){
		RegressionTable regressionTable = getOrCreateRegressionTable();

		NumericPredictor numericPredictor = new NumericPredictor(name, coefficient.doubleValue());
		regressionTable.getNumericPredictors().add(numericPredictor);

		return numericPredictor;
	}

	public RegressionTable getOrCreateRegressionTable(){

		if(this.regressionTable == null){
			RegressionModel regressionModel = getModel();

			List<RegressionTable> regressionTables = regressionModel.getRegressionTables();
			if(regressionTables.isEmpty()){
				RegressionTable regressionTable = new RegressionTable(0d);

				regressionTables.add(regressionTable);
			}

			this.regressionTable = regressionTables.get(0);
		}

		return this.regressionTable;
	}

	@Override
	public Double evaluate(Map<FieldName, ?> parameters){
		double result = 0D;

		result += evaluateIntercept();

		List<NumericPredictor> numericPredictors = getNumericPrecictors();
		for(NumericPredictor numericPredictor : numericPredictors){
			result += evaluateNumericPredictor(numericPredictor, parameters);
		}

		return Double.valueOf(result);
	}

	private double evaluateIntercept(){
		Double intercept = getIntercept();

		if(intercept == null){
			throw new EvaluationException("Missing intercept");
		}

		return intercept.doubleValue();
	}

	private double evaluateNumericPredictor(NumericPredictor numericPredictor, Map<FieldName, ?> parameters){
		Double fieldValue = (Double)getParameterValue(parameters, numericPredictor.getName());

		return numericPredictor.getCoefficient() * fieldValue.doubleValue();
	}
}
@@ -3068,41 +3068,428 @@
 %7D%0A%0A%09
-@Override%0A%09public Double evaluate
+/**%0A%09 * @see #evaluateRegression(Map)%0A%09 */%0A%09@Override%0A%09public Double evaluate(Map%3CFieldName, ?%3E parameters)%7B%0A%09%09RegressionModel regressionModel = getModel();%0A%0A%09%09MiningFunctionType miningFunction = regressionModel.getFunctionName();%0A%09%09switch(miningFunction)%7B%0A%09%09%09case REGRESSION:%0A%09%09%09%09return evaluateRegression(parameters);%0A%09%09%09default:%0A%09%09%09%09break;%0A%09%09%7D%0A%0A%09%09throw new EvaluationException();%0A%09%7D%0A%0A%09public Double evaluateRegression
 (Map

Elaborated the mining function type