package com.brilliance.isc.doc.utils;

import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class PdfStamperUtil {

    private static Logger logger = LoggerFactory.getLogger(PdfStamperUtil.class);
    private static final float rotation = 30f;


    /**
     * 文字水印
     *
     * @param inflie   原文件
     * @param outfile  水印文件
     * @param words    水印文本
     * @param fontSize 水印文本字体大小
     * @param opcity   水印文本透明度
     * @param color   水印文本颜色
     * @param single   true单条水印，false 满屏水印
     * @param ratio    水印间隔比例，宽fontSize * ratio，高 fontSize*ratio*2
     */
    public static boolean genTextWaterMark(File inflie, File outfile, String words, float fontSize, float opcity,WaterMarkColor color, boolean single, float ratio) {
        InputStream fileOutputStream = null;
        PdfReader reader = null;
        PdfStamper pdfStamper = null;
        try {
            fileOutputStream = new FileInputStream(inflie);
            reader = new PdfReader(fileOutputStream);

            PdfGState pdfGState = new PdfGState();
            pdfGState.setFillOpacity(opcity);

            pdfStamper = new PdfStamper(reader, new FileOutputStream(outfile));
            BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            float wordsWidth = font.getWidthPoint(words, fontSize);

            int pageNum = reader.getNumberOfPages();

            //单水印
            for (int i = 1; i <= pageNum; i++) {
                PdfContentByte overContent = pdfStamper.getOverContent(i);
                overContent.beginText();
                overContent.saveState();
                overContent.setGState(pdfGState);
                overContent.setColorFill(color.baseColor);
                overContent.setFontAndSize(font, fontSize);
                float pageWidth = reader.getPageSize(i).getWidth();
                float pageHeight = reader.getPageSize(i).getHeight();
                Float height = (float) Math.sin(Math.toRadians(rotation)) * wordsWidth;
                Float width = (float) Math.cos(Math.toRadians(rotation)) * wordsWidth;

                if (single) {
                    //单水印
                    float x = (pageWidth - width) / 2;
                    float y = (pageHeight - height) / 2;
                    overContent.showTextAligned(Element.ALIGN_LEFT, words, x, y, rotation);
                } else {
                    //满屏水印
                    int wNum = (int) (pageWidth / (width * (1 + ratio)));
                    int hNum = (int) (pageHeight / (height * (1 + ratio * 2)));

                    for (int j = 0; j <= wNum; j++) {
                        for (int k = 0; k <= hNum; k++) {
                            float x = width * j * (1 + ratio);
                            float y = height * k * (1 + ratio * 2);
                            overContent.showTextAligned(Element.ALIGN_LEFT, words, x, y, rotation);
                        }
                    }

                }
                overContent.endText();

            }


        } catch (IOException | DocumentException e) {
            logger.error("文字水印失败，失败原因：{}", e);
            return false;
        } finally {

            try {
                if (fileOutputStream != null)
                    fileOutputStream.close();
                if (pdfStamper != null) pdfStamper.close();
                if (reader != null) reader.close();
            } catch (IOException | DocumentException e) {
                logger.error("文字水印资源关闭失败：{}", e);
            }


        }
        return true;
    }

    /**
     * @param infile    原文件
     * @param outfile   水印文件
     * @param imgPath   图片水印地址,类相对路径
     * @param imgWidth  图片水印宽
     * @param imgHeigth 图片水印高
     * @param x         坐标x
     * @param y         坐标y
     * @return
     */
    public static boolean genImgWaterMark(File infile, File outfile, String imgPath, float imgWidth, float imgHeigth, float x, float y) {
        InputStream fileOutputStream = null;
        PdfReader reader = null;
        PdfStamper pdfStamper = null;
        try {
            fileOutputStream = new FileInputStream(infile);
            reader = new PdfReader(fileOutputStream);
            pdfStamper = new PdfStamper(reader, new FileOutputStream(outfile));
            URL imgurl = PdfStamperUtil.class.getClassLoader().getResource(imgPath);
            Image image = Image.getInstance(imgurl);
            image.scaleAbsolute(imgWidth, imgHeigth);
            image.setAbsolutePosition(x, y);
            int pageNum = reader.getNumberOfPages();

            for (int i = 1; i <= pageNum; i++) {
                PdfContentByte underContent = pdfStamper.getUnderContent(i);

                underContent.addImage(image);

            }

        } catch (IOException | DocumentException e) {
            logger.error("图片水印失败：", e);
            return false;
        } finally {

            try {
                if (fileOutputStream != null)
                    fileOutputStream.close();
                if (pdfStamper != null) pdfStamper.close();
                if (reader != null) reader.close();
            } catch (IOException | DocumentException e) {
                logger.error("图片水印资源关闭失败：{}", e);
            }


        }
        return true;
    }

    public enum WaterMarkColor {
        RED(BaseColor.RED),
        WHITE(BaseColor.WHITE),
        LIGHT_GRAY(BaseColor.LIGHT_GRAY),
        GRAY(BaseColor.GRAY),
        DARK_GRAY(BaseColor.DARK_GRAY),
        BLACK(BaseColor.BLACK),
        PINK(BaseColor.PINK),
        ORANGE(BaseColor.ORANGE),
        YELLOW(BaseColor.YELLOW),
        GREEN(BaseColor.GREEN),
        BLUE(BaseColor.BLUE);

        WaterMarkColor(BaseColor baseColor) {

            this.baseColor = baseColor;
        }

        private BaseColor baseColor;


    }
}