//	Contour - Android drawing teacher application
//	Copyright (C) 2014  Johannes Riedmann
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU 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 General Public License for more details.
//	
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.

package com.j0h1.contour.admin.server;

import java.util.ArrayList;

import org.apache.commons.codec.binary.Base64;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.j0h1.contour.admin.client.service.ImageService;
import com.j0h1.contour.admin.server.dao.DAOImage;
import com.j0h1.contour.admin.server.dao.impl.DAOImageImpl;
import com.j0h1.contour.admin.shared.DAOImageException;
import com.j0h1.contour.admin.shared.domain.Image;

/**
 * RemoteServiceServlet that implements methods defined in ImageService.
 * @author Johannes Riedmann
 *
 */
public class ImageServiceImpl extends RemoteServiceServlet implements ImageService {
	
	private static final long serialVersionUID = 1L;

	@Override
	public void persist(String titleEN, String titleDE, String originalImage,
			String edgeImage) throws DAOImageException {
		DAOImage imageDao = new DAOImageImpl();
		imageDao.persist(titleEN, titleDE, originalImage, edgeImage);
	}

	@Override
	public String generateEdgeImage(String originalImage, String fileEnding,
			int threshold) {
		// load OpenCV Library
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
		
		// convert previously uploaded (original) image String into Mat object
		byte[] originalBytes = Base64.decodeBase64(originalImage.getBytes());		
		Mat mat = Highgui.imdecode(new MatOfByte(originalBytes), Highgui.IMREAD_UNCHANGED);
		
		// perform image processing methods to create edge image
		Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGB2GRAY); // grayscale image
		Imgproc.GaussianBlur(mat, mat, new Size(3, 3), 0); // gaussian blur
		Imgproc.Canny(mat, mat, threshold, 3 * threshold); // edge image
		
		// invert image (get black contours and white background)
		Core.bitwise_not(mat, mat);		
		
		// convert Mat to byte[]
		MatOfByte bytemat = new MatOfByte();
		Highgui.imencode(fileEnding, mat, bytemat);
		byte[] bytes = bytemat.toArray();
		
		// base64 encoding and return encoded String
		byte[] base64Bytes = Base64.encodeBase64(bytes);
		String response = new String(base64Bytes);
		
		return response;
	}

	@Override
	public ArrayList<Image> findAll() throws DAOImageException {
		DAOImage imageDao = new DAOImageImpl();
		return  imageDao.findAll();
	}

	@Override
	public void delete(int imageId) throws DAOImageException {
		DAOImage imageDao = new DAOImageImpl();
		imageDao.delete(imageId);
	}

}
