// 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 mark PDF content and
// get marked content from graphics objects.

#include "FSPDFObjC.h"

NSString *input_path = @"../input_files/";
NSString *output_path = @"../output_files/";
NSString *content = @"";

NSString *sn = @"bPxThFlBAYifO3yiW0C51bKbjPap1zHaf5aG5sX378TjFvB7Q0802A==";
NSString *key = @"8f3g1sGNtR8NAgfSNv+BvaJWy2fnrw36NZvzh8GUxYXvs+/YczAk4e34yqlOnmL4asgxGMO7+rlOcSHUSSKagx5g4G7VEXfkYLXnDDx77FOOedZPrFFcOCu1vT4+wOKzy1zkORq9cKtiFf44byH5sfRqf+OvELjep2teT9eF9yPCsSw2vRKljXlPy40DMP9XX1O5OTe+mSG3RvwKUMb0+RpG3YobM87j+/ynTDlJMMXw4vgwuTb1ZuAtlvkTdFz7HDLV81C6TYnn73ddHeGD3qYWBVsD4uJkDwyyH/SWr7QX0HSgVg8HSZqnab1VGdAUYxKY2vGWeOTJdu6qDGb5ZEb9O3kZZg+9LYAmUKzDfCYwfIsYZ8Y9LPC4wMx70kIq7JpNnzPvigrdshV8/ew1F0+qP/P5Z1EB53vDVrp2LVSuL873Wv4g3PzjZlNH+1qgT87hC+Buto4qsSUfP5Y2z0uApu+c/TfttCXbeMLSsw9TY1HQD3mkrZExMaQqRrAuXAcZWdvBnVuG3DCZmm8q0DLxJiCfYfViAU/AkbeKMIGaTJdrvIXBcssfde4nmU6qr0M4x4+Hs2ESddtY2QRtLAUBq/7h7GJlJHkEZr8ueaUy/6D/2vvAWz6wMLgmjlPbDTLqzfnCJylHCPtcJmu1SPPT9v1VreBX3+zNWcIT8HueyHEiUniqzwWkRKaotrnNb/zhnHLPpgaBSwKjyi8rOzzVwu/nY84G9ye4jsVjmkIRItKDrW7z22iS+QQuTwfqLVuMB0OD4jMkPCC2slzPfEeZnuh4+Rewln2qLRJVgI72zJ20OBWAelGSpO1Ii2Y3gOvojdmtUwx6R3Z1qFNWTTB25o9ytcux8BLOtTCkA8T8xaT4N339OTCsu/TmfahIDixKvr8cDa6F2WkBT8SOfv64W9PgiNv5B/BMOD2VWYaAl0N7yD0NkYYg/cDWRC4dfpdeip1jrr0k3mND0oSpIkxC+FicZbaYYwRdtJ9OSVWJ5OE0voLv8HgLze8mw6s4TrN3z+a2NQCveMa2VRN7YcEF7agPrvb/qU+otMwHae/wM7+f+HFAaOW+WTfzfxIVFB8/A1DN0NiEX+em4G7nO5F5ZcvfYPpaaioe8Nn33BbVLtMjXqsOBeM8AXiVfpD6YO75j7BqnBUPnivvD8BxJaaIQZvVSuQmvGm0ynt03IYwE8Rq+jYsunvsZ86jh5BiUR+Nm7sK0Qe9BdZn/7jdqohMv9czfMGUAscX+xBMunFbDpcRbWVpUADcm209L8Ndek2XY7YlCMxPgPVNvfWRF2jxehib9Tpd7zB5ZIDfAEH9zrpLfp29DLvCh2Yx8mH7xxdKG1O9Q0GdHphYHhej6smAcPm68R0GUQaTOLfXqNpueGJC1GAOI3Y4swjyt7jMTWcibnKLzwukWE5rnEDhn5n64JnyUM0ZFkRmtOiV";

// The search results are displayed in the terminal.
void textOutput(NSString *str) {
    content = [[NSString alloc] initWithFormat:@"%@%@", content, str];
}

