package cokr.xit.fims.cmmn.pdf.print;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;
import org.springframework.core.io.ClassPathResource;

import cokr.xit.foundation.Downloadable;

public class PDFWriter extends PDF {

	public PDFWriter(){
		this.doc = new PDDocument();
	}

	public PDFWriter paper(String type){
		if(type.equals("A4")) {
			this.paperSize = PDRectangle.A4;
		} else if(type.equals("LETTER")) {
			this.paperSize = PDRectangle.LETTER;
		}
		return this;
	}

	public PDRectangle getPaperSize(){
		return this.paperSize;
	}

	public PDType0Font font(String path) throws IOException{
		return PDType0Font.load(doc, new ClassPathResource(path).getInputStream());
	}

	public PDFWriter beginPage() throws IOException {
		PDPage blankPage = new PDPage(paperSize);
		doc.addPage(blankPage);

		// 작업 페이지 설정
		PDPage page = doc.getPage(doc.getNumberOfPages()-1);
		// 컨텐츠 스트림 열기
		contentStream = new PDPageContentStream(doc, page);
		return this;
	}

	public PDFWriter setLineDashPattern(float[] pattern, float phase) throws IOException{
		contentStream.setLineDashPattern(pattern, phase);
		return this;
	}
	public PDFWriter moveTo(float x, float y) throws IOException {
		contentStream.moveTo(x, y);
		return this;
	}

	public PDFWriter lineTo(float x, float y) throws IOException {
		contentStream.lineTo(x, y);
		return this;
	}
	public PDFWriter stroke() throws IOException {
		contentStream.stroke();
		return this;
	}
	public PDFWriter beginText() throws IOException {
		contentStream.beginText();
		return this;
	}
	public PDFWriter setFont(PDType0Font font, int fontSize) throws IOException {
		contentStream.setFont(font, fontSize);
		return this;
	}
	public PDFWriter setRenderingMode(RenderingMode fontStyle) throws IOException {
		contentStream.setRenderingMode(fontStyle);
		return this;
	}
	public PDFWriter setNonStrokingColor(PDColor fontColr) throws IOException {
		contentStream.setNonStrokingColor(fontColr);
		return this;
	}
	public PDFWriter newLineAtOffset(float tx, float ty) throws IOException {
		contentStream.newLineAtOffset(tx, ty);
		return this;
	}
	public PDFWriter showText(String text) throws IOException {
		contentStream.showText(text);
		return this;
	}
	public PDFWriter endText() throws IOException {
		contentStream.endText();
		return this;
	}

	public PDFWriter image(InputStream imageStream, float x, float y, float width, float height) throws IOException {
		PDImageXObject image = PDImageXObject.createFromByteArray(doc, imageStream.readAllBytes(), "temp");
		contentStream.drawImage(image, x, y, width, height);
		return this;
	}

	public PDFWriter endPage() throws IOException {
		contentStream.close();
		contentStream = null;
		return this;
	}


	public void write(OutputStream out) {
		try {
			doc.save(out);
			doc.close();
		} catch (Exception e) {
			throw runtimeException(e);
		}
	}

	public File write(String filepath) {
		File file = new File(filepath);
		try (FileOutputStream out = new FileOutputStream(file)) {
			write(out);
			return file;
		} catch (Exception e) {
			throw runtimeException(e);
		}
	}

	public Downloadable getDownloadable() {
		return new Downloadable()
			.setContentType(MIME_TYPE)
			.setWriter(this::write);
	}
}
