//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 tag a PDF document.

import com.foxit.sdk.PDFException;
import com.foxit.sdk.common.Library;
import com.foxit.sdk.common.Progressive;
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.pdf.PDFPage;
import com.foxit.sdk.pdf.SignatureCallback;
import com.foxit.sdk.addon.accessibility.*;
import com.foxit.sdk.common.fxcrt.RectF;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import static com.foxit.sdk.common.Constants.e_ErrSuccess;
import static com.foxit.sdk.pdf.PDFPage.e_ParsePageNormal;

public class taggedpdf {

 // 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();
     }
 }

 public static void main(String[] args) throws PDFException {
     String key = "8f3g1sFttW8NAgfSNv+BvQJm2vDtTY+wGQ/1PcmGtqKTwvvI8mLE4KvuHocWH+XZnP3U+Vh1BnqpgQIjO0jwRz7evDdlijTdutpBEsozaXEvFpLbixmsSGvtznflVsuEmsu5ytLwVJiTap2VcCiiSbyuvQwQu88I8BxJ+XXv3LPXN5v/+00zDrZ+V5yLefi+bk7JX5FRE2jfSnOJIqEaVkHOpCIjwf9aszl01YoY7x0EAehg0ILal+v2QLLo7HnkAVt/TA31rddZexhq/2hwAwfy4OfvkJPnESppD7D+SAsX5CfXoU55P1vmyRe+lKBM6pOcarUbuaN4Vjj62SD0sTDbJZ2Ypyp+kcIxZ9wcD+Mg8aSimr5+hg8wZJT0u0mIAdZhTJ++A9sq9OmVAfL2QQ6bh2ISyKPGJPv29u738bAokRjqzZy9bi30mYfGLEwKChEd2R2NBDKZTDOVxFwpzD1IbF0/wN/DDbMO2gS0xUvgSbJyuXfA3ALtmoUH9I9iScaBVon5oYRRy6OTnFMgDgVM+nFTzWbaGKZfO+PMBnreaQ/Ezr9wH7YKJ+LrM4r6xVQjcHDUyx4dlVLe3zQlDRKGGChhyvymVDBuZR8B0/M9Y/DKr1sQAzp/W1Wsz+LZb+JUIxLBrJzgRLtOliuLF+JOTy036W0shWcXYYc2bwLdPWP/BXygmnopzUTCtuo/QLVTRNdENFqciYYvSHEZxgV1sUFpuBqIMUEigWR/2gMlMDiTVq0udEqn8g9bkw1SImVy50v2gwEbUHkEa243BP/3/Dae0YhH03NDUlTSVBKX6w1UVQK6/7aDL3A4EEg47YmKgh6NsABzRsgSvLBhBQNqzOoUvnKaf7YMlw0ns06BdFswP6DaY1KmuRR2Xn6MtDTshGNtT9+azHPqaAWaZs1rHz3fGYb5pfJHptJlx+r9609bY+ZhCERLYG+0lTNWCFnDxdI8Vj1BG4iGWaDBkIC5qdJI3qDLVDABdtIk43fMhgfr+TUqds+G6KBDapS9p32nKZc6lBqvlNN12Pv1AJCC1rwfECzmNQi3MXogQCxzi5pHAgd/BGyGwo4RWhFrKFN869H0whvDVC8NJM2upFrEEJET4fecQyMLWHuTCWvjRZclLC/GGOj9PAXHOcEdFkq4UkloMulXLGsQzkzHB3Elvd2NnxZ2+3FK2e0xNx+rBMru/i/HHLG6WZvz6Jz7mjmibNfBExydtEI5lWUZ1Wsy0r17kyvlME9Bot7XXPkx/+cKTcxfNWSb3kaPROYIgSpGjrXxfrphBnr1mioJPq3WrtP9E5lZBeMd8jxXT4NlX3T0frsci6Xy1ChB/BytU7pvn6bMfddTnEDd/QpkW+6WYOnHHrIYVk2ngKjUBl5nGOkp37wpgUpWp5tcICjpbjfNdY43VfTyHRf4dGRR";
	 String sn = "nkyvo37UxrKdu5Peq294Eb+g2ihRldgPQEP6MFtAM4LwtxXXJ+T7MQ==";
     String input_path = "../input_files/";
     String output_path = "../output_files/taggedpdf/";
     String input_file = input_path + "AboutFoxit.pdf";
     createResultFolder(output_path);

     // Initialize library
     int error_code = Library.initialize(sn, key);
     if (error_code != e_ErrSuccess) {
         System.out.println("Library Initialize Error: " + error_code);
         return;
     }
     
     {
         String output_file_path = output_path + "TaggedPdf_StartAutoTagged.pdf";

         PDFDoc pdfDoc= new PDFDoc(input_file);
         pdfDoc.load(null);
         TaggedPDF taggedpdf = new TaggedPDF(pdfDoc);
         Progressive progressive = taggedpdf.startTagDocument(null);
         int progressState = Progressive.e_ToBeContinued;
         while (Progressive.e_ToBeContinued == progressState)
           progressState = progressive.resume();

         pdfDoc.saveAs(output_file_path, 0);
     }
     {
         String output_file_path = output_path + "TaggedPdf_StartAutoTagged_SetCallback.pdf";

         PDFDoc pdfDoc= new PDFDoc(input_file);
         pdfDoc.load(null);
         TaggedPDF taggedpdf = new TaggedPDF(pdfDoc);
         TaggedPDFCallbackImpl callback = new TaggedPDFCallbackImpl();
         taggedpdf.setCallback(callback);
         Progressive progressive = taggedpdf.startTagDocument(null);
         int progressState = Progressive.e_ToBeContinued;
         while (Progressive.e_ToBeContinued == progressState)
           progressState = progressive.resume();

         pdfDoc.saveAs(output_file_path, 0);
     }
		 
     Library.release();
 }
}

