// 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 get/set attributes of viewer preference
// and values of metadata in a PDF file.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;

namespace docinfoCS
{
    class TestInfo
    {
        public string input_path = "../input_files/";
        public string output_path = "../output_files/docinfo/";
    };
    class TextDoc
    {
        private FileStream mfile_stream;
        public TextDoc(string file_name, FileMode fill_mode)
        {
            //FileStream F = new FileStream(file_name, FileMode.Open, FileAccess.Read, FileShare.Read);
            mfile_stream = new FileStream(file_name, fill_mode);
        }
        ~TextDoc()
        {
            try
            {
                mfile_stream.Flush();
                mfile_stream.Close();
            }
            catch (System.ObjectDisposedException e)
            {
                string str = e.Message;
            }

        }
        public void Write(string contents)
        {
            byte[] byte_data = System.Text.Encoding.Default.GetBytes(contents);
            // Move file pointer to the end of file.
            mfile_stream.Seek(0, SeekOrigin.End);
            mfile_stream.Write(byte_data, 0, byte_data.Length);
            mfile_stream.Flush();
        }
        public string Read()
        {
            int fs_len = (int)mfile_stream.Length;
            byte[] byte_data = new byte[fs_len];
            int r = mfile_stream.Read(byte_data, 0, byte_data.Length);
            string contents = System.Text.Encoding.UTF8.GetString(byte_data);
            return contents;
        }
    };

    class docinfo
    {
        public static DocViewerPrefs.ViewerPref[] UI_Items = {DocViewerPrefs.ViewerPref.e_HideToolbar,
              DocViewerPrefs.ViewerPref.e_HideMenubar,DocViewerPrefs.ViewerPref.e_HideWindowUI,
              DocViewerPrefs.ViewerPref.e_FitWindow,DocViewerPrefs.ViewerPref.e_CenterWindow,
                                                      DocViewerPrefs.ViewerPref.e_DisplayDocTitle};

        public static PDFDoc.DisplayMode[] display_modes = {PDFDoc.DisplayMode.e_DisplayUseNone,PDFDoc.DisplayMode.e_DisplayUseOutlines,
               PDFDoc.DisplayMode.e_DisplayUseThumbs, PDFDoc.DisplayMode.e_DisplayFullScreen,PDFDoc.DisplayMode.e_DisplayUseOC,
               PDFDoc.DisplayMode.e_DisplayUseAttachment};

        public static string[] display_mode_strings = {"UseNone", "UseOutlines", "UseThumbs", "FullScreen", "UseOC", "UseAttachment"};

        public static string GetPageBoxName(PDFPage.BoxType type)
        {
            switch (type) {
                case PDFPage.BoxType.e_MediaBox:
                    return "MediaBox";
                case PDFPage.BoxType.e_CropBox:
                    return "CropBox";
                case PDFPage.BoxType.e_TrimBox:
                    return "TrimBox";
                case PDFPage.BoxType.e_ArtBox:
                    return "ArtBox";
                case PDFPage.BoxType.e_BleedBox:
                    return "BleedBox";
            }
            return "";
        }

        public static string GetViewerPrefName(DocViewerPrefs.ViewerPref ui_item) {
          switch(ui_item){
            case DocViewerPrefs.ViewerPref.e_HideToolbar:
              return "HideToolbar";
            case DocViewerPrefs.ViewerPref.e_HideMenubar:
              return "HideMenubar";
            case DocViewerPrefs.ViewerPref.e_HideWindowUI:
              return "HideWindowUI";
            case DocViewerPrefs.ViewerPref.e_FitWindow:
              return "FitWindow";
            case DocViewerPrefs.ViewerPref.e_CenterWindow:
              return "CenterWindow";
            case DocViewerPrefs.ViewerPref.e_DisplayDocTitle:
              return "DisplayDocTitle";
          }
          return "";
        }

        public static string PrintScaleAppDefault(DocViewerPrefs.PrintScale ui_item)
        {
            switch (ui_item)
            {
                case DocViewerPrefs.PrintScale.e_PrintScaleNone:
                    return "PrintScaleNone";
                case DocViewerPrefs.PrintScale.e_PrintScaleAppDefault:
                    return "PrintScaleAppDefault";
            }
             return "";
        }



        public static string[] metadata_items = {"Title", "Author", "Subject", "Keywords","Creator", "Producer", "CreationDate", "ModDate"};

        public static string DateTimeToString(foxit.common.DateTime datetime)
        {
            String s_datetime = string.Format("{0}{1}{2}{3}-{4}:{5}:{6} {7}{8}:{9}", datetime.year, datetime.month, datetime.day,
                datetime.hour, datetime.minute, datetime.second, datetime.utc_hour_offset > 0 ? "+" : "-",
                datetime.utc_hour_offset,
                datetime.utc_minute_offset);
            return s_datetime;
        }

        public static void ShowDocViewerPrefsInfo(PDFDoc doc,string file_name) 
        {  
            TestInfo test_info = new TestInfo();
            string output_path = test_info.output_path;
            string file_info = output_path + "DocViewerPrefsInfo_"+ file_name;
            TextDoc text_doc = new TextDoc(file_info, FileMode.Create);

            using(DocViewerPrefs prefs = new DocViewerPrefs(doc, null))
            {
                text_doc.Write("Document viewer preferences information:\r\n");
                
                // Get UI visibility status.
                for (int i = 0; i < UI_Items.Length; i++) 
                {
                    text_doc.Write(string.Format("Visibility of {0}:\t{1}\r\n", GetViewerPrefName(UI_Items[i]), prefs.GetUIDisplayStatus(UI_Items[i]) ? "Yes" : "No"));
                }
                
                // Get display mode for non full-screen mode.
                PDFDoc.DisplayMode mode = prefs.GetNonFullScreenPageMode();
                string display_mode = "";
                for (int i = 0; i < display_modes.Length; i++) 
                {
                    if (mode == display_modes[i]) 
                    {
                        display_mode = display_mode_strings[i];
                        break;
                    }
                }
                text_doc.Write(string.Format("None full screen page mode:\t{0}\r\n",display_mode));
                // Get reading direction.
                text_doc.Write(string.Format("Reading direction:\t{0}\r\n", prefs.GetReadingDirection() ? "left to right" : "right to left"));
                // Get the type of area item.
                PDFPage.BoxType type = prefs.GetPrintClip();
                text_doc.Write(string.Format("The GetPrintClip returned:\t{0}\r\n", GetPageBoxName(type)));
                type = prefs.GetPrintArea();
                text_doc.Write(string.Format("The GetPrintArea returned:\t{0}\r\n", GetPageBoxName(type)));
                type = prefs.GetViewArea();
                text_doc.Write(string.Format("The GetViewArea returned:\t{0}\r\n", GetPageBoxName(type)));
                type = prefs.GetViewClip();
                text_doc.Write(string.Format("The GetViewClip returned:\t{0}\r\n", GetPageBoxName(type)));

                // Get page scaling option.
                text_doc.Write(string.Format("PDFPage scaling option:\t{0}\r\n", PrintScaleAppDefault(prefs.GetPrintScale())));

                // Get the number of copies to be printed.
                text_doc.Write(string.Format("The number of copies to be printed:\t{0}\r\n", prefs.GetPrintCopies()));

                // Get page ranges which allowed to print
                text_doc.Write("PDFPage ranges for printing:\r\n");
                Range print_ranges = prefs.GetPrintRange();
                if(!print_ranges.IsEmpty())
                {
                    for (int i = 0; i < print_ranges.GetSegmentCount(); i=i+1)
                        text_doc.Write(string.Format("\tfirst:\t{0}\tlast:\t{1}\r\n", print_ranges.GetSegmentStart(i), print_ranges.GetSegmentEnd(i)));
                }
            }
        }

        public static void ShowMetaDataInfo(PDFDoc doc,string file_name)
        {
            TestInfo test_info = new TestInfo();
            string output_path = test_info.output_path;
            string output_file = output_path + "MetaDataInfo_"+file_name;
            TextDoc text_doc = new TextDoc(output_file, FileMode.Create);
            text_doc.Write("Metadata information:\r\n");
            using (Metadata metadata = new Metadata(doc))
            {
                for (int i = 0; i < metadata_items.Length; i++)
                {
                    string item = metadata_items[i];
                    text_doc.Write(string.Format("{0}: ", item));
                    WStringArray value = metadata.GetValues(item);
                    for (uint j = 0; j < value.GetSize(); j++)
                    {
                        text_doc.Write(string.Format("{0}",value.GetAt(j)));
                    }
                    text_doc.Write("\r\n");
                }
            }
        }

        public static foxit.common.DateTime GetLocalDateTime()
        {
            System.DateTimeOffset rime = System.DateTimeOffset.Now;
            foxit.common.DateTime datetime = new foxit.common.DateTime();
            datetime.year = (UInt16)rime.Year;
            datetime.month = (UInt16)rime.Month;
            datetime.day = (ushort)rime.Day;
            datetime.hour = (UInt16)rime.Hour;
            datetime.minute = (UInt16)rime.Minute;
            datetime.second = (UInt16)rime.Second;

            datetime.utc_hour_offset = (short)rime.Offset.Hours;
            datetime.utc_minute_offset = (ushort)rime.Offset.Minutes;

            return datetime;
        }

        public static void SetDocViewerPrefsInfo(PDFDoc doc)
        {
            doc.SetDisplayMode(PDFDoc.DisplayMode.e_DisplayFullScreen);
            using (DocViewerPrefs prefs = new DocViewerPrefs(doc, null))
            {
                // Set UI visibility status.
                for (int i = 0; i < UI_Items.Length; i++)
                {
                    prefs.SetUIDisplayStatus(UI_Items[i], true);
                }

                // Set display mode for non full-screen mode.
                prefs.SetNonFullScreenPageMode(PDFDoc.DisplayMode.e_DisplayUseOutlines);

                // Set reading direction.
                prefs.SetReadingDirection(false);

                // Set the type of area item.
                prefs.SetViewArea(PDFPage.BoxType.e_CropBox);
                prefs.SetViewClip(PDFPage.BoxType.e_CropBox);
                prefs.SetPrintArea(PDFPage.BoxType.e_CropBox);
                prefs.SetPrintClip(PDFPage.BoxType.e_CropBox);

                // Set page scaling option.
                prefs.SetPrintScale(DocViewerPrefs.PrintScale.e_PrintScaleNone);
                // Set the number of copies to be printed.
                prefs.SetPrintCopies(4);
                Range print_range = new Range(0, doc.GetPageCount() / 2, Range.Filter.e_All);
                prefs.SetPrintRange(print_range);
            }
        }

        public static void SetMetaDataInfo(PDFDoc doc)
        {
            string[] metadata_values = {"Title set by simple demo", "Simple demo","Subject set by simple demo",
                      "Keywords set by simple demo","Foxit PDF SDK", "Foxit"};
            using (Metadata metadata = new Metadata(doc))
            {
                for (int i = 0; i < metadata_values.Length; i++)
                {
                    WStringArray ws_metadata_values = new WStringArray();
                    ws_metadata_values.Add(metadata_values[i]);
                    metadata.SetValues(metadata_items[i], ws_metadata_values);
                }
                metadata.SetCreationDateTime(GetLocalDateTime());
                metadata.SetModifiedDateTime(GetLocalDateTime());
            }
        }

        static void Main(string[] args)
        {
            TestInfo test_info = new TestInfo();
            string input_path = test_info.input_path;
            string output_path = test_info.output_path;
            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);
                return;
            }

            try
            {
                 string input_file = input_path + "AboutFoxit.pdf";
                 using (PDFDoc doc = new PDFDoc(input_file))
                 {
                     ErrorCode code = doc.Load(null);
                     if (code != ErrorCode.e_ErrSuccess)
                     {
                         Console.WriteLine("[Failed] Cannot load PDF document {0}.\r\nError Message: {1}\r\n", input_file, code);
                         Library.Release();
                         return;
                     }

                     // Show original information.
                     ShowDocViewerPrefsInfo(doc, "original.txt");
                     ShowMetaDataInfo(doc, "original.txt");

                     // Set information.
                     SetDocViewerPrefsInfo(doc);
                     SetMetaDataInfo(doc);

                     // Show new information.
                     ShowDocViewerPrefsInfo(doc, "new.txt");
                     ShowMetaDataInfo(doc, "new.txt");
                     string output_file = output_path + "AboutFoxit_docinfo.pdf";
                     doc.SaveAs(output_file, (int)PDFDoc.SaveFlags.e_SaveFlagNoOriginal);
                 }
            }
            catch (foxit.PDFException e)
            {
                Console.WriteLine(e.Message);
            }

            Library.Release();
        }
    }
}
