package technology.tabula;

import com.smppw.modaq.application.components.CustomTabulaTextStripper;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

import java.io.IOException;
import java.util.List;

/**
 * @author wangzaijun
 * @date 2024/9/30 18:08
 * @description 自定义的pdf表格提取，重写的目的是为了让自定义的去水印的文本提起工具生效
 * @see CustomTabulaTextStripper
 */
public class CustomObjectExtractor extends ObjectExtractor {
    private final PDDocument pdfDocument;

    public CustomObjectExtractor(PDDocument pdfDocument) {
        super(pdfDocument);
        this.pdfDocument = pdfDocument;
    }

    @Override
    protected Page extractPage(Integer pageNumber) throws IOException {
        if (pageNumber > pdfDocument.getNumberOfPages() || pageNumber < 1) {
            throw new IndexOutOfBoundsException("Page number does not exist.");
        }
        PDPage page = pdfDocument.getPage(pageNumber - 1);

        ObjectExtractorStreamEngine streamEngine = new ObjectExtractorStreamEngine(page);
        streamEngine.processPage(page);

        // 只要水平或垂直的线条
        List<Ruling> rulings = streamEngine.rulings;
        rulings = rulings.stream().filter(e -> e.horizontal() || e.vertical()).toList();

        // 自定义的文本提取
        CustomTabulaTextStripper textStripper = new CustomTabulaTextStripper(pdfDocument, pageNumber);
        textStripper.process();

        Utils.sort(textStripper.getTextElements(), Rectangle.ILL_DEFINED_ORDER);

        float width, height;
        int rotation = page.getRotation();
        if (Math.abs(rotation) == 90 || Math.abs(rotation) == 270) {
            width = page.getCropBox().getHeight();
            height = page.getCropBox().getWidth();
        } else {
            width = page.getCropBox().getWidth();
            height = page.getCropBox().getHeight();
        }

        return Page.Builder.newInstance()
                .withPageDims(PageDims.of(0, 0, width, height))
                .withRotation(rotation)
                .withNumber(pageNumber)
                .withPdPage(page)
                .withPdDocument(pdfDocument)
                .withRulings(rulings)
                .withTextElements(textStripper.getTextElements())
                .withMinCharWidth(textStripper.getMinCharWidth())
                .withMinCharHeight(textStripper.getMinCharHeight())
                .withIndex(textStripper.getSpatialIndex())
                .build();
    }
}
