package com.knecon.fforesight.service.viewerdoc.service;

import com.knecon.fforesight.service.viewerdoc.model.Outline;
import com.pdftron.common.PDFNetException;
import com.pdftron.pdf.Action;
import com.pdftron.pdf.Bookmark;
import com.pdftron.pdf.Destination;
import com.pdftron.pdf.PDFDoc;

import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;

@UtilityClass
public class OutlineUtility {

    @SneakyThrows
    public void addOutline(PDFDoc doc, Outline outline) {

        if (outline.getEntries().isEmpty()) {
            return;
        }

        deleteExistingOutline(doc);

        for (Outline.Entry entry : outline.getEntries()) {
            Destination destination = createXyzAction(doc, entry);
            Action action = Action.createGoto(destination);
            Bookmark bookmark = createBookmark(doc, entry, action);
            doc.addRootBookmark(bookmark);
            addChildren(doc, entry, bookmark);
        }

    }


    @SneakyThrows
    private static void addChildren(PDFDoc doc, Outline.Entry parent, Bookmark parentBookmark) {

        if (parent.children().isEmpty()) {
            return;
        }

        for (Outline.Entry entry : parent.children()) {
            Destination destination = createXyzAction(doc, entry);
            Action action = Action.createGoto(destination);
            Bookmark bookmark = createBookmark(doc, entry, action);
            parentBookmark.addChild(bookmark);
            addChildren(doc, entry, bookmark);
        }
    }


    private static Bookmark createBookmark(PDFDoc doc, Outline.Entry entry, Action action) throws PDFNetException {

        Bookmark bookmark = Bookmark.create(doc, entry.name());
        bookmark.setAction(action);
        return bookmark;
    }


    private static Destination createXyzAction(PDFDoc doc, Outline.Entry entry) throws PDFNetException {

        return Destination.createXYZ(doc.getPage(entry.action().pageNumber()), entry.action().position().getX(), entry.action().position().getY(), 1);
    }


    @SneakyThrows
    public static void deleteExistingOutline(PDFDoc doc) {

        Bookmark firstBookmark = doc.getFirstBookmark();
        while (firstBookmark != null && firstBookmark.isValid()) {
            firstBookmark.delete();
            firstBookmark = doc.getFirstBookmark();
        }

    }

}
