package com.pdflib.cookbook.pcos.interactive;

import com.pdflib.pCOS;
import com.pdflib.pCOSException;
import com.pdflib.cookbook.pcos.pcos_cookbook_example;

/**
 * Determine the total number of file attachments:<br>
 * - document-level attachments; identify PDF packages (collections)<br>
 * - file attachments on all pages).<br>
 * <p>
 * Required software: pCOS interface 3 (pCOS 2.x, PDFlib 7.x, TET 2.2,
 * PLOP 3.x)<br>
 * Required data: PDF document
 *
 * @version $Id: attachments.java,v 1.8 2008/07/04 08:16:10 stm Exp $
 */
public class attachments extends pcos_cookbook_example {

    /* This is where the data files are. Adjust as necessary. */
    private final static String SEARCH_PATH = "../input";

    public void example_code(pCOS p, String filename) throws pCOSException,
        Exception {

        /* Open the PDF document */
        int doc = p.open_document(filename, "");
        if (doc == -1)
            throw new Exception("Error: " + p.get_errmsg());

        System.out.println("File name: " + p.get_string(doc, "filename"));

        int pagecount = (int) p.get_number(doc, "length:pages");

        int filecount = 0;

        /* Check for document file attachments */
        filecount = (int) p.get_number(doc, "length:names/EmbeddedFiles");

        /* Check whether the document represents a PDF package */
        String colltype = p.get_string(doc, "type:/Root/Collection");
        if (colltype.equals("dict")) {
			String defaultdoc;
			System.out.print("PDF package, default document: ");

			/* Check the default document (may be different from container PDF);
             * we currently don't check whether this name is actually present
             * in the list of embedded files.
             */
			if (p.get_string(doc, "type:/Root/Collection/D").equals("string")) {
				defaultdoc = "'" + p.get_string(doc, "/Root/Collection/D") + "'";
			} else
				defaultdoc = "container PDF";

			System.out.println(defaultdoc);
		}

        for (int file = 0; file < filecount; file++) {
            /* Check for Unicode file name (a PDF 1.7 feature) */
            String objtype = p.get_string(doc, "type:names/EmbeddedFiles["
                + file + "]/UF");

            if (objtype.equals("string")) {
                String val = p.get_string(doc,
                    "names/EmbeddedFiles[" + file + "]/UF");
                System.out.println("Document attachment '" + val
                    + "', length "
                    + get_attachment_contents(p, doc,
                        "names/EmbeddedFiles[" + file + "]/EF/F")
                    + " bytes");
            }
            else {
                /* Check for ASCII/native encoded file name */
                objtype = p.get_string(doc,
                    "type:names/EmbeddedFiles[" + file + "]/F");
                if (objtype.equals("string")) {
                    String val = p.get_string(doc,
                        "names/EmbeddedFiles[" + file + "]/F");
                    System.out.println("Document attachment '" + val
                        + "', length "
                        + get_attachment_contents(p, doc,
                            "names/EmbeddedFiles[" + file + "]/EF/F")
                        + " bytes");
                }
            }
        }

        System.out.println(filecount + " document attachments found");
        System.out.println();

        /* Check all pages for annotations of type FileAttachment */
        filecount = 0;

        for (int page = 0; page < pagecount; page++) {
            int annotcount = (int) p.get_number(doc,
                "length:pages[" + page + "]/Annots");

            for (int annot = 0; annot < annotcount; annot++) {
                // pCOS path for a specific annotation on a page
                String page_annotation =
                    "pages[" + page + "]/Annots[" + annot + "]";
                String val = p.get_string(doc, page_annotation + "/Subtype");

                if (val.equals("FileAttachment")) {
                    process_attachment(p, doc, page, page_annotation);
                    filecount++;
                }
            }
        }
        System.out.println(filecount + " attachment annotations found");

        p.close_document(doc);
    }

    /**
     * Prints information about a file attachment and extracts it to disk. <br>
     * The method expects the pCOS path to the attachment in the form
     * "pages[i]/Annots[j]", with i being the page number and j being the number
     * of the annotation of interest on that page.
     *
     * @param p
     *            pCOS object
     * @param doc
     *            pCOS document handle
     * @param page
     *            page number (zero based)
     * @param annotation
     *            pCOS path to the annotation
     *
     * @throws pCOSException
     */
    private void process_attachment(pCOS p, int doc, int page, String annotation)
        throws pCOSException {

        /* Check for Unicode file name (a PDF 1.7 feature) */
        String objtype = p.get_string(doc, "type:" + annotation + "/FS/UF");

        if (objtype.equals("string")) {
            String val = p.get_string(doc, annotation + "/FS/UF");
            System.out.println("Page " + (page + 1) + ", attachment '" + val
                + "', length "
                + get_attachment_contents(p, doc, annotation + "/FS/EF/F")
                + " bytes");
        }
        else {
            /* Check for ASCII/native encoded file name */
            objtype = p.get_string(doc, "type:" + annotation + "/FS/F");
            if (objtype.equals("string")) {
                String val = p.get_string(doc, annotation + "/FS/F");
                System.out.println("Page " + (page + 1) + ", attachment '"
                    + val + "', length "
                    + get_attachment_contents(p, doc, annotation + "/FS/EF/F")
                    + " bytes");
            }
        }
    }

    /**
     * Retrieves the contents of the attachment.
     *
     * @param p
     *            pCOS object
     * @param doc
     *            pCOS document handle
     * @param attachment_stream_path
     *            pCOS path to embedded file stream
     *
     * @return the length of the attachment in bytes
     *
     * @throws pCOSException
     */
    private int get_attachment_contents(pCOS p, int doc,
        String attachment_stream_path) throws pCOSException {
        byte[] attachment_contents =
            p.get_stream(doc, "", attachment_stream_path);

        return attachment_contents.length;
    }

    public attachments(String[] argv, String readable_name, String search_path,
        String full_rcs_file_name, String revision) {
        super(argv, readable_name, search_path, full_rcs_file_name, revision);
    }

    public static void main(String argv[]) {
        attachments example = new attachments(argv, "File attachments",
            SEARCH_PATH, "$RCSfile: attachments.java,v $", "$Revision: 1.8 $");
        example.execute();
    }
}
