/*
    Antenna House PDF Tool API V8.0
    Java Interface sample program

    概要：注釈情報の取得

    Copyright 2015-2025 Antenna House, Inc.
*/

package Sample;

import jp.co.antenna.ptl.*;

public class GetAnnots {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (args.length < 1)
        {
            System.out.println("usage: java GetAnnots in-pdf-file [out-attach-file]");
            return;
        }
        String outpathAttach = "";
        if (args.length == 2) {
            outpathAttach = args[1];
        }

        try (PtlParamInput inputFile = new PtlParamInput(args[0]);
             PtlPDFDocument doc = new PtlPDFDocument()) {

            // PDFファイルをロードします。
            doc.load(inputFile);

            try (PtlPages pages = doc.getPages()) //ページコンテナの取得
            {
                // ページコンテナが空かどうか
                if (pages.isEmpty())
                {
                    System.out.println("ページコンテナが空\n");
                    return;
                }

                int numPages = pages.getCount();
                for (int i=0; i < numPages; i++)
                {
                    System.out.println("ページ" + (i+1));

                    try (PtlPage page = pages.get(i))
                    {
                        // 注釈コンテナが空かどうか
                        if (!page.hasAnnots())
                        {
                            System.out.println("注釈なし");
                            continue;
                        }

                        try (PtlAnnots annots = page.getAnnots())
                        {
                            // 注釈数の取得
                            int numAnnots = annots.getCount();
                            System.out.println("注釈数 : " + numAnnots);
                            for (int j=0; j < numAnnots; j++)
                            {
                                try (PtlAnnot annot = annots.get(j)) {
                                    showAnnot(annot, outpathAttach);
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (PtlException pex) {
            System.out.println("PtlException : ErrorCode = " + pex.getErrorCode() + "\n  " + pex.getErrorMessage());
        }
        catch (Exception ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }
        catch (Error ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }
        finally {
            System.out.println("-- 完了 --");
        }
    }

    public static void showAnnot(PtlAnnot annot, String outpathAttach) throws PtlException, Exception, Error
    {
        PtlAnnot.ANNOT_TYPE annotType = annot.getType();
        switch (annotType) {
        case TYPE_TEXT:
            showAnnotText(annot);
            break;
        case TYPE_LINK:
            showAnnotLink(annot);
            break;
        case TYPE_STAMP:
            showAnnotStamp(annot);
            break;
        case TYPE_FILE_ATTACHMENT:
            showAnnotFileAttachment(annot, outpathAttach);
            break;
        default:
            showAnnotOther(annot);
            break;
        }
    }

    public static void showAnnotText(PtlAnnot annot) throws PtlException, Exception, Error
    {
        System.out.println("ANNOT_TYPE = Text ");
        PtlAnnotText annotText = (PtlAnnotText)annot;
        showAnnotCommon(annotText);
        PtlAnnotText.ICON_TYPE iconType = annotText.getIconType();
        switch (iconType) {
        case ICON_COMMENT:
            System.out.println("ICON_TYPE = COMMENT" );
            break;
        case ICON_HELP:
            System.out.println("ICON_TYPE = HELP" );
            break;
        case ICON_INSERT:
            System.out.println("ICON_TYPE = INSERT" );
            break;
        case ICON_KEY:
            System.out.println("ICON_TYPE = KEY" );
            break;
        case ICON_NEWPARAGRAPH:
            System.out.println("ICON_TYPE = NEWPARAGRAPH" );
            break;
        case ICON_NOTE:
            System.out.println("ICON_TYPE = NOTE" );
            break;
        case ICON_PARAGRAPH:
            System.out.println("ICON_TYPE = PARAGRAPH" );
            break;
        case ICON_CUSTOM:
            System.out.println("ICON_TYPE = CUSTOM" );
            break;
        case ICON_UNKNOWN:
            System.out.println("ICON_TYPE = UNKNOWN" );
            break;
        }
        System.out.println("ICON_NAME = \"" + annotText.getIconName() + "\"" );
        showAnnotMarkup(annotText);
    }

    public static void showAnnotLink(PtlAnnot annot) throws PtlException, Exception, Error
    {
        System.out.println("ANNOT_TYPE = Link ");
        PtlAnnotLink annotLink = (PtlAnnotLink)annot;
        showAnnotCommon(annotLink);
        PtlAnnotLink.HIGHLIGHTING_MODE highlight = annotLink.getHighlightMode();
        switch (highlight) {
        case HIGHLIGHTING_MODE_NONE:
            System.out.println("HIGHLIGHTING_MODE = NONE" );
            break;
        case HIGHLIGHTING_MODE_INVERT:
            System.out.println("HIGHLIGHTING_MODE = INVERT" );
            break;
        case HIGHLIGHTING_MODE_OUTLINE:
            System.out.println("HIGHLIGHTING_MODE = OUTLINE" );
            break;
        case HIGHLIGHTING_MODE_PUSH:
            System.out.println("HIGHLIGHTING_MODE = PUSH" );
            break;
        }
        try (PtlDest dest = annotLink.getDest()) {
            showDest(dest);
        }
        try (PtlAction act = annotLink.getAction()) {
            showAction(act);
        }
    }

    public static void showAnnotStamp(PtlAnnot annot) throws PtlException, Exception, Error
    {
        System.out.println("ANNOT_TYPE = Stamp");
        PtlAnnotStamp annotStamp = (PtlAnnotStamp)annot;
        showAnnotCommon(annotStamp);
        PtlAnnotStamp.ICON_TYPE iconType = annotStamp.getIconType();
        switch (iconType) {
        case ICON_APPROVED:
            System.out.println("ICON_TYPE = APPROVED" );
            break;
        case ICON_AS_IS:
            System.out.println("ICON_TYPE = AS_IS" );
            break;
        case ICON_CONFIDENTIAL:
            System.out.println("ICON_TYPE = CONFIDENTIAL" );
            break;
        case ICON_DEPARTMENTAL:
            System.out.println("ICON_TYPE = DEPARTMENTAL" );
            break;
        case ICON_DRAFT:
            System.out.println("ICON_TYPE = DRAFT" );
            break;
        case ICON_EXPERIMENTAL:
            System.out.println("ICON_TYPE = EXPERIMENTAL" );
            break;
        case ICON_EXPIRED:
            System.out.println("ICON_TYPE = EXPIRED" );
            break;
        case ICON_FINAL:
            System.out.println("ICON_TYPE = FINAL" );
            break;
        case ICON_FOR_COMMENT:
            System.out.println("ICON_TYPE = FOR_COMMENT" );
            break;
        case ICON_FOR_PUBLIC_RELEASE:
            System.out.println("ICON_TYPE = FOR_PUBLIC_RELEASE" );
            break;
        case ICON_NOT_APPROVED:
            System.out.println("ICON_TYPE = NOT_APPROVED" );
            break;
        case ICON_NOT_FOR_PUBLIC_RELEASE:
            System.out.println("ICON_TYPE = NOT_FOR_PUBLIC_RELEASE" );
            break;
        case ICON_SOLD:
            System.out.println("ICON_TYPE = SOLD" );
            break;
        case ICON_TOP_SECRET:
            System.out.println("ICON_TYPE = TOP_SECRET" );
            break;
        case ICON_SB_APPROVED:
            System.out.println("ICON_TYPE = SB_APPROVED" );
            break;
        case ICON_SB_COMPLETED:
            System.out.println("ICON_TYPE = SB_COMPLETED" );
            break;
        case ICON_SB_CONFIDENTIAL:
            System.out.println("ICON_TYPE = SB_CONFIDENTIAL" );
            break;
        case ICON_SB_DRAFT:
            System.out.println("ICON_TYPE = SB_DRAFT" );
            break;
        case ICON_SB_FINAL:
            System.out.println("ICON_TYPE = SB_FINAL" );
            break;
        case ICON_SB_FOR_COMMENT:
            System.out.println("ICON_TYPE = SB_FOR_COMMENT" );
            break;
        case ICON_SB_FOR_PUBLIC_RELEASE:
            System.out.println("ICON_TYPE = SB_FOR_PUBLIC_RELEASE" );
            break;
        case ICON_SB_INFORMATIONONLY:
            System.out.println("ICON_TYPE = SB_INFORMATIONONLY" );
            break;
        case ICON_SB_NOT_APPROVED:
            System.out.println("ICON_TYPE = SB_NOT_APPROVED" );
            break;
        case ICON_SB_NOT_FOR_PUBLIC_RELEASE:
            System.out.println("ICON_TYPE = SB_NOT_FOR_PUBLIC_RELEASE" );
            break;
        case ICON_SB_PRELIMINARYRESULTS:
            System.out.println("ICON_TYPE = SB_PRELIMINARYRESULTS" );
            break;
        case ICON_SB_VOID:
            System.out.println("ICON_TYPE = SB_VOID" );
            break;
        case ICON_CUSTOM:
            System.out.println("ICON_TYPE = CUSTOM" );
            break;
        case ICON_UNKNOWN:
            System.out.println("ICON_TYPE = UNKNOWN" );
            break;
        }
        System.out.println("ICON_NAME = \"" + annotStamp.getIconName() + "\"" );
        showAnnotMarkup(annotStamp);
    }

    public static void showAnnotFileAttachment(PtlAnnot annot, String outpathAttach) throws PtlException, Exception, Error
    {
        System.out.println("ANNOT_TYPE = FileAttachment");
        PtlAnnotFileAttachment annotFileAttachment = (PtlAnnotFileAttachment)annot;
        showAnnotCommon(annotFileAttachment);
        PtlAnnotFileAttachment.ICON_TYPE iconType = annotFileAttachment.getIconType();
        switch (iconType) {
        case ICON_GRAPH:
            System.out.println("ICON_TYPE = GRAPH" );
            break;
        case ICON_PAPERCLIP:
            System.out.println("ICON_TYPE = PAPERCLIP" );
            break;
        case ICON_PUSHPIN:
            System.out.println("ICON_TYPE = PUSHPIN" );
            break;
        case ICON_TAG:
            System.out.println("ICON_TYPE = TAG" );
            break;
        case ICON_CUSTOM:
            System.out.println("ICON_TYPE = CUSTOM" );
            break;
        case ICON_UNKNOWN:
            System.out.println("ICON_TYPE = UNKNOWN" );
            break;
        }
        System.out.println("ICON_NAME = \"" + annotFileAttachment.getIconName() + "\"" );
        System.out.println("FILE_NAME = \"" + annotFileAttachment.getFileName() + "\"" );
        if (!outpathAttach.isEmpty()) {
            try (PtlParamOutput outputAttach = new PtlParamOutput(outpathAttach)) {
                annotFileAttachment.writeFile(outputAttach);
            }
        }
        showAnnotMarkup(annotFileAttachment);
    }

    public static void showAnnotOther(PtlAnnot annot) throws PtlException, Exception, Error
    {
        PtlAnnot.ANNOT_TYPE annotType = annot.getType();
        switch (annotType) {
        case TYPE_FREE_TEXT:
            System.out.println("ANNOT_TYPE = FreeText" );
            break;
        case TYPE_LINE:
            System.out.println("ANNOT_TYPE = Line" );
            break;
        case TYPE_SQUARE:
            System.out.println("ANNOT_TYPE = Square" );
            break;
        case TYPE_CIRCLE:
            System.out.println("ANNOT_TYPE = Circle" );
            break;
        case TYPE_POLYGON:
            System.out.println("ANNOT_TYPE = Polygon" );
            break;
        case TYPE_POLYLINE:
            System.out.println("ANNOT_TYPE = Polyline" );
            break;
        case TYPE_HIGHLIGHT:
            System.out.println("ANNOT_TYPE = Highlight" );
            break;
        case TYPE_UNDERLINE:
            System.out.println("ANNOT_TYPE = Underline" );
            break;
        case TYPE_SQUIGGLY:
            System.out.println("ANNOT_TYPE = Squiggly" );
            break;
        case TYPE_STRIKEOUT:
            System.out.println("ANNOT_TYPE = Strikeout" );
            break;
        case TYPE_CARET:
            System.out.println("ANNOT_TYPE = Caret" );
            break;
        case TYPE_INK:
            System.out.println("ANNOT_TYPE = Ink" );
            break;
        case TYPE_SOUND:
            System.out.println("ANNOT_TYPE = Sound" );
            break;
        case TYPE_MOVIE:
            System.out.println("ANNOT_TYPE = Movie" );
            break;
        case TYPE_WIDGET:
            System.out.println("ANNOT_TYPE = Widget" );
            break;
        case TYPE_SCREEN:
            System.out.println("ANNOT_TYPE = Screen" );
            break;
        case TYPE_PRINTER_MARK:
            System.out.println("ANNOT_TYPE = PrinterMark" );
            break;
        case TYPE_TRAP_NETWORK:
            System.out.println("ANNOT_TYPE = TrapNetwork" );
            break;
        case TYPE_WATERMARK:
            System.out.println("ANNOT_TYPE = Watermark" );
            break;
        case TYPE_3D:
            System.out.println("ANNOT_TYPE = 3D" );
            break;
        case TYPE_REDACT:
            System.out.println("ANNOT_TYPE = Redact" );
            break;
        case TYPE_PROJECTION:
            System.out.println("ANNOT_TYPE = Projection" );
            break;
        case TYPE_RICHMEDIA:
            System.out.println("ANNOT_TYPE = Richmedia" );
            break;
        default:
            System.out.println("ANNOT_TYPE = Unknown" );
            break;
        }
        showAnnotCommon(annot);
        if (annot.isMarkup()) {
            showAnnotMarkup(annot);
        }
    }

    public static void showPopup(PtlAnnot annot) throws PtlException, Exception, Error
    {
        System.out.println("ANNOT_TYPE = Popup");
        PtlAnnotPopup annotPopup = (PtlAnnotPopup)annot;
        showAnnotCommon(annotPopup);
        boolean openState = annotPopup.getOpenState();
        if (openState)
            System.out.println("OPEN_STATE == true" );
        else
            System.out.println("OPEN_STATE == false" );
    }

    public static void showAnnotCommon(PtlAnnot annot) throws PtlException, Exception, Error
    {
        try (PtlRect rect = annot.getRect()) {
            System.out.printf("Rcet = %f,%f,%f,%f\n" , rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop());
        }
        System.out.println("TextContents = \"" + annot.getTextContents() + "\"" );
        try (PtlDate date = annot.getDate())
        {
            int year = date.getYear();
            int month = date.getMonth();
            int day = date.getDay();
            int hour = date.getHour();
            int min = date.getMin();
            int sec = date.getSec();
            System.out.printf("Date : %d/%d/%d %d:%d:%d\n", year, month, day, hour, min, sec);
        }
        int flags = annot.getAnnotFlags();
        if ((flags & PtlAnnot.FLAG_INVISIBLE) == PtlAnnot.FLAG_INVISIBLE)
            System.out.println("FLAG_INVISIBLE on" );
        else
            System.out.println("FLAG_INVISIBLE off" );
        if ((flags & PtlAnnot.FLAG_HIDDEN) == PtlAnnot.FLAG_HIDDEN)
            System.out.println("FLAG_HIDDEN on" );
        else
            System.out.println("FLAG_HIDDEN off" );
        if ((flags & PtlAnnot.FLAG_PRINT) == PtlAnnot.FLAG_PRINT)
            System.out.println("FLAG_PRINT on" );
        else
            System.out.println("FLAG_PRINT off" );
        if ((flags & PtlAnnot.FLAG_NOZOOM) == PtlAnnot.FLAG_NOZOOM)
            System.out.println("FLAG_NOZOOM on" );
        else
            System.out.println("FLAG_NOZOOM off" );
        if ((flags & PtlAnnot.FLAG_NOROTATE) == PtlAnnot.FLAG_NOROTATE)
            System.out.println("FLAG_NOROTATE on" );
        else
            System.out.println("FLAG_NOROTATE off" );
        if ((flags & PtlAnnot.FLAG_NOVIEW) == PtlAnnot.FLAG_NOVIEW)
            System.out.println("FLAG_NOVIEW on" );
        else
            System.out.println("FLAG_NOVIEW off" );
        if ((flags & PtlAnnot.FLAG_READONLY) == PtlAnnot.FLAG_READONLY)
            System.out.println("FLAG_READONLY on" );
        else
            System.out.println("FLAG_READONLY off" );
        if ((flags & PtlAnnot.FLAG_LOCKED) == PtlAnnot.FLAG_LOCKED)
            System.out.println("FLAG_LOCKED on" );
        else
            System.out.println("FLAG_LOCKED off" );
        if ((flags & PtlAnnot.FLAG_TOGGLE_NOVIEW) == PtlAnnot.FLAG_TOGGLE_NOVIEW)
            System.out.println("FLAG_TOGGLE_NOVIEW on" );
        else
            System.out.println("FLAG_TOGGLE_NOVIEW off" );
        if ((flags & PtlAnnot.FLAG_LOCKED_CONTENTS) == PtlAnnot.FLAG_LOCKED_CONTENTS)
            System.out.println("FLAG_LOCKED_CONTENTS on" );
        else
            System.out.println("FLAG_LOCKED_CONTENTS off" );
        try (PtlColor color = annot.getColor()) {
            showColor(color);
        }
        try (PtlColor colorI = annot.getInteriorColor()) {
            showColor(colorI);
        }
        PtlAnnot.BORDER_STYLE boderStyle = annot.getBorderStyle();
        switch (boderStyle) {
        case BORDER_SOLID:
            System.out.println("BORDER_STYLE = SOLID" );
            break;
        case BORDER_DASHED:
            System.out.println("BORDER_STYLE = DASHED" );
            break;
        case BORDER_BEVELED:
            System.out.println("BORDER_STYLE = BEVELED" );
            break;
        case BORDER_INSET:
            System.out.println("BORDER_STYLE = INSET" );
            break;
        case BORDER_UNDERLINE:
            System.out.println("BORDER_STYLE = UNDERLINE" );
            break;
        }
        PtlAnnot.BORDER_LINE_WIDTH boderWidth = annot.getBorderWidth();
        switch (boderWidth) {
        case BORDER_WIDTH_NONE:
            System.out.println("BORDER_WIDTH = NONE" );
            break;
        case BORDER_WIDTH_THIN:
            System.out.println("BORDER_WIDTH = THIN" );
            break;
        case BORDER_WIDTH_MIDDLE:
            System.out.println("BORDER_WIDTH = MIDDLE" );
            break;
        case BORDER_WIDTH_THICK:
            System.out.println("BORDER_WIDTH = THICK" );
            break;
        }
    }

    public static void showAnnotMarkup(PtlAnnot annot) throws PtlException, Exception, Error
    {
        PtlAnnotMarkup annotMarkup = (PtlAnnotMarkup)annot;
        System.out.println("MarkUpTitle = \"" + annotMarkup.getMarkUpTitle() + "\"" );
        System.out.println("MarkUpSubj = \"" + annotMarkup.getMarkUpSubj() + "\"" );
        try (PtlDate date = annotMarkup.getMarkUpDate())
        {
            int year = date.getYear();
            int month = date.getMonth();
            int day = date.getDay();
            int hour = date.getHour();
            int min = date.getMin();
            int sec = date.getSec();
            System.out.printf("MarkUpDate : %d/%d/%d %d:%d:%d\n", year, month, day, hour, min, sec);
        }
        System.out.printf("MarkUpCA : %f\n", annotMarkup.getMarkUpCA());
        if (annotMarkup.hasAnnotPopup()) {
            try (PtlAnnotPopup popup = annotMarkup.getAnnotPopup())
            {
                showPopup(popup);
            }
        }
    }

    public static void showColor(PtlColor color) throws PtlException, Exception, Error
    {
        PtlColor.COLOR_TYPE colorType = color.getType();
        switch (colorType) {
        case TYPE_NONE:
             System.out.println("COLOR_TYPE = None" );
             break;
         case TYPE_DEVICE_GRAY:
             PtlColorDeviceGray colorGray = (PtlColorDeviceGray)color;
             System.out.printf("COLOR_TYPE = GRAY(%f)\n" , colorGray.getGray());
             break;
         case TYPE_DEVICE_RGB:
             PtlColorDeviceRGB colorRGB = (PtlColorDeviceRGB)color;
             System.out.printf("COLOR_TYPE = RGB(%f,%f,%f)\n" , colorRGB.getR(), colorRGB.getG(), colorRGB.getB());
             break;
         case TYPE_DEVICE_CMYK:
             PtlColorDeviceCMYK colorCMYK = (PtlColorDeviceCMYK)color;
             System.out.printf("COLOR_TYPE = CMYK(%f,%f,%f,%f)\n" , colorCMYK.getC(), colorCMYK.getM(), colorCMYK.getY(), colorCMYK.getK());
             break;
        }
    }

    public static void showAction(PtlAction act) throws PtlException, Exception, Error
    {
        PtlAction.ACTION_TYPE actType = act.getType();
        switch (actType) {
        case TYPE_GOTO:
            System.out.println("ACTION_TYPE = GOTO" );
            PtlActionGoTo actGoTo = (PtlActionGoTo)act;
            try (PtlDest destGoTo = actGoTo.getDest()) {
                showDest(destGoTo);
            }
            break;
        case TYPE_GOTO_R:
            System.out.println("ACTION_TYPE = GOTOR" );
            PtlActionGoToR actGoToR = (PtlActionGoToR)act;
            try (PtlDest destGoToR = actGoToR.getDest()) {
                showDest(destGoToR);
            }
            String fileName1 = actGoToR.getFileName();
            System.out.printf("GOTOR FILENAME = %s\n", fileName1);
            if (actGoToR.getNewWindowFlag())
                System.out.println("GOTOR NewWindowFlag on" );
            else
                System.out.println("GOTOR NewWindowFlag off" );
            break;
        case TYPE_LAUNCH:
            System.out.println("ACTION_TYPE = LAUNCH" );
            PtlActionLaunch actLaunch = (PtlActionLaunch)act;
            String fileName2 = actLaunch.getFileName();
            System.out.printf("LAUNCH FILENAME = %s\n", fileName2);
            if (actLaunch.getNewWindowFlag())
                System.out.println("LAUNCH NewWindowFlag on" );
            else
                System.out.println("LAUNCH NewWindowFlag off" );
            break;
        case TYPE_URI:
            System.out.println("ACTION_TYPE = URI" );
            PtlActionURI actURI = (PtlActionURI)act;
            String uri = actURI.getURI();
            System.out.printf("URI = %s\n", uri);
            break;
        case TYPE_UNKNOWN:
            System.out.println("ACTION_TYPE = UNKNOWN" );
            break;
        }
    }

    public static void showDest(PtlDest dest) throws PtlException, Exception, Error
    {
        PtlDest.DEST_TYPE destType = dest.getType();
        switch (destType) {
        case TYPE_NONE:
             System.out.println("DEST_TYPE = NONE" );
             break;
         case TYPE_XYZ:
             System.out.println("DEST_TYPE = XYZ" );
             break;
         case TYPE_FIT:
             System.out.println("DEST_TYPE = FIT" );
             break;
         case TYPE_FIT_H:
             System.out.println("DEST_TYPE = FITH" );
             break;
         case TYPE_FIT_V:
             System.out.println("DEST_TYPE = FITV" );
             break;
         case TYPE_FIT_R:
             System.out.println("DEST_TYPE = FITR" );
             break;
         case TYPE_FIT_B:
             System.out.println("DEST_TYPE = FITB" );
             break;
         case TYPE_FIT_BH:
             System.out.println("DEST_TYPE = FITBH" );
             break;
         case TYPE_FIT_BV:
             System.out.println("DEST_TYPE = FITBV" );
             break;
        }
        System.out.printf("DEST_PAGE : %d\n", dest.getPageNumber());
        if (dest.isLeftNull())
            System.out.println("DEST_LEFT = null" );
        else
             System.out.printf("DEST_LEFT : %f\n", dest.getLeft());
        if (dest.isBottomNull())
            System.out.println("DEST_BOTTOM = null" );
        else
             System.out.printf("DEST_BOTTOM : %f\n", dest.getBottom());
        if (dest.isRightNull())
            System.out.println("DEST_RIGHT = null" );
        else
             System.out.printf("DEST_RIGHT : %f\n", dest.getRight());
        if (dest.isTopNull())
            System.out.println("DEST_TOP = null" );
        else
             System.out.printf("DEST_TOP : %f\n", dest.getTop());
        if (dest.isZoomNull())
            System.out.println("DEST_ZOOM = null" );
        else
            System.out.printf("DEST_ZOOM : %f\n", dest.getZoom());
    }
}