void CreateMarkedContent(FSPDFPage *page) {
    @autoreleasepool {
        long position = [page getLastGraphicsObjectPosition:FSGraphicsObjectTypeText];
        FSTextObject *text_object = [FSTextObject create];

        text_object.fillColor = 0xFF83AF98;

        // Prepare text state
        FSTextState *state = [[FSTextState alloc] init];
        state.font_size = 72.f;
        FSFont *font = [[FSFont alloc] initWithFont_id:FSFontStdIDTimesB];
        state.font = font;
        state.textmode = FSTextStateModeFill;

        [text_object setTextState:page text_state:state is_italic:NO weight:750];

        text_object.text = @"Marked-Content";
        [page insertGraphicsObject:position graphics_object:text_object];

        FSRectF *rect = [text_object getRect];
        float offset_x = ([page getWidth] - (rect.right - rect.left)) / 2;
        float offset_y = ([page getHeight] * 0.618f - (rect.top - rect.bottom)) / 2;
        [text_object transform:[[FSMatrix2D alloc] initWithA1:1 b1:0 c1:0 d1:1 e1:offset_x f1:offset_y] need_transform_clippath:NO];

        FSMarkedContent *content = [text_object getMarkedContent];
        FSPDFDictionary *span_dict = [FSPDFDictionary create];
        [span_dict setAtInteger:@"Direct" value:55];
        [content addItem:@"Span" property_dict:span_dict];

        // Generate content
        [page generateContent];
    }
}

bool GetMarkedContentObject(NSString *pdf_file) {
    @autoreleasepool {
        FSPDFDoc *doc = [[FSPDFDoc alloc] initWithPath:pdf_file];
        FSErrorCode ret = [doc load:@""];
        if (ret != FSErrSuccess) {
            NSLog(@"[Failed] Cannot load PDF document %@.\n Error message:%ld\n", pdf_file, ret);
            return false;
        }
        FSPDFPage *page = [doc getPage:0];
        [page startParse:FSPDFPageParsePageNormal pause:nil is_reparse:NO];
        long position = [page getFirstGraphicsObjectPosition:FSGraphicsObjectTypeText];
        FSTextObject *text_obj = [[page getGraphicsObject:position] getTextObject];
        FSMarkedContent *content = [text_obj getMarkedContent];
        int item_count = [content getItemCount];

        // Get marked content property
        for (int i = 0; i < item_count; i++) {
            textOutput([[NSString alloc] initWithFormat:@"index: %d\r\n", i]);
            NSString *tag_name = [content getItemTagName:i];
            textOutput([[NSString alloc] initWithFormat:@"Tag name: %@\r\n", tag_name]);
            int mcid = [content getItemMCID:i];
            textOutput([[NSString alloc] initWithFormat:@"mcid: %d\r\n", mcid]);
        }
        return true;
    }
}

int main(int argc, const char *argv[]) {
    @autoreleasepool {
        NSString *output_directory = [[NSString alloc] initWithFormat:@"%@%@", output_path, @"marked_content/"];
        NSString *output_file = [[NSString alloc] initWithFormat:@"%@%@", output_directory, @"marked_content.pdf"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL isDir = NO;
        if ([fileManager fileExistsAtPath:output_directory isDirectory:&isDir]) {
            if (!isDir) {
                NSError *error = nil;
                if (![fileManager removeItemAtPath:output_directory error:&error] || error) {
                    return -1;
                }
                if (![fileManager createDirectoryAtPath:output_directory withIntermediateDirectories:YES attributes:nil error:&error] || error) {
                    return -1;
                }
            }
        } else {
            NSError *error = nil;
            if (![fileManager createDirectoryAtPath:output_directory withIntermediateDirectories:YES attributes:nil error:&error] || error) {
                return -1;
            }
        }

        // Initialize library
        FSErrorCode errorCode = [FSLibrary initialize:sn key:key];
        if (errorCode != FSErrSuccess) {
            NSLog(@"Library Initialize Error: %ld", errorCode);
            return -1;
        }

        @try {
            FSPDFDoc *doc = [[FSPDFDoc alloc] init];
            FSPDFPage *page = [doc insertPageWithType:0 size:FSPDFPageSizeA4];

            CreateMarkedContent(page);

            [doc saveAs:output_file save_flags:FSPDFDocSaveFlagNormal];

            if (!GetMarkedContentObject(output_file)) {
                return 1;
            }
            NSLog(@"Add marked content to PDF file.");

            NSString *file_info = [[NSString alloc] initWithFormat:@"%@%@", output_directory, @"markedcontent.txt"];
            NSError *error;
            [content writeToFile:file_info atomically:YES encoding:NSUTF8StringEncoding error:&error];

        }
        @catch (NSException *exception) {
            NSLog(@"Unknown Exception, %@", exception);
            return -1;
        }
    }
    [FSLibrary destroy];
    return 0;
}
