//
// pCOS starter:
// Dump information from an existing PDF document
//
// Required software: PDFlib+PDI or PDFlib Personalization Server (PPS)
// Required data: PDF input file
//

using System;
using System.Text;
using PDFlib_dotnet;

class starter_pcos {
    static void Main(string[] args) {

        /* This is where the data files are. Adjust as necessary. */
        String searchpath = "../../../data";

        PDFlib p = null;
        string pdfinput = "pCOS-datasheet.pdf";

        string docoptlist = "requiredmode=minimum";
        int    count;
        int    i, doc;
        string objtype;

        try 
        {
            p = new PDFlib();

            // This means we must check return values of load_font() etc.
            p.set_option("errorpolicy=return");

            // Set the search path for fonts and PDF files 
            p.set_option("SearchPath={{" + searchpath + "}}");

            /* We do not create any output document, so no call to
             * begin_document() is required.
             */

            /* Open the input document */
            if ((doc = p.open_pdi_document(pdfinput, docoptlist)) == -1)
                throw new Exception("Error: " + p.get_errmsg());

            /* --------- general information (always available) */

            String pcosmode = p.pcos_get_string(doc, "pcosmodename");

            Console.WriteLine("   File name: " +
                p.pcos_get_string(doc,"filename"));

            Console.WriteLine(" PDF version: " +
                p.pcos_get_string(doc, "pdfversionstring"));

            Console.WriteLine("  Encryption: " +
                p.pcos_get_string(doc, "encrypt/description"));

            Console.WriteLine("   Master pw: " +
                ((p.pcos_get_number(doc, "encrypt/master") != 0) ? "yes":"no"));

            Console.WriteLine("     User pw: " +
                ((p.pcos_get_number(doc, "encrypt/user") != 0) ? "yes" : "no"));

            Console.WriteLine("Text copying: " +
                ((p.pcos_get_number(doc, "encrypt/nocopy") != 0) ? "no":"yes"));

            Console.WriteLine("  Linearized: " +
                ((p.pcos_get_number(doc, "linearized") != 0) ? "yes" : "no"));

            Console.WriteLine();

            if (pcosmode == "minimum")
            {
                Console.WriteLine(
                    "Minimum mode: no more information available\n");
                return;
            }
            /* --------- more details (requires at least user password) */
            Console.WriteLine("PDF/X status: " + p.pcos_get_string(doc, "pdfx"));

            Console.WriteLine("PDF/A status: " + p.pcos_get_string(doc, "pdfa"));

            bool xfa_present =
                p.pcos_get_string(doc, "type:/Root/AcroForm/XFA") != "null";
            Console.WriteLine("    XFA data: " + (xfa_present ? "yes" : "no"));
        
            Console.WriteLine("  Tagged PDF: " +
                ((p.pcos_get_number(doc, "tagged") != 0) ? "yes" : "no"));

            Console.WriteLine("No. of pages: " +
                (int) p.pcos_get_number(doc, "length:pages"));

            Console.WriteLine(" Page 1 size: width={0:0.000}, height={1:0.000}",
                 p.pcos_get_number(doc, "pages[0]/width"),
                 p.pcos_get_number(doc, "pages[0]/height"));

            count = (int) p.pcos_get_number(doc, "length:fonts");
            Console.WriteLine("No. of fonts: " +  count);

            for (i=0; i < count; i++)
            {
                String fonts;

                fonts = "fonts[" + i + "]/embedded";
                if (p.pcos_get_number(doc, fonts) != 0)
                    Console.Write("embedded ");
                else
                    Console.Write("unembedded ");

                fonts = "fonts[" + i + "]/type";
                Console.Write(p.pcos_get_string(doc, fonts) + " font ");
                fonts = "fonts[" + i + "]/name";
                Console.WriteLine(p.pcos_get_string(doc, fonts));
            }

            Console.WriteLine("");

            bool plainmetadata = 
                p.pcos_get_number(doc, "encrypt/plainmetadata") != 0;

            if (pcosmode == "restricted" && !plainmetadata
                    && p.pcos_get_number(doc, "encrypt/nocopy") != 0)
            {
                Console.Write(
                    "Restricted mode: no more information available");
                return;
            }

            /* ----- document info keys and XMP metadata (requires master pw) */

            count = (int) p.pcos_get_number(doc, "length:/Info");

            for (i=0; i < count; i++)
            {
                String info;
                String key;
                int len;

                info = "type:/Info[" + i + "]";
                objtype = p.pcos_get_string(doc, info);

                info = "/Info[" + i + "].key";
                key = p.pcos_get_string(doc, info);
                len = 12 - key.Length;
                while (len-- > 0) Console.Write(" ");

                Console.Write(key + ": ");

                /* Info entries can be stored as string or name objects */
                if (objtype == "name" || objtype == "string")
                {
                    info = "/Info[" + i + "]";
                    Console.WriteLine("'" + p.pcos_get_string(doc, info) +
                                                        "'");
                }
                else
                {
                    info = "type:/Info[" + i + "]";
                    Console.WriteLine("(" + p.pcos_get_string(doc, info) +
                         " object)");
                }
            }
            Console.WriteLine();
            Console.Write("XMP meta data: ");

            objtype = p.pcos_get_string(doc, "type:/Root/Metadata");
            if (objtype == "stream")
            {
                    byte[] contents;
                    String ustring;

                    contents = p.pcos_get_stream(doc, "", "/Root/Metadata");
                    // This demonstrates Unicode conversion 
                    ustring = p.convert_to_unicode("utf8", contents,
                                                "outputformat=utf16");
                    Console.WriteLine("(" + ustring.Length + " Unicode code points)");
            }
            else
            {
                    Console.WriteLine("not present");
            }

            p.close_pdi_document(doc);
        }

        catch (PDFlibException e)
        {
            // caught exception thrown by PDFlib
            Console.WriteLine("PDFlib exception occurred:\n");
            Console.WriteLine("[{0}] {1}: {2}\n", e.get_errnum(),
                    e.get_apiname(), e.get_errmsg());
        } finally {
            if (p != null) {
                p.Dispose();
            }
        }
    }
}
