/*
 *  Brno University of Technology
 *
 *  Copyright (C) 2009-2010 by Brno University of Technology and the contributors
 *
 *  Complete list of developers available at our web site:
 *
 *       http://spl.utko.feec.vutbr.cz
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/.
 */
package cz.vutbr.feec.utko.opencv.operators.imageProcessing;

import java.util.List;

import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.parameter.ParameterType;
import com.rapidminer.parameter.ParameterTypeCategory;
import com.rapidminer.parameter.ParameterTypeDouble;
import com.rapidminer.parameter.ParameterTypeInt;

import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;


public class AdaptiveThreshold extends BaseProcessingOperator {

	public AdaptiveThreshold(OperatorDescription description) {
		super(description);
	}
	
	private static final String PARAM_OFFSET = "Offset";
	
	private static final String PARAM_MAX_VALUE = "Max value";
	
	private static final String PARAM_TYPE = "Type";

	private static final String PARAM_BLOCK_SIZE = "Block size";
	
	private static final String[] PARAM_TYPES = new String[] {
	    	"Binary",
	    	"Binary inverse",
	    };

	private static final String TYPE_ADAPTIVE_METHOD = "Adaptive metod";
	private static final String[] TYPES_ADAPTIVE_METHOD = {
		"Mean",
		"Gaussian"
	};
	
	@Override
	public IplImage doWork(IplImage original) throws OperatorException
	{
		
		IplImage out = cvCreateImage( cvGetSize(original), IPL_DEPTH_8U, 1 );
		cvCvtColor(original, out,CV_BGR2GRAY);
		
		double offset = getParameterAsDouble(PARAM_OFFSET);
		double max = getParameterAsDouble(PARAM_MAX_VALUE);
		int blockSize =  getParameterAsInt(PARAM_BLOCK_SIZE);
		int type = getParameterAsInt(PARAM_TYPE);
		int ttype = CV_THRESH_BINARY;
		switch (type)
		{
		case 0:
			ttype = CV_THRESH_BINARY;
			break;
		case 1:
			ttype = CV_THRESH_BINARY_INV;
			break;
		default:
			break;
		}
		
		int methodType = getParameterAsInt(TYPE_ADAPTIVE_METHOD);
		int methodTyped = CV_ADAPTIVE_THRESH_MEAN_C;
		switch (methodType) {
		case 0:
			methodTyped = CV_ADAPTIVE_THRESH_MEAN_C;
			break;
		case 1:
			methodTyped = CV_ADAPTIVE_THRESH_GAUSSIAN_C;
			break;

		default:
			break;
		}
		cvAdaptiveThreshold(out, out, max, methodTyped, ttype, blockSize , offset);
		
		return out;
	}
	
	
	@Override
	public List<ParameterType> getParameterTypes()
	{
		List<ParameterType> types = super.getParameterTypes();
		types.add(new ParameterTypeDouble(PARAM_OFFSET, 
				"Offset", 
				0, 255, 3));
		types.add(new ParameterTypeInt(PARAM_BLOCK_SIZE, 
				"Size of processed area.", 
				0, 255, 5));
		types.add(new ParameterTypeDouble(PARAM_MAX_VALUE, 
				"Maximum value", 
				0, 255, 255));
		types.add(new ParameterTypeCategory(TYPE_ADAPTIVE_METHOD, 
				"Types of adaptive methods.", TYPES_ADAPTIVE_METHOD,0));
		types.add(new ParameterTypeCategory(PARAM_TYPE, 
				"Types of thresholding.", PARAM_TYPES,0));
		
		return types;
	}

}
