package com.apobates.forum.thumbnail.servlet;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.apobates.forum.thumbnail.ImagePath;
import com.apobates.forum.thumbnail.ThumbConstant;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.image.OverlayBox;
import com.apobates.forum.utils.image.OverlayBox.BoxColor;
import com.apobates.forum.utils.image.OverlayBox.BoxPosition;
import com.apobates.forum.utils.image.OverlayBox.OverlayConfig;
import com.apobates.forum.utils.image.OverlayTextElement.TextElementConfig;

// /cover?dir=$1&amp;file=$2.$4&amp;scale=$3
public class ThumbBuilderServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final Logger logger = LoggerFactory.getLogger(ThumbBuilderServlet.class);
	private String originalDir;
	private String thumbDir;
	private int maxWidth;
	//水印相关的
	private boolean allowWater;
	private float waterOpacity;
	private String waterType;
	private BoxPosition waterPosition;
	
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String scaleParameter = req.getParameter("scale"); //接受:auto|width<x>height
		String imageFileName = req.getParameter("file");
		String directory = req.getParameter("dir");
		//
		if (null==scaleParameter || scaleParameter.isEmpty()) {
			resp.sendError(400, "scale parameter lost");
			return;
		}
		if (imageFileName.isEmpty() || imageFileName.indexOf(".") == -1) {
			resp.sendError(400, "image file is not exist");
			return;
		}
		try {
			String originalImageDirect = getServletContext().getRealPath("/") + originalDir + ThumbConstant.FS;
			String originalImagePath;
			if(!"/".equals(directory)){
				originalImagePath = directory + ThumbConstant.FS + imageFileName;
			}else{
				originalImagePath = imageFileName;
			}
			OverlayBox ob = getWaterOverlayBox();
			//是否裁剪
			int imageWidth = getOriginalImageWidth(originalImageDirect+originalImagePath);
			if(imageWidth <= maxWidth && "auto".equals(scaleParameter)){ 
				logger.info("[Thumb][TBS]图片尺寸不用裁剪");
				if(null == ob){
					RequestDispatcher rd = getServletContext().getRequestDispatcher("/"+ originalDir + ThumbConstant.WEB_FS + originalImagePath);
					rd.forward(req, resp);
				}else{
					try(OutputStream responseOutStream = resp.getOutputStream()){ //20200329@AutoCloseable
						File originalImage = new File(getServletContext().getRealPath("/"+ originalDir + ThumbConstant.WEB_FS + originalImagePath));
						ob.toStream(originalImage, responseOutStream);
					}
				}
				return;
			}
			//裁剪开始
			ImagePath ip = new ImagePath(scaleParameter, (originalImageDirect+originalImagePath), imageWidth, new File(getServletContext().getRealPath("/") + thumbDir + ThumbConstant.FS));
			if (!ip.getImagePhysicalPath().exists()) {
				if(allowWater){
					logger.info("[Thumb][TBS]设置水印");
					ip.water(ob);
				}
				logger.info("[Thumb][TBS]开始裁剪");
				ip.makeThumb();
			}
			logger.info("[Thumb][TBS]裁剪图已经存在无需再裁剪");
			redirectThumbImage(req, resp, ip);
		} catch (IOException e) {
			if(logger.isDebugEnabled()){
				logger.debug("[Thumb][TBS]image thumb create fail");
			}
		}
	}
	private OverlayBox getWaterOverlayBox(){
		if(!allowWater){
			return null;
		}
		if("image".equals(waterType)){
			//图片水印遮盖
			File watermarkImgFile = new File(getServletContext().getRealPath("/watermark/image.png"));
			return OverlayConfig.getDefault().backgroundColor(BoxColor.TRANSPARENT).position(waterPosition).opacity(waterOpacity).isContinueSave(true).image(watermarkImgFile);
		}
		if("text".equals(waterType)){
			Properties p = getTextWatermarkConfig(getServletContext().getRealPath("/watermark/text.properties"));
			if(null != p){
				TextElementConfig tec = TextElementConfig
											.getDefault()
											.fontSize(Commons.stringToInteger(p.getProperty("fontSize"), -1))
											.fontColor(p.getProperty("fontColor"))
											.fontFamily(p.getProperty("fontFamily"))
											.isBold(Boolean.valueOf(p.getProperty("bold")))
											.rectangle(Commons.stringToInteger(p.getProperty("width"), -1), Commons.stringToInteger(p.getProperty("height"), -1));
				return OverlayConfig.getDefault().backgroundColor(BoxColor.TRANSPARENT).position(waterPosition).opacity(waterOpacity).isContinueSave(true).text(p.getProperty("content"), tec);
			}
		}
		return null;
	}
	private Properties getTextWatermarkConfig(String configPath){
		try{
			Properties configProps = new Properties();
			configProps.load(new FileInputStream(configPath));
			return configProps;
		}catch(IOException e){
			return null;
		}
	}
	/**
	 * 获得初始化值
	 */
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		this.originalDir = config.getInitParameter("original"); //原目录
		this.thumbDir = config.getInitParameter("thumb"); //封面目录
		this.maxWidth = 900;
		try{
			maxWidth = Integer.valueOf(config.getInitParameter("maxWidth"));
		}catch(NullPointerException | NumberFormatException e){}
		//水印相关的
		this.allowWater = true;
		try{
			allowWater = Boolean.valueOf(config.getInitParameter("allowWater"));
		}catch(NullPointerException e){}
		this.waterOpacity = 0.5f;
		try{
			waterOpacity = Float.valueOf(config.getInitParameter("waterOpacity"));
			if(waterOpacity > 1.0f || waterOpacity < 0.0f){
				waterOpacity = 0.5f;
			}
		}catch(NullPointerException | NumberFormatException e){}
		this.waterPosition = BoxPosition.BOTTOM_RIGHT;
		try{
			waterPosition = BoxPosition.getInstance(Integer.valueOf(config.getInitParameter("waterPosition")));
			if(null == waterPosition){
				waterPosition = BoxPosition.BOTTOM_RIGHT;
			}
		}catch(NullPointerException | NumberFormatException e){}
		this.waterType = config.getInitParameter("waterType");
	}
	
	/**
	 * 跳转到缩略图地址
	 * 
	 * @param req
	 * @param resp
	 * @param ip
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void redirectThumbImage(HttpServletRequest req, HttpServletResponse resp, ImagePath ip)throws ServletException, IOException {
		RequestDispatcher rd = getServletContext().getRequestDispatcher(ip.getThumbWebHref(thumbDir));
		rd.forward(req, resp);
	}
	
	/**
	 * 计算原始图片的宽度
	 * 
	 * @param originalImagePath 原始图片的物理地址
	 * @return
	 */
	private int getOriginalImageWidth(String originalImagePath){
		int imageWidth = 0;
		try{
			BufferedImage bimg = ImageIO.read(new File(originalImagePath));
			imageWidth = bimg.getWidth();
		}catch(NullPointerException | IOException e){}
		return imageWidth;
	}
}
