/*
//
// ADOBE SYSTEMS INCORPORATED
// Copyright 2012 Adobe Systems Incorporated
// All Rights Reserved.
// 
// NOTICE:   Adobe permits you to use, modify, and distribute this file in accordance with the 
// terms of the Adobe license agreement accompanying it.   If you have received this file from a 
// source other than Adobe, then your use, modification, or distribution of it requires the prior 
// written permission of Adobe.
//
*/

/*
// Project: PDFProcessor - Converts PDF to PDF/A and PDF/X compliant PDF files.
//
// Note: By default, this example program opens a file called input.pdf in the
//             source directory.   It converts this file and saves the output in the 
//                             executable diretory by the name out.pdf. It demonstrates use of 
//                             PDFProcessorConvertAndSaveToPDFA() and PDFProcessorConvertAndSaveToPDFX()
//                             that allows user to specify (optional)
//                             Callback to Monitor Flattening Progress. The User also has an Option to 
//                             Cancel the Operation by returning 1 in Callback, if required.
//
// Steps:
// * Initialize HFT with the statement gPDFProcessorHFT = InitPDFProcessorHFT;
// * Initialize PDFProcessor by invoking Plugin API PDFProcessorInitialize()
// * Convert the input PDF by invoking Plugin API PDFProcessorConvertAndSaveToPDFA()/PDFProcessorConvertAndSaveToPDFX()
// * Terminate PDFProcessor by invoking Plugin API PDFProcessorTerminate()
*/

#include <stdio.h>
#include <sstream>
#ifdef UNIX_PLATFORM
#include <string.h>
#endif
//PDFL Headers
#include "PDFInit.h"
#include "ASCalls.h"
#include "PDCalls.h"
#include "PDFLExpT.h"
#include "ASExtraCalls.h"


// PDFProcessor Plugin headers
#include "PDFProcessorCalls.h"
#ifdef MAC_ENV
#include "MacUtils.h"
#endif

// Sample Headers
#include "MyPDFLibUtils.h"

#define INPUT_PATH "../sources/input.pdf"
#define OUTPUT_PATH "out.pdf"
#define MAX_PATH 1000

HFT   gPDFProcessorHFT;
typedef   enum  {
                //Convert to PDF/A1a
                kPDFProcessorConvertToPDFA_1a,
                //Convert to PDF/A1b
                kPDFProcessorConvertToPDFA_1b,
                //Convert to PDF/X1a
                kPDFProcessorConvertToPDFX_1a,
                //Convert to PDF/X3
                kPDFProcessorConvertToPDFX_3
}PDFProcessorConversionOption;

void   MainProc(PDFProcessorConversionOption  convertOption);
void   PDFProcessorMain(PDFProcessorConversionOption  convertOption);

//Setting the convert parameters.
void   SetupPDFAProcessorParams(PDFProcessorPDFAConvertParams userParams);
void   SetupPDFXProcessorParams(PDFProcessorPDFXConvertParams userParams);

//Progress Monitor CallBack for PDFProcessor
ASBool   PDFProcessorProgressMonitorCB  (ASInt32  pageNum,  ASInt32  totalPages,  float  current,  void  *clientData);

int   main( int  argc,  char  *argv[],  char  *envp[])
{
                INIT_AUTO_POOL(autoReleasePool);
                /* Required only on MAC platform */
               
                if  (argc != 2) 
               {
                               printf( "Usage: %s PDFProcessor Selector (PDFA1a/PDFA1b/PDFX1a/PDFX3) \n" , argv[0]);
                                RELEASE_AUTO_POOL(autoReleasePool);          /* Required only on MAC platform */
                                return  0;
               }

                PDFProcessorConversionOption  convertOption;
               
                if (!strcmp (argv[1] , "PDFA1a" ))
                               convertOption =  kPDFProcessorConvertToPDFA_1a;
                else   if  (!strcmp(argv[1],  "PDFA1b" ))
                               convertOption =  kPDFProcessorConvertToPDFA_1b;
                else   if  (!strcmp (argv[1] , "PDFX1a" ))
                               convertOption =  kPDFProcessorConvertToPDFX_1a;
                else   if  (!strcmp (argv[1] , "PDFX3" ))
                               convertOption =  kPDFProcessorConvertToPDFX_3;
                else  {
                               printf( "PDF Conversion Standard not supported !!!! " );
                                RELEASE_AUTO_POOL(autoReleasePool);          /* Required only on MAC platform */
                                return  0;
               }

                int  err =  MyPDFLInit();  /* initialize the PDFLib */
                if  (err != 0)                                      /* check for error after initialization */
               {
                               fprintf(stderr,  "Initialization error. See \"AcroErr.h\" for more info.\n" );
                               fprintf(stderr,  "Error system: %d\nError Severity: %d\nError Code: %d\n" ,
                                                                                                ErrGetSystem(err),  ErrGetSeverity(err),  ErrGetCode(err));
               }
                else
               {
                                MainProc(convertOption);
                                MyPDFLTerm();      /* terminate the PDFLib */
               }

                RELEASE_AUTO_POOL(autoReleasePool);          /* Required only on MAC platform */
                return  0;
}


void   MainProc(PDFProcessorConversionOption  convertOption)
{
DURING
                gPDFProcessorHFT  = InitPDFProcessorHFT;

                //initialize PDFProcessor plugin
                if (PDFProcessorInitialize())
               {
                                PDFProcessorMain(convertOption);
                                //Terminate PDFProcessor plugin
                               PDFProcessorTerminate();
               }
                else
                               printf( "Initialization of PDFProcessor Plugin failed...\n" );
HANDLER
               printf( "MainProc has thrown an exception...\n" );
                DisplayError(ERRORCODE);
END_HANDLER
}

