package com.harper.util;

import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfReader;

import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.jboss.netty.util.internal.ReusableIterator;

import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.PdfPageNumber;
import com.spire.pdf.PdfPageRotateAngle;
import com.spire.pdf.widget.PdfPageCollection;

import play.Logger;
import play.Play;
import sun.misc.BASE64Decoder;

/**
 * 
 * 
 * 判断PDF文件是否损坏
 * 
 * @author Administrator
 *
 */
public class PdfUtil {
	
	/**
	 * 
	 * 判断pdf 是否损坏
	 * 
	 */
	public static boolean check(String file) {
		boolean flag1 = false;
		int n = 0;
		try {
			Document document = new Document(new PdfReader(file).getPageSize(1));
			document.open();
			PdfReader reader = new PdfReader(file);
			n = reader.getNumberOfPages();
			if (n != 0)
				flag1 = true;
			document.close();
		} catch (Exception e) {
			
		}
		return flag1;
	}
	
   
	/**
	 * 
	 * 
	 * 
	 * 如果原PDF不存在或者损坏 那么就不能返回文件路径
	 * 
	 * @param outputFile (添加了sku后输出的文件路径)
	 * @param input 原始PDF文件
	 * @param waterMarkName 添加的文字信息
	 * 
	 */
	public static String setWatermark(String filename, String inputFilePath, String waterMarkName) {		
		String outputfilepath = Play.configuration.getProperty("applicationPath") + "/file/orderprint/skupdf/" + filename + ".pdf";
		File fileout = new File(outputfilepath);
		try {
			
			if(fileout.exists()){
				fileout.delete();
			}
			
			Boolean status = PdfUtil.check(inputFilePath);			
			File file = new File(inputFilePath);
			if(!file.exists() || !status){
				return "";
			}
			
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputfilepath)));			
			PdfReader reader = new PdfReader(inputFilePath);
			PdfStamper stamper = new PdfStamper(reader, bos);			
			int total = reader.getNumberOfPages() + 1;
			PdfContentByte content;
			BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);			
			for (int i = 1; i < total; i++) {				
				content = stamper.getOverContent(i);
				content.beginText();
				content.setColorFill(Color.black);
				content.setFontAndSize(base, 7);
				content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, 4, 2, 0);
				content.endText();
			}
			stamper.close();
		} catch (Exception e) {

		}
		return outputfilepath;
	}
	
	
	/**
	 * 
	 * 传入一个从代理那里下载的文件流, 然后先将此文件流保存成一个文件 名字选择为传入的 "tracking_D" 保证以后如果形成错误后,可以找回原面单进行后台修改
	 * 
	 * 
	 * @param trackingNo
	 * @param labelPdfBytes
	 * @param x x轴  14
	 * @param y y轴(相对于坐标原点(0,0)) 253
	 * @param height 长度 80
	 * @param width 高度120
	 * @return
	 */
	public static byte[] setWatermarkImage(String trackingNo, byte[] labelPdfBytes, int x, int y, int height, int width) {
		try {			
			//先把文件流形成文件
			String fromOtherPdfFile = Play.configuration.getProperty("applicationPath")+"/file/orderprint/pdf/" + trackingNo+"_D" + ".pdf";                    			
			FileUtils.writeByteArrayToFile(new File(fromOtherPdfFile), labelPdfBytes);
			String outputfilepath = Play.configuration.getProperty("applicationPath")+"/file/orderprint/pdf/"+trackingNo+".pdf";
			Boolean status = PdfUtil.check(fromOtherPdfFile);
			if(!status){
				return labelPdfBytes;
			}			
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputfilepath)));			
			PdfReader reader = new PdfReader(fromOtherPdfFile);
			PdfStamper stamper = new PdfStamper(reader, bos);			
			int total = reader.getNumberOfPages() + 1;
			PdfContentByte content;
			BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
			for (int i = 1; i < total; i++) {				
				content = stamper.getOverContent(i);
				Image image = Image.getInstance(Play.configuration.getProperty("applicationPath")+"/file/imgs/white.png");	            
	            image.setAbsolutePosition(x, y); 
	            image.scaleToFit(height, width);
	            content.addImage(image);
	            content.setColorFill(Color.BLACK);
	            content.setFontAndSize(base, 8);
				content.endText();
			}
			stamper.close();
			
			return FileUtil.fileTobyte(outputfilepath);
			
		} catch (Exception e) {
			return labelPdfBytes;
		}
	}
	
	

	/***
	 * 
	 * 合并PDF
	 * 
	 * 
	 * @param files 传入文件路径数组
	 * @param savepath 形成新的文件路径
	 */
	public static void mergePdfFiles(String[] files, String savepath) {
		try {
			String firstPdf = null;
			int index = 0;
			// 第一个不为空的PDF将成为第一页
			while (firstPdf == null) {
				firstPdf = files[index];
			}
			Document document = new Document(
					new PdfReader(files[0]).getPageSize(1));
			PdfCopy copy = new PdfCopy(document, new FileOutputStream(savepath));
			document.open();
			for (int i = 0; i < files.length; i++) {
				if (files[i] != null) {
					File f = new File(files[i]);
					if (f.exists()) {
						PdfReader reader = null;
						try{
							reader = new PdfReader(files[i]);
						}catch (Exception e) {
							Logger.info(files[i]);
							e.printStackTrace();
						}
						if(reader != null) {
							int n = reader.getNumberOfPages();
							for (int j = 1; j <= n; j++) {
								document.newPage();
								PdfImportedPage page = copy.getImportedPage(reader, j);
								copy.addPage(page);
							}
						}
					}
				}
			}
			document.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 图片转换成PDF
	 * 
	 * @param inputFile
	 * @param outFile
	 * @param x 长 812
	 * @param y 宽 1218
	 */
	public static void pngToPdf(String inputFile, String outFile, int x, int y){		
		try {
			Rectangle rect = new Rectangle(x,y);
			Document document = new Document(rect, 0, 0, 0, 0);
			PdfWriter.getInstance(document, new FileOutputStream(outFile));
			document.open();
			Image image = Image.getInstance(inputFile);
			document.add(image);
			document.close();
		} catch (Exception e) {
			e.printStackTrace();
		} 		
	}
	
	/**
	 * 
	 * byte[] zeroLabelPdfBytes = setwaterImageAndSetMark(
				"C:\\Users\\Administrator\\Desktop\\tdw\\", 
				FileUtil.fileTobyte("C:\\Users\\Administrator\\Desktop\\tmp\\D.pdf"), 
				"C:\\Users\\Administrator\\Desktop\\tmp\\white.png", 
				"深圳夏浦物流有限公司", 
				101, 
				165, 
				82, 
				80);
	 * 
	 * 
	 * 
	 * 
	 * 先将不需要的部分用白色的图片给盖住,然后在盖住的地方打上水印也就是文字(这个方法集成了 PDF图片水印,和PDF文字水印的方式,是上面单纯盖图片和在单纯打水印的升级版)
	 * 
	 * 每次只能做一个操作 (不可以同时盖住多个地方) 每次调用这个方法,都会形成将近4个中间文件出来 ,如果不是特别的需求,建议不要使用(单纯使用盖住,或者单纯使用加水印的方式)
	 * 
	 * 如果只需要盖住某个地方 ,那么就可以不用传入水印文字(或者可以使用上面单纯的盖住某一块的方式,效率比较高)
	 * 
	 * 这个方式比上面单纯加水印的方式优点在于,会直接覆盖之前的文字(用了图片进行覆盖,之前的东西看不到了),单纯的加水印的方式, 之前的那些都还会存在,会重叠
	 * 
	 * 
	 * 
	 * @param filePath 需要保存中间文件的文件夹, 这个文件夹到时候可以找到中间环节的文件, 具体转换过程
	 * @param labelPdfBytes 传入的文件流(实体文件形成的文件流,用FileUtils封装的一个方法进行使用转换) 或者直接从代理那里下载的文件流
	 * @param pngFilepath 盖住图片的文件路径(有时候可以是自己设置的一个logo,或者是一个纯色的png图片)
	 * @param mark 在盖上图片的位置加上水印文字
	 * @param x 相对于原点的坐标 x
	 * @param y 相对于原点的坐标y
	 * @param width 图片的宽度
	 * @param height 图片的高度
	 * 
	 * @return 返回一个做了修改后的文件流 这个文件流可以直接形成文件
	 */
	public static byte[] setwaterImageAndSetMark(String filePath, byte[] labelPdfBytes, String pngFilepath, String mark, int x,int y, int width, int height ){
		byte[] endLabelPdfBytes = null;
		try {
			//首先将传入的文件流形成一个文件
			String saveFirstPathAndFileName =filePath + "first_in_" +  UUID.randomUUID() + ".pdf";
			FileUtils.writeByteArrayToFile(new File(saveFirstPathAndFileName), labelPdfBytes);
			//进行加工处理
			String outputFirstfilepathAndFileName =  filePath + "first_out_" + UUID.randomUUID() + ".pdf";
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputFirstfilepathAndFileName)));			
			PdfReader reader = new PdfReader(saveFirstPathAndFileName);
			PdfStamper stamper = new PdfStamper(reader, bos);			
			int total = reader.getNumberOfPages() + 1;
			PdfContentByte content;
			BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
			for (int i = 1; i < total; i++) {				
				content = stamper.getOverContent(i);
				Image image = Image.getInstance(pngFilepath);	            
	            image.setAbsolutePosition(x, y); 
	            image.scaleToFit(height, width);
	            content.addImage(image);
	            content.setColorFill(Color.BLACK);
	            content.setFontAndSize(base, 8);
				content.endText();
			}
			stamper.close();
			
			//已经覆盖上图片的文件流
			endLabelPdfBytes =  FileUtil.fileTobyte(outputFirstfilepathAndFileName);
			
			
			//然后再将第一次形成的文件流 设置一个水印字体
			String saveTwoFilePathAndFileName =  filePath + "two_in_" + UUID.randomUUID() +".pdf";
			FileUtils.writeByteArrayToFile(new File(saveTwoFilePathAndFileName), endLabelPdfBytes);
			
			String outputTwoFilePathAndFileName = filePath + "two_out_" + UUID.randomUUID() +".pdf";
			BufferedOutputStream bosTwo = new BufferedOutputStream(new FileOutputStream(new File(outputTwoFilePathAndFileName)));
					
			PdfReader readerTwo = new PdfReader(saveTwoFilePathAndFileName);
			PdfStamper stamperTWo = new PdfStamper(readerTwo, bosTwo);			
			int totalTwo = readerTwo.getNumberOfPages() + 1;
			PdfContentByte contentSecond;
			BaseFont baseTwo = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);			
			for (int i = 1; i < totalTwo; i++) {				
				contentSecond = stamperTWo.getOverContent(i);
				contentSecond.beginText();
				contentSecond.setColorFill(Color.BLACK);
				contentSecond.setFontAndSize(baseTwo, 7);
				contentSecond.showTextAligned(Element.ALIGN_LEFT, mark, x, y, 0);
				contentSecond.endText();
			}
			stamperTWo.close();
			
			
			endLabelPdfBytes = FileUtil.fileTobyte(outputTwoFilePathAndFileName);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return endLabelPdfBytes;
	}
	
	/**
	 * PDF 旋转 (只能旋转一个PDF)
	 * @param fromFileName
	 * @param toFileName
	 */
	public static String anglePDF(String oldFileName,String angleFileName){
		if(StringUtils.isBlank(oldFileName)){
			return "";
		}
		
		try {
			// 加载PDF文档
			PdfDocument pdf = new PdfDocument();
			pdf.loadFromFile(oldFileName);
			// 获取第一页
			PdfPageBase page = pdf.getPages().get(0);
			// 获取第一页当前的旋转角度
			int rotateAngle = page.getRotation().getValue();
			// 在当前旋转角度的基础上,将第一页顺时针旋转90度(可选0/90/180/270度)
			rotateAngle+=PdfPageRotateAngle.Rotate_Angle_90.getValue();
			page.setRotation((PdfPageRotateAngle.fromValue(rotateAngle)));
			// 保存文档
			pdf.saveToFile(angleFileName);
			
			return angleFileName;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}		
	}
}