// 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 is a demo to demonstrate how to use matrix to translate, scale... objects.

#include "FSPDFObjC.h"

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

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";

int main(int argc, const char *argv[]) {
    @autoreleasepool {
        NSString *output_directory = [[NSString alloc] initWithFormat:@"%@%@", output_path, @"matrix/"];
        NSString *input_file = [[NSString alloc] initWithFormat:@"%@%@", input_path, @"SamplePDF.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] initWithPath:input_file];
            FSErrorCode error_code = [doc load:@""];
            if (error_code != FSErrSuccess) {
                NSLog(@"The Doc [%@] Error: %ld\n", input_file, error_code);
                return 1;
            }
            // Get and parse page.
            FSPDFPage *page = [doc getPage:0];
            [page startParse:FSPDFPageParsePageNormal pause:nil is_reparse:NO];
            long pos = [page getFirstGraphicsObjectPosition:FSGraphicsObjectTypeAll];
            int flag = 0;
            while (pos != 0) {
                if (flag == (2 | 4))
                    break;
                FSGraphicsObject *obj = [page getGraphicsObject:pos];
                pos = [page getNextGraphicsObjectPosition:pos filter:FSGraphicsObjectTypeAll];
                FSGraphicsObjectType type = [obj getType];
                float start_x = 0;
                // Get one TextObject or one ImageObject.
                if (type == FSGraphicsObjectTypeText && !(flag & 2)) {
                    FSTextObject *text_obj = [obj getTextObject];
                    NSString *text = text_obj.text;
                    if (![text isEqualToString:@"Foxit Software Incorporated"]) {
                        continue;
                    }
                    start_x = 400.0f;
                    flag |= 2;
                } else if (type == FSGraphicsObjectTypeImage && !(flag & 4)) {
                    start_x = 150.0f;
                    flag |= 4;
                } else {
                    continue;
                }

                // Now we have found the TextObject or the ImageObject, transform them.
                FSGraphicsObject *clone_obj1 = [obj clone];
                FSMatrix2D *matrix = clone_obj1.matrix;
                // Translate the matrix in vertical direction.
                [matrix translate:0 y:150 bPrepended:0];
                clone_obj1.matrix = matrix;
                [page insertGraphicsObject:0 graphics_object:clone_obj1];

                FSGraphicsObject *clone_obj2 = [obj clone];
                matrix = clone_obj2.matrix;
                float d = matrix.d;
                float e = matrix.e;
                float f = matrix.f;
                // Translate it to the original point(0,0) first
                [matrix translate:-e y:-f bPrepended:0];
                // Rotate the matrix 90 degree in anticlockwise direction.
                [matrix rotate:1.57f bPrepended:0];
                // Page rotation should be considered, assume that the current page rotation is 0.
                float distance = d;
                if (type == FSGraphicsObjectTypeText) {
                    FSRectF *obj_rect = [obj getRect];
                    distance = obj_rect.top - obj_rect.bottom;
                }
                // Translate it to the specific coordinate(start_x,400)
                [matrix translate:distance + start_x y:400 bPrepended:0];
                clone_obj2.matrix = matrix;
                [page insertGraphicsObject:0 graphics_object:clone_obj2];

                FSGraphicsObject *clone_obj3 = [obj clone];
                matrix = clone_obj3.matrix;
                // Translate it to the original point(0,0) first
                [matrix translate:-e y:-f bPrepended:0];
                // Magnify the matrix 1.5 times in both horizontal and vertical directions.
                [matrix scale:1.5 sy:1.5 bPrepended:0];
                // Translate it to the specific coordinate(start_x,600)
                [matrix translate:start_x y:600.0f bPrepended:0];
                clone_obj3.matrix = matrix;
                [page insertGraphicsObject:0 graphics_object:clone_obj3];

                FSGraphicsObject *clone_obj4 = [obj clone];
                matrix = clone_obj4.matrix;
                // Translate it to the original point(0,0) first
                [matrix translate:-e y:-f bPrepended:0];
                // Skews the x axis by an angle 0.5 and the y axis by an angle 0.5.
                [matrix shear:0.5 fBetaRadian:0.5 bPrepended:0];
                // Translate it to the specific coordinate(start_x,600)
                [matrix translate:start_x y:800.0f bPrepended:0];
                clone_obj4.matrix = matrix;
                [page insertGraphicsObject:0 graphics_object:clone_obj4];
            }
            // Generate the page content
            [page generateContent];

            // Save the pdf document
            NSString *file_name = [[NSString alloc] initWithFormat:@"%@%@", output_directory, @"/MatrixTransformResult.pdf"];
            [doc saveAs:file_name save_flags:FSPDFDocSaveFlagNormal];
            NSLog(@"Matrix demo.");
        }
        @catch (NSException *exception) {
            NSLog(@"Unknown Exception, %@", exception);
            return -1;
        }
    }
    [FSLibrary destroy];
    return 0;
}