void   PDFProcessorMain(PDFProcessorConversionOption  convertOption)
{                             
                ASInt32  res =  false ;
                PDDoc  srcPDDoc =  NULL;
#ifndef MAC_PLATFORM
                ASPathName  srcFilePath =  ASFileSysCreatePathNameNULLASAtomFromString( "Cstring" ),  INPUT_PATH,  NULL  );
                ASPathName  destFilePath =  ASFileSysCreatePathNameNULLASAtomFromString( "Cstring" ),  OUTPUT_PATH,  NULL  );
#endif
       
#ifdef MAC_PLATFORM
        ASPathName  destFilePath =  GetMacPath(OUTPUT_PATH);
#endif
DURING
#ifdef MAC_PLATFORM

       srcPDDoc =  MyPDDocOpen(INPUT_PATH);
#else
               srcPDDoc =  PDDocOpenEx(srcFilePath,  ASGetDefaultFileSys(),NULL, 0,  true );
#endif
                if  (convertOption ==  kPDFProcessorConvertToPDFA_1a)
               {
                               PDFProcessorPDFAConvertParamsRec userParamsA;
                               printf( "\nConverting using PDFProcessorConvertAndSaveToPDFA (with Callback)\n" );
                                SetupPDFAProcessorParams(&userParamsA);
                                // To change the PDF/A Conversion standard user can send 'kPDFProcessorConvertToPDFA1aCMYK' for CMYK Conversion.
                               res = PDFProcessorConvertAndSaveToPDFA(srcPDDoc, destFilePath,  ASGetDefaultFileSys(), kPDFProcessorConvertToPDFA1aRGB, &userParamsA);
               }
                else   if  (convertOption ==  kPDFProcessorConvertToPDFA_1b)
               {
                               PDFProcessorPDFAConvertParamsRec userParamsA;
                               printf( "\nConverting using PDFProcessorConvertAndSaveToPDFA (with Callback)\n" );
                                SetupPDFAProcessorParams(&userParamsA);
                                // To change the PDF/A Conversion standard user can send 'kPDFProcessorConvertToPDFA1bCMYK' for CMYK Conversion.
                               res = PDFProcessorConvertAndSaveToPDFA(srcPDDoc, destFilePath,  ASGetDefaultFileSys(), kPDFProcessorConvertToPDFA1bRGB, &userParamsA);
               }
                else  
               {
                               PDFProcessorPDFXConvertParamsRec userParamsX;
                               printf( "\nConverting using PDFProcessorConvertAndSaveToPDFX (with Callback)\n" );
                                SetupPDFXProcessorParams(&userParamsX);
                                if  (convertOption ==  kPDFProcessorConvertToPDFX_1a)
                                               res = PDFProcessorConvertAndSaveToPDFX(srcPDDoc, destFilePath,  ASGetDefaultFileSys(), kPDFProcessorConvertToPDFX1a2001, &userParamsX);
                                else
                                               res = PDFProcessorConvertAndSaveToPDFX(srcPDDoc, destFilePath,  ASGetDefaultFileSys(), kPDFProcessorConvertToPDFX32003, &userParamsX);
               }
HANDLER
                DisplayError  (ERRORCODE);
END_HANDLER

                if (res)
                               printf( "File %s has been successfully Converted.\n" ,  INPUT_PATH);
                else
                               printf( "Conversion of file %s has failed...\n" ,  INPUT_PATH);

                if  (srcPDDoc)
                                PDDocClose(srcPDDoc);
#ifdef MAC_PLATFORM
        if  (destFilePath)
                                ASFileSysReleasePath(NULL, destFilePath);
#else
                if  (srcFilePath)
                                ASFileSysReleasePath(NULL, srcFilePath);
                if  (destFilePath)
                                ASFileSysReleasePath(NULL, destFilePath);
#endif
}

void   SetupPDFAProcessorParams(PDFProcessorPDFAConvertParams userParams)
{
               memset (userParams, 0,  sizeof  (PDFProcessorPDFAConvertParamsRec));
               userParams->size =  sizeof (PDFProcessorPDFAConvertParamsRec);
               userParams->progMon =  PDFProcessorProgressMonitorCB;
               userParams->noRasterizationOnFontErrors =  false ;
               userParams->removeAllAnnotations =  false ;
               userParams->colorCompression = kPDFProcessorColorJpegCompression;
}
void   SetupPDFXProcessorParams(PDFProcessorPDFXConvertParams userParams)
{

               memset (userParams, 0,  sizeof  (PDFProcessorPDFXConvertParamsRec));
               userParams->size =  sizeof (PDFProcessorPDFXConvertParamsRec);
               userParams->progMon =  PDFProcessorProgressMonitorCB;
               userParams->removeAllAnnotations =  false ;
               userParams->colorCompression = kPDFProcessorColorJpegCompression;
}


ASBool   PDFProcessorProgressMonitorCB  (ASInt32  pageNum,  ASInt32  totalPages,  float  current,  void  *clientData)
{
                if  ( clientData ) 
               {
                                ASBool  * IsMonitorCalled = (ASBool*)clientData;
                                if  ( *IsMonitorCalled ==  false  )
                               {
                                               printf( "PDFProcessor Progress Monitor CallBack\n" );
                                                //Set to true to Display this Message Only Once
                                               *IsMonitorCalled =  true ;
                               }
               }

               printf ( "PDFProcessor Page %d of %d. Overall Progress = %f %%. \n" , 
                                                               pageNum + 1,  /* Adding 1, since Page numbers are 0-indexed*/  
                                                                               totalPages,   
                                                                                               current  /* Current Overall Progress */  );
               
                //Return 1 to Cancel conversion
                return  0;
}