/*
 *  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.operator.UserError;
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 Smooth extends BaseProcessingOperator{

	//TODO upravit zobrazovani parametru podle vybraneho rozmazani
	//TODO odstranit padani pri Gauss 10 10 6 6
	private static final String TYPE_OF_SMOOTH = "Type of smooth";
	private static final String[] TYPES_OF_SMOOTH = new String[] { 
		"Simple blur",
		"Simple blur with no scaling", 
		"Median blur", 
		"Gaussian blur", 
		"Bilateral filter"};
	
	private static final String PARAM1 = "size1";
	private static final String PARAM2 = "param2";
	private static final String PARAM3 = "param3";
	private static final String PARAM4 = "param4";
	
	public static final int BLUR_SIMPLE = 0;
	public static final int BLUR_SIMPLE_WSCAL = 1;
	public static final int BLUR_MEDIAN = 2;
	public static final int BLUR_GAUSSIAN = 3;
	public static final int BLUR_BILATERAL = 4;
	
	public Smooth(OperatorDescription description) {
		super(description);
	}
	
	@Override
	public IplImage doWork(IplImage cvImg) throws OperatorException {
		IplImage out = cvCreateImage( cvGetSize(cvImg), IPL_DEPTH_8U, cvImg.nChannels() );
		
		int param1 = getParameterAsInt(PARAM1);
		int param2 = getParameterAsInt(PARAM2);
		double param3 = getParameterAsDouble(PARAM3);
		double param4 = getParameterAsDouble(PARAM4);
		
		int type = getParameterAsInt(TYPE_OF_SMOOTH);
		switch (type) {
		case BLUR_SIMPLE:
			type = CV_BLUR;
			break;
		case BLUR_SIMPLE_WSCAL:
			type = CV_BLUR_NO_SCALE;
			break;
		case BLUR_MEDIAN:
			type = CV_MEDIAN;
			break;
		case BLUR_GAUSSIAN:
			type = CV_GAUSSIAN;
			break;
		case BLUR_BILATERAL:
			type = CV_BILATERAL;
			break;

		default:
			break;
		}
		try {
			cvSmooth(cvImg, out, type, param1, param2, param3, param4);
		} catch (Exception e) {
			throw new UserError(this, 301, e.toString());
		}
		
		
		return out;
		
	}
	
	@Override
	public List<ParameterType> getParameterTypes() {
		List<ParameterType> p = super.getParameterTypes();
		p.add(new ParameterTypeCategory(TYPE_OF_SMOOTH,
				"Type of smooth",
				TYPES_OF_SMOOTH, 0));
		p.add(new ParameterTypeInt(PARAM1, "Param1 refers to size1 from OpenCV cvSmooth api.",1, Integer.MAX_VALUE, 3));
		p.add(new ParameterTypeInt(PARAM2, "Param2 refers to size2 from OpenCV cvSmooth api.", 0, Integer.MAX_VALUE, 0));
		p.add(new ParameterTypeDouble(PARAM3, "Param3 refers to sigma1 from OpenCV cvSmooth api.", 0, Double.MAX_VALUE, 0));
		p.add(new ParameterTypeDouble(PARAM4, "Param4 refers to sigma2 from OpenCV cvSmooth api.", 0, Double.MAX_VALUE, 0));
		return p;
	}
}