class AutoTag_ReportElemRectCon {
	  public RectF rcRect;
	  public int eConfidence;
}
class ReportElemMap extends HashMap<Integer,ArrayList<AutoTag_ReportElemRectCon>> {}
class ReportResultPagesMap extends HashMap<Integer,ReportElemMap> {}
//Implementation of TaggedPDFCallback
class TaggedPDFCallbackImpl extends TaggedPDFCallback{
	private ReportResultPagesMap result_map_ = new ReportResultPagesMap();

	@Override
	public void release() {
		System.out.println("TaggedPDFCallbackImpl::Release()");
		ResetResult();
	}
	
	String GetReportCategoryString(int type) {
		String sFormat = "";
		switch (type) {
		case TaggedPDFCallback.e_ReportCategoryRegion:
		    sFormat = "Region";
		    break;
		case TaggedPDFCallback.e_ReportCategoryArtifact:
		    sFormat = "Artifact";
		    break;
		case TaggedPDFCallback.e_ReportCategoryParagraph:
		    sFormat = "Paragraph";
		    break;
		case TaggedPDFCallback.e_ReportCategoryListItem:
		    sFormat = "List Item";
		    break;
		case TaggedPDFCallback.e_ReportCategoryFigure:
		    sFormat = "Figure";
		    break;
		case TaggedPDFCallback.e_ReportCategoryTable:
		    sFormat = "Table";
		    break;
		case TaggedPDFCallback.e_ReportCategoryTableRow:
		    sFormat = "Table Row";
		    break;
		case TaggedPDFCallback.e_ReportCategoryTableHeader:
		    sFormat = "Table Header";
		    break;
		case TaggedPDFCallback.e_ReportCategoryTocItem:
		    sFormat = "Toc Item";
		    break;
		default:
		    break;
		}
		return sFormat;
	}

	String GetReportConfidenceString(int type) {
		String sFormat = "";
		switch (type) {
		case TaggedPDFCallback.e_ReportConfidenceHigh:
		    sFormat = "High";
		    break;
		case TaggedPDFCallback.e_ReportConfidenceMediumHigh:
		    sFormat = "Medium High";
		    break;
		case TaggedPDFCallback.e_ReportConfidenceMedium:
		    sFormat = "Medium";
		    break;
		case TaggedPDFCallback.e_ReportConfidenceMediumLow:
		    sFormat = "Medium Low";
		    break;
		case TaggedPDFCallback.e_ReportConfidenceLow:
		    sFormat = "Low";
		    break;
		default:
		    break;
		}
		return sFormat;
	}

	@Override
	public void report(int category, int confidence, int page_index, RectF rect) {
		System.out.println("Page Index: " + page_index + ", ReportCategory: " + GetReportCategoryString(category)
		      + ", ReportConfidence: " + GetReportConfidenceString(confidence) + ", Rect: [" + rect.getLeft()
		      + ", " +rect.getTop() + ", " + rect.getRight() + ", " + rect.getBottom() + "]");

		AutoTag_ReportElemRectCon pRectCon = new AutoTag_ReportElemRectCon();
		pRectCon.rcRect = rect;
		pRectCon.eConfidence = confidence;

		ReportElemMap pElemMap = null;
		ArrayList<AutoTag_ReportElemRectCon> pArray = null;

		if (!result_map_.containsKey(page_index)) {
		    pArray = new ArrayList<AutoTag_ReportElemRectCon>();
		    pArray.add(pRectCon);
		    pElemMap = new ReportElemMap();
		    pElemMap.put(category, pArray);
		    result_map_.put(page_index, pElemMap);
		}
		else {
		    pElemMap = result_map_.get(page_index);
		    if (pElemMap.containsKey(category)) {
		        pArray = pElemMap.get(category);
		        pArray.add(pRectCon);
		    }
		    else {
		        pArray = new ArrayList<AutoTag_ReportElemRectCon>();
		        pArray.add(pRectCon);
		        pElemMap.put(category, pArray);
		    }
		}
	}

	ReportResultPagesMap GetResult() {
		return result_map_;
	}

	void ResetResult() {
		result_map_.clear();
	}
}