// 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.

import java.io.File;

import com.foxit.sdk.PDFException;
import com.foxit.sdk.common.*;
import com.foxit.sdk.pdf.*;


import java.util.Calendar;
import java.io.FileWriter;
import java.io.IOException;

import static com.foxit.sdk.common.Constants.e_ErrSuccess;
import static com.foxit.sdk.pdf.PDFPage.*;
import static com.foxit.sdk.pdf.PDFDoc.*;
import static com.foxit.sdk.pdf.DocViewerPrefs.*;

public class docinfo {
    private static 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=";
    private static String sn = "Rew1vB0TqoMIxX444UcpScARWdhgJpsJfzmyMLR32a0+EgrCjp2NaQ==";
    private static String output_path = "../output_files/docinfo/";
    private static String input_path = "../input_files/";
    private static String[] kMetadataItems = {"Title", "Author", "Subject", "Keywords",
            "Creator", "Producer", "CreationDate", "ModDate"};
    private static String[] kDisplayModeStrings = {"UseNone", "UseOutlines", "UseThumbs", "FullScreen", "UseOC", "UseAttachment"};
    private static int[] kUIItems = {e_HideToolbar, e_HideMenubar, e_HideWindowUI, e_FitWindow,
            e_CenterWindow, e_DisplayDocTitle};
    private static int[] kDisplayModes = {e_DisplayUseNone, e_DisplayUseOutlines, e_DisplayUseThumbs,
            e_DisplayFullScreen, e_DisplayUseOC, e_DisplayUseAttachment};

    // You can also use System.load("filename") instead. The filename argument must be an absolute path name.
    static {
        String os = System.getProperty("os.name").toLowerCase();
        String lib = "fsdk_java_";
        if (os.startsWith("win")) {
            lib += "win";
        } else if (os.startsWith("mac")) {
            lib += "mac";
        } else {
            lib += "linux";
        }
        
        if (System.getProperty("sun.arch.data.model").equals("64")) {
          if(System.getProperty("os.arch").equals("aarch64")){
            if(os.startsWith("mac")){
              lib += "arm";
             }
             else{
               lib += "armv8";
             }
           }
           else{
              lib += "64";
           }
        } else {
           if(System.getProperty("os.arch").equals("arm")){
              lib += "armv7";
           }
           else{
              lib += "32";
           }
        }
        System.loadLibrary(lib);
    }

    private static void createResultFolder(String output_path) {
        File myPath = new File(output_path);
        if (!myPath.exists()) {
            myPath.mkdir();
        }
    }

    private static DateTime GetLocalDateTime() {
        Calendar c = Calendar.getInstance();

        DateTime datetime = new DateTime();
        datetime.setYear(c.get(Calendar.YEAR));
        datetime.setMonth(c.get(Calendar.MONTH) + 1);
        datetime.setDay(c.get(Calendar.DATE));
        datetime.setHour(c.get(Calendar.HOUR));
        datetime.setMinute(c.get(Calendar.MINUTE));
        datetime.setSecond(c.get(Calendar.SECOND));
        
        java.util.TimeZone timeZone = c.getTimeZone();
        int offset = timeZone.getRawOffset();
        int gmt = offset/(3600*1000);
        
        datetime.setUtc_hour_offset((short)gmt);
        datetime.setUtc_minute_offset(offset%(3600*1000) / 60);
        return datetime;
    }

    private static String GetPageBoxName(int type) {
        switch (type) {
            case e_MediaBox:
                return "MediaBox";
            case e_CropBox:
                return "CropBox";
            case e_TrimBox:
                return "TrimBox";
            case e_ArtBox:
                return "ArtBox";
            case e_BleedBox:
                return "BleedBox";
        }
        return "";
    }

    private static String GetViewerPrefName(int ui_item) {
        switch (ui_item) {
            case e_HideToolbar:
                return "HideToolbar";
            case e_HideMenubar:
                return "HideMenubar";
            case e_HideWindowUI:
                return "HideWindowUI";
            case e_FitWindow:
                return "FitWindow";
            case e_CenterWindow:
                return "CenterWindow";
            case e_DisplayDocTitle:
                return "DisplayDocTitle";
        }
        return "";
    }

    private static void ShowDocViewerPrefsInfo(PDFDoc doc, String file_name) throws PDFException, IOException {
        String file_info = output_path + "DocViewerPrefsInfo_" + file_name;
        FileWriter writer = new FileWriter(file_info, false);
        writer.write("Document viewer preferences information:\r\n");

        DocViewerPrefs prefs = new DocViewerPrefs(doc, null);

        // Get UI visibility status.
        for (int i = 0; i < kUIItems.length; i++) {
            String status = (prefs.getUIDisplayStatus(kUIItems[i])) ? "Yes" : "No";
            writer.write("Visibility of " + kUIItems[i] + ":\t" + status + "\r\n");
        }
        // Get display mode for non full-screen mode.
        int mode = prefs.getNonFullScreenPageMode();
        String display_mode = null;
        for (int i = 0; i < kDisplayModes.length; i++) {
            if (mode == kDisplayModes[i]) {
                display_mode = kDisplayModeStrings[i];
                break;
            }
        }
        writer.write("None full screen page mode:\t" + display_mode + "\r\n");
        // Get reading direction.
        String direction = prefs.getReadingDirection() ? "left to right" : "right to left";
        writer.write("Reading direction:\t" + direction + "\r\n");
        // Get the type of area item.
        int type = prefs.getPrintClip();
        writer.write("The GetPrintClip returned:\t" + GetPageBoxName(type) + "\r\n");
        type = prefs.getPrintArea();
        writer.write("The GetPrintArea returned:\t" + GetPageBoxName(type) + "\r\n");
        type = prefs.getViewArea();
        writer.write("The GetViewArea returned:\t" + GetPageBoxName(type) + "\r\n");
        type = prefs.getViewClip();
        writer.write("The GetViewClip returned:\t" + GetPageBoxName(type) + "\r\n");

        // Get page scaling option.
        writer.write("Page scaling option:\t" + prefs.getPrintScale() + "\r\n");
        // Get the number of copies to be printed.
        writer.write("The number of copies to be printed:\t" + prefs.getPrintCopies() + "\r\n");
        // Get page ranges which allowed to print
        writer.write("Page 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) {
                writer.write("\tfirst:\t" + print_ranges.getSegmentStart(i) + "\tlast:\t" + print_ranges.getSegmentEnd(i) + "\r\n");
            }
        }
        writer.close();
    }

    private static void SetDocViewerPrefsInfo(PDFDoc doc) throws PDFException, IOException {

        doc.setDisplayMode(e_DisplayFullScreen);
        DocViewerPrefs prefs = new DocViewerPrefs(doc, null);
        // Set UI visibility status.
        for (int i = 0; i < kUIItems.length; i++) {
            prefs.setUIDisplayStatus(kUIItems[i], true);
        }
        // Set display mode for non full-screen mode.
        prefs.setNonFullScreenPageMode(e_DisplayUseOutlines);
        // Set reading direction.
        prefs.setReadingDirection(false);
        // Set the type of area item.

        prefs.setViewArea(e_CropBox);
        prefs.setViewClip(e_CropBox);
        prefs.setPrintArea(e_CropBox);
        prefs.setPrintClip(e_CropBox);
        // Set page scaling option.
        prefs.setPrintScale(e_PrintScaleNone);
        // Set the number of copies to be printed.
        prefs.setPrintCopies(4);
        Range print_range = new Range(0, doc.getPageCount() / 2, Range.e_All);
        prefs.setPrintRange(print_range);
    }

    private static void ShowMetaDataInfo(PDFDoc doc, String file_name) throws PDFException, IOException {
        String output_file = output_path + "MetaDataInfo_" + file_name;
        FileWriter writer = new FileWriter(output_file, false);
        writer.write("Metadata information:\r\n");
        Metadata metadata = new Metadata(doc);
        for (int i = 0; i < kMetadataItems.length; i++) {
            writer.write(kMetadataItems[i] + ": ");
            WStringArray value = metadata.getValues(kMetadataItems[i]);
            for (int j = 0; j < value.getSize(); j++) {
                writer.write(value.getAt(j));
            }
            writer.write("\r\n");
        }
        writer.close();
    }

    private static void SetMetaDataInfo(PDFDoc doc) throws PDFException {
        String[] kMetadataValues = {"Title set by simple demo", "Simple demo",
                "Subject set by simple demo", "Keywords set by simple demo",
                "Foxit PDF SDK", "Foxit"};
        Metadata metadata = new Metadata(doc);
        for (int i = 0; i < kMetadataValues.length; i++) {
            WStringArray MetadataValues = new WStringArray();
            MetadataValues.add(kMetadataValues[i]);
            metadata.setValues(kMetadataItems[i], MetadataValues);
        }
        metadata.setCreationDateTime(GetLocalDateTime());
        metadata.setModifiedDateTime(GetLocalDateTime());
    }

    public static void main(String[] args) throws PDFException, IOException {
        createResultFolder(output_path);
        // Initialize Library.
        int error_code = Library.initialize(sn, key);
        if (error_code != e_ErrSuccess) {
            System.out.println(String.format("Library Initialize Error: %d\n", error_code));
            return;
        }

        String input_file = input_path + "AboutFoxit.pdf";

        try {
            PDFDoc doc = new PDFDoc(input_file);
            error_code = doc.load(null);

            if (error_code != e_ErrSuccess) {
                System.out.println(String.format("[Failed] Cannot load PDF document [%s].\r\nError Message: %d\n", input_file, error_code));
                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, e_SaveFlagNoOriginal);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        Library.release();
        return;
    }
}
