/*
 *  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 com.rapidminer.parameter.conditions.EqualTypeCondition;

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 Resize extends BaseProcessingOperator {
	private static final String TYPE_OF_UNIT = "Units";
	private static final String[] TYPES_OF_UNIT = new String[] {
		"%" ,
		"pixels"
		};
	
	private static final String TYPE_OF_INTERPOLATION = "Interpolation";
	private static final String[] TYPES_OF_INTERPOLATION = new String[] {
		"Nearest neighbor", 
		"Bilinear",
		"Pixel area re-sampling", 
		"Bicubic interpolation"
		};
	
	private static final String HEIGHT_PERCENT = "Height %";
	private static final String WIDTH_PERCENT = "Width %";
	private static final String HEIGHT_PX = "Height pixels";
	private static final String WIDTH_PX = "Width pixels";
	
	private static final int UNIT_PERCENT = 0;
	private static final int UNIT_PIXELS = 1;
	
	private static final int INTER_NN = 0;
	private static final int INTER_LINEAR = 1;
	private static final int INTER_AREA = 2;
	private static final int INTER_CUBIC = 3;
	
	
	public Resize(OperatorDescription description) {
		super(description);
	}
	
	@Override
	public IplImage doWork(IplImage cvImg) throws OperatorException {
		int interpolation;
		switch (getParameterAsInt(TYPE_OF_INTERPOLATION)) {
		case INTER_NN:
			interpolation = CV_INTER_NN;
			break;
		case INTER_LINEAR:
			interpolation = CV_INTER_LINEAR;
			break;
		case INTER_AREA:
			interpolation = CV_INTER_AREA;
			break;
		case INTER_CUBIC:
			interpolation = CV_INTER_CUBIC;
			break;

		default:
			interpolation = 0;
			break;
		}
		int newHeight = 0;
		int newWidth = 0;
		
		if(getParameterAsInt(TYPE_OF_UNIT) == UNIT_PIXELS){
			newHeight = getParameterAsInt(HEIGHT_PX);
			newWidth = getParameterAsInt(WIDTH_PX);
		} else {
			newHeight =(int)(cvGetSize(cvImg).height() * getParameterAsDouble(HEIGHT_PERCENT)/100.0);
			newWidth =(int)(cvGetSize(cvImg).width() * getParameterAsDouble(WIDTH_PERCENT)/100.0);
		}
		IplImage outImage = cvCreateImage(cvSize(newWidth,newHeight), cvImg.depth(), 3);
		
		
		 cvResize(cvImg, outImage, interpolation);
		 
		return outImage;
	}
	
	@Override
	public List<ParameterType> getParameterTypes() {
		List<ParameterType> p = super.getParameterTypes();
		p.add(new ParameterTypeCategory(TYPE_OF_INTERPOLATION,
				"Interpolation type",
				TYPES_OF_INTERPOLATION, 0, true));
		p.add(new ParameterTypeCategory(TYPE_OF_UNIT,
				"Units to determine new dimension.",
				TYPES_OF_UNIT, 0, false));
		
		ParameterType heightPer = new ParameterTypeDouble(HEIGHT_PERCENT, "New heigh in percent of original image.", 0, 9999, 50);
		ParameterType widthPer = new ParameterTypeDouble(WIDTH_PERCENT, "New width in percent of original image.", 0, 9999, 50);
		ParameterType heightPx = new ParameterTypeInt(HEIGHT_PX, "New width in percent of original image.", 1, 9999, 600);
		ParameterType widthPx = new ParameterTypeInt(WIDTH_PX, "New width in percent of original image.", 1, 9999, 800);
		
		heightPer.registerDependencyCondition(new EqualTypeCondition(this, TYPE_OF_UNIT, TYPES_OF_UNIT, true, UNIT_PERCENT));
		widthPer.registerDependencyCondition(new EqualTypeCondition(this, TYPE_OF_UNIT, TYPES_OF_UNIT, true, UNIT_PERCENT));
		
		heightPx.registerDependencyCondition(new EqualTypeCondition(this, TYPE_OF_UNIT, TYPES_OF_UNIT, true, UNIT_PIXELS));
		widthPx.registerDependencyCondition(new EqualTypeCondition(this, TYPE_OF_UNIT, TYPES_OF_UNIT, true, UNIT_PIXELS));
		
		p.add(heightPer);
		p.add(widthPer);
		p.add(heightPx);
		p.add(widthPx);
		return p;
	}
}
