// Copyright (C) 2003-2026, Foxit Software Inc..
// All Rights Reserved.
//
// http://www.foxitsoftware.com
//
// The following code is copyrighted and contains proprietary information and trade secrets of Foxit Software Inc..
// You cannot distribute any part of Foxit PDF SDK to any third party or general public,
// unless there is a separate license agreement with Foxit Software Inc. which explicitly grants you such rights.
//
// This file contains an example to demonstrate how to use Foxit PDF SDK to associate files with PDF.

using System;

using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.graphics;
using foxit.pdf.objects;
using foxit.pdf.annots;

namespace associated_filesCS
{
    class associated_files
    {
        static void Main(String[] args)
        {
            string input_path = "../input_files/";
            string output_path = "../output_files/associated_files/";
            System.IO.Directory.CreateDirectory(output_path);
            string sn = "Rew1vB0TqoMIxX444UcpScARWdhgJpsJfzmyMLR32a0+EgrCjp2NaQ==";
            string key = "8f3g1sFttW8NAgfSNv+BvaJWy4Pp8flcm7ncNDkdvCCO4JwUFbGLyZdujReMaiplbYJwwxam3lr7uHtQaEf0xTSu8j2ZBdrZ8FS4OQkEUjOI9UEGb3Ic0GqmlP9T9OnSItOYqoZZA/OnYg5EaVP+c/ha32nUquOk+5riEdhYgINAZDdgJkPc+YSWsrfixOIROf6t34j3eRcyFnOY0MS7tSXi1AEPE0VZdyu+5bfmBSGvLI+WR5lQ+oOQR5hRGwqf990WEdBelNO7dxhZELVhEZ+/L60PpDf5y9A8qmrY6PiEU8nhqIyLpks0BxeIsYyZ3Cr82jjfbItPGyEARsIVzluBSgVMD4oGjojz8T6wGDEXUbmZH/pra94XAs8wZ28mzbmIEppWnhBqX0c6Ov8iXCfFfUZr4KNuPxMEgk4VOYTMOd70GEjGnylivw18hbn7ZpkWh2Zql+uU2HejvOgn+WHvT0HF9NhK0Xb5vH8aFkgBP92PJx8obIbxBVeeExczxvsqWufuPdXS2sPNIgMYZ2TtvqVVsiUToeGB2FQo09fzZOSH5Vi18u/siyvC3FmjeMf4+OYWPuDPNCcrb21NgcHam7XI8AAoGLTGtLLWR+fxynbBBcg2d2ZPcZ5CMFIfOBHRWCkcA0sDT3cl9nsBppHNJze/jVxHy+lREeQEA/etSIgohTGAWW3ZlpibRXqMxlmVWEPifCubbWTzQ6U54mRMpW2UghH3gvCNFNgdday3Av7EtlIJOdUuiMq3zmmd5J4Jt4C82CKnVewA0DtZ4EEtwRG9IYuLrfpuZlnjBAtoeXRV1lqUZ6BcCe0E3m9jO28sGkALuIeJQ74XG7X8lMC7lMWWQYiYD7D6G9QT6X3qV4vXJwNKRKpYc/rI+amEawTSnDYAMEaYPwtZ0rb/7BL+atsZZaI+ncebdfVfjDJZbCZAc+JnkuNlUn2xrNRuObw8h/G0lm2pNOEJ10S8R4+yplo5B1QmC2dCDhaTaW67QJPqnJPKbVmjw7i6KGBi+CDP3JnAKlOX/YUu8uk56JfeQUuGcQg/KaBMGctnchH2n1i3+oGbibhurQj22+OO66Q6mijKoCRP/QJm5WTGcO4c0iVX0B8dIlai/uv/pGU8Wps9MxysH5ViVIj56LWKuNfy1FNO9+wx4iHYnUxfW0Iccq3YJYAlOBkMv8VZIJl9aTEEFJ626LJEw/UbEBdR9CdlwnylPf4RuNW/lcGYMgq3xNVpp/bzYKwZivvQOFgMdX1tv8D33SHvAm3zrRCU+v94BJXnBi9k25fnKsc705IMwv+I6bueXA+mDnagj1oTqsWXZ0WnPAYI3WUO7sBf7XUH230wfYXnTSVhujJxiEP/2oWqi2813gtQkKwz9N2p6yT8Vsh3+BaAwwDvtOZMJKUFcabTBSL6NoouzmzwItJ4mIboT6KXaef66rs8jCU=";
            // Initialize library
            ErrorCode error_code = Library.Initialize(sn, key);
            if (error_code != ErrorCode.e_ErrSuccess)
                Console.WriteLine("Library Initialize Error: {0}\n", error_code);

            // Get information about associated files from PDF document.
            string input_file = input_path + "AF_Catalog_Page_Annot.pdf";
            try {
                using(PDFDoc doc = new PDFDoc(input_file)) {
                    error_code = doc.Load(null);
                    if (error_code != ErrorCode.e_ErrSuccess) {
                        Console.WriteLine("The Doc [" +  input_file + " Error: " +  error_code);
                        return;
                    }

                    using(AssociatedFiles associated_files = new AssociatedFiles(doc))
                    using(PDFDictionary doc_catalog_dict = doc.GetCatalog()) {
                        int count = associated_files.GetAssociatedFilesCount(doc_catalog_dict);
                        Console.WriteLine("The catalog dictionary of \"AF_Catalog_Page_Annot.pdf\" has" + count + " associated files.");
                        using(FileSpec filespec = associated_files.GetAssociatedFile(doc_catalog_dict, 0)) {
                            Console.WriteLine("The file name is \"" + filespec.GetFileName() + "\".");
                            filespec.ExportToFile(output_path + "af_1.txt");
                        }
                        using(PDFPage page = doc.GetPage(0))
                        using(PDFDictionary page_dict = page.GetDict()) {
                            count = associated_files.GetAssociatedFilesCount(page_dict);
                            Console.WriteLine("The page dictionary of \"AF_Catalog_Page_Annot.pdf\" has " + count + " associated files.");
                            using(FileSpec filespec = associated_files.GetAssociatedFile(page_dict, 0)) {
                                Console.WriteLine("The file name is \"" + filespec.GetFileName() + "\".");
                                filespec.ExportToFile(output_path + "af_2.txt");
                            }
                            using(Annot annot = page.GetAnnot(0))
                            using(PDFDictionary annot_dict = annot.GetDict()) {
                                count = associated_files.GetAssociatedFilesCount(annot_dict);
                                Console.WriteLine("The annot dictionary of \"AF_Catalog_Page_Annot.pdf\" has " + count + " associated files.");
                                using(FileSpec filespec = associated_files.GetAssociatedFile(annot_dict, 0)) {
                                    Console.WriteLine("The file name is \"" + filespec.GetFileName() + "\".");
                                    filespec.ExportToFile(output_path + "af_4.txt");
                                }
                            }
                        }
                    }
                }
                } catch (System.Exception e) {
                Console.WriteLine(e.Message);
            }
  
            input_file = input_path + "AF_ImageXObject_FormXObject.pdf";
            try {
                using(PDFDoc doc = new PDFDoc(input_file)) {
                    error_code = doc.Load(null);
                    if (error_code != ErrorCode.e_ErrSuccess) {
                        Console.WriteLine("The Doc [" +  input_file + " Error: " +  error_code);
                        return;
                    }

                    using(AssociatedFiles associated_files = new AssociatedFiles(doc))
                    using(PDFPage page = doc.GetPage(0)) {
                        Progressive progress = page.StartParse((int)PDFPage.ParseFlags.e_ParsePageNormal, null, false);
                        progress.Dispose();
                        long pos = page.GetFirstGraphicsObjectPosition(GraphicsObject.Type.e_TypeImage);
                        using(GraphicsObject image_x_object = page.GetGraphicsObject(pos))
                        using(PDFDictionary image_x_object_dict = image_x_object.GetImageObject().GetStream().GetDictionary()) {
                            int count = associated_files.GetAssociatedFilesCount(image_x_object_dict);
                            Console.WriteLine("The image x object of \"AF_ImageXObject_FormXObject.pdf\" has " + count + " associated files.");
                            using(FileSpec filespec = associated_files.GetAssociatedFile(image_x_object_dict, 0)) {
                                Console.WriteLine("The file name is \"" + filespec.GetFileName() + "\".");
                                filespec.ExportToFile(output_path + "2.jpg");
                            }
                        }
                        pos = page.GetFirstGraphicsObjectPosition(GraphicsObject.Type.e_TypeFormXObject);
                        using(GraphicsObject form_x_object = page.GetGraphicsObject(pos))
                        using(PDFDictionary form_x_object_dict = form_x_object.GetFormXObject().GetStream().GetDictionary()) {
                            int count = associated_files.GetAssociatedFilesCount(form_x_object_dict);
                            Console.WriteLine("The form x object of \"AF_ImageXObject_FormXObject.pdf\" has "+ count + "associated files.");
                            using (FileSpec filespec = associated_files.GetAssociatedFile(form_x_object_dict, 0))
                            {
                                Console.WriteLine("The file name is \"" + filespec.GetFileName() + "\".");
                                filespec.ExportToFile(output_path + "af_6.txt");
                            }
                        }
                    }
                }
            } catch (System.Exception e) {
              Console.WriteLine(e.Message);
            }

            input_file = input_path + "AF_MarkedContent.pdf";
            try
            {
                using (PDFDoc doc = new PDFDoc(input_file))
                {
                    error_code = doc.Load(null);
                    if (error_code != ErrorCode.e_ErrSuccess)
                    {
                        Console.WriteLine("The Doc [" + input_file + " Error: " + error_code);
                        return;
                    }

                    using (AssociatedFiles associated_files = new AssociatedFiles(doc))
                    using (PDFPage page = doc.GetPage(0))
                    {
                        Progressive progress = page.StartParse((int)PDFPage.ParseFlags.e_ParsePageNormal, null, false);
                        progress.Dispose();
                        long pos = page.GetFirstGraphicsObjectPosition(GraphicsObject.Type.e_TypeText);
                        using (GraphicsObject text_object = page.GetGraphicsObject(pos))
                        {
                            int count = associated_files.GetAssociatedFilesCount(text_object);
                            Console.WriteLine("The text object of \"AF_MarkedContent.pdf\" has " + count + " associated files.");
                            using (FileSpec filespec = associated_files.GetAssociatedFile(text_object, 0))
                            {
                                Console.WriteLine("The file name is \"" + filespec.GetFileName() + "\".");
                                filespec.ExportToFile(output_path + "bitmap.bmp");
                            }

                            using (FileSpec filespec = associated_files.GetAssociatedFile(text_object, 1))
                            {
                                Console.WriteLine("The second name is \"" + filespec.GetFileName() + "\".");
                                filespec.ExportToFile(output_path + "text.txt");
                            }
                        }
                    }
                }
            } catch (System.Exception e) {
                Console.WriteLine(e.Message);
            }

            // Associate files with objects in PDF document.
            input_file = input_path + "AssociateTestFile.pdf";
            try
            {
                using (PDFDoc doc = new PDFDoc(input_file))
                {
                    error_code = doc.Load(null);
                    if (error_code != ErrorCode.e_ErrSuccess)
                    {
                        Console.WriteLine("The PDFDoc " + input_file + " Error: " + error_code);
                        return;
                    }

                    using (AssociatedFiles associated_files = new AssociatedFiles(doc))
                    {
                        //Create filespec with 1.txt
                        using (FileSpec filespec_txt = new FileSpec(doc))
                        {
                            filespec_txt.SetAssociteFileRelationship(AssociatedFiles.Relationship.e_RelationshipSource);
                            filespec_txt.SetFileName("1.txt");
                            using (foxit.common.DateTime dateTime = new foxit.common.DateTime(2017, 9, 15, 17, 20, 20, 0, 8, 0))
                            {
                                filespec_txt.SetDescription("text");
                                filespec_txt.Embed(input_path + "1.txt");
                                filespec_txt.SetCreationDateTime(dateTime);
                                filespec_txt.SetModifiedDateTime(dateTime);
                                filespec_txt.SetSubtype("application/octet-stream");


                                //Associate 1.txt with catalog dictionary.
                                {
                                    PDFObject catalog_dict = doc.GetCatalog();
                                    associated_files.AssociateFile(catalog_dict, filespec_txt);
                                    Console.WriteLine("Associate a text file with catalog dictionary.");
                                    using (FileSpec filespec_catalog = associated_files.GetAssociatedFile(catalog_dict, 0))
                                    {
                                        filespec_catalog.ExportToFile(output_path + "catalog.txt");
                                    }
                                }

                                using (PDFPage page = doc.GetPage(0))
                                {
                                    Progressive progress = page.StartParse((int)PDFPage.ParseFlags.e_ParsePageNormal, null, false);
                                    progress.Dispose();
                                    //Associate 1.txt with page dictionary.
                                    {
                                        associated_files.AssociateFile(page, filespec_txt);
                                        Console.WriteLine("Associate a text file with page.");

                                        using (FileSpec filespec_page = associated_files.GetAssociatedFile(page.GetDict(), 0))
                                        {
                                            filespec_page.ExportToFile(output_path + "page.txt");
                                        }
                                    }

                                    //Associate 1.txt with annotation dictionary.
                                    {
                                        using (RectF rect = new RectF(100, 50, 220, 100))
                                        {
                                            using (Annot annot = page.AddAnnot(Annot.Type.e_Note, rect))
                                            {
                                                annot.ResetAppearanceStream();
                                                associated_files.AssociateFile(annot, filespec_txt);
                                                Console.WriteLine("Associate a text file with annotation.");
                                                using (FileSpec filespec_annot = associated_files.GetAssociatedFile(annot.GetDict(), 0))
                                                {
                                                    filespec_annot.ExportToFile(output_path + "annotation.txt");
                                                }
                                            }
                                        }
                                    }

                                    //Create filespec with 2.jpg image.
                                    using (FileSpec filespec_jpg = new FileSpec(doc))
                                    {
                                        filespec_jpg.SetAssociteFileRelationship(AssociatedFiles.Relationship.e_RelationshipSource);
                                        filespec_jpg.SetFileName("2.jpg");
                                        filespec_jpg.SetDescription("jpeg");
                                        filespec_jpg.Embed(input_path + "2.jpg");
                                        filespec_jpg.SetCreationDateTime(dateTime);
                                        filespec_jpg.SetModifiedDateTime(dateTime);
                                        filespec_jpg.SetSubtype("application/octet-stream");


                                        //Associate 2.jpg with marked content.
                                        {
                                            PDFDictionary page_dict = page.GetDict();
                                            PDFObject resource_dict = page_dict.GetElement("Resources");
                                            if (resource_dict == null) return;

                                            Int64 position = page.GetFirstGraphicsObjectPosition(GraphicsObject.Type.e_TypeText);
                                            GraphicsObject text_object = page.GetGraphicsObject(position);
                                            if (text_object != null)
                                            {
                                                MarkedContent markcontent = text_object.GetMarkedContent();
                                                if (markcontent == null) return;

                                                if (markcontent.GetItemCount() == 0)
                                                {
                                                    markcontent.AddItem("Associated", null);
                                                }
                                                associated_files.AssociateFile(text_object, 0, resource_dict, "textobject", filespec_jpg);
                                                page.GenerateContent();

                                                Console.WriteLine("Associate a jpeg file with markcontent.");

                                                using (FileSpec filespec_text_object = associated_files.GetAssociatedFile(text_object, 0))
                                                {
                                                    filespec_text_object.ExportToFile(output_path + "textobject.jpg");
                                                }
                                            }
                                        }


                                        //Associate 2.jpg with image object.
                                        {
                                            Int64 position = page.GetFirstGraphicsObjectPosition(GraphicsObject.Type.e_TypeImage);
                                            using (ImageObject image_oject = page.GetGraphicsObject(position).GetImageObject())
                                            {
                                                if (image_oject != null)
                                                {
                                                    associated_files.AssociateFile(image_oject, filespec_jpg);
                                                    Console.WriteLine("Associate a jpeg file with image xobject.");

                                                    using (FileSpec filespec_image_oject = associated_files.GetAssociatedFile(image_oject.GetStream().GetDictionary(), 0))
                                                    {
                                                        filespec_image_oject.ExportToFile(output_path + "image_x_object.jpg");
                                                    }
                                                }
                                            }
                                        }

                                        //Associate 2.jpg with form XObject.
                                        {
                                            Int64 position = page.GetFirstGraphicsObjectPosition(GraphicsObject.Type.e_TypeFormXObject);
                                            using (FormXObject form_x_object = page.GetGraphicsObject(position).GetFormXObject())
                                            {
                                                if (form_x_object != null)
                                                {
                                                    associated_files.AssociateFile(form_x_object, filespec_jpg);
                                                    Console.WriteLine("Associate a jpeg file with form xobject.");

                                                    using (FileSpec filespec_form_x_object = associated_files.GetAssociatedFile(form_x_object.GetStream().GetDictionary(), 0))
                                                    {
                                                        filespec_form_x_object.ExportToFile(output_path + "form_x_object.jpg");
                                                    }
                                                }
                                            }
                                        }

                                        // Save PDF file
                                        String newPdf = output_path + "associated_files.pdf";
                                        doc.SaveAs(newPdf, (int)PDFDoc.SaveFlags.e_SaveFlagNoOriginal);
                                    }
                                }
                            }

                        }                       
                    }
                }
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Library.Release();
        }
    }
}
