// 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 Conversion 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 Conversion SDK to convert PDF files to Office(Word, Excel or PowerPoint) format files.

var {
  ErrorCode,
  State,
  WorkbookSettings,
  Library,
  PDF2WordSettingData,
  Range,
  PDF2OfficeSettingData,
  PDF2PowerPointSettingData,
  PDF2ExcelSettingData,
  ConvertCallback,
  ConvertCheckCallback,
  PDF2Office,
  Progressive,
  ReaderCallback,
  StreamCallback } = require("@fuxinsoft/foxit-pdf-conversion-sdk-node");
var fs = require('fs');

class CustomConvertCallback extends ConvertCallback {
  NeedToPause() {
    return true;
  }

  ProgressNotify(converted_count, total_count) {
  }
}

class CustomReaderCallback extends ReaderCallback {
  LoadFile(file_path) {
    this.file_path = file_path;
    this.fd = fs.openSync(file_path, 'r');
  }

  GetSize() {
    var states = fs.statSync(this.file_path);
    return states.size;
  }

  ReadBlock(offset, size) {
	var buf = Buffer.alloc(size);
    var read_size = fs.readSync(this.fd, buf, 0, size, offset);
    if (read_size == 0) {
      return "";
    }
    return buf.toString('binary');
  }
}

class CustomStreamCallback extends StreamCallback{
  LoadFile(file_path) {
    this.file_path = file_path;
    this.fd = fs.openSync(file_path, 'w+')
    this.curpos = 0;
    this.offset = 0;
    this.ref_ = 1;
  }

  Retain() {
    this.ref_ ++;
    return this;
  }

  Release() {
    this.ref_ -= 1;
    if(this.ref_ == 0)
      fs.closeSync(this.fd);
  }

  GetSize() {
    var states = fs.statSync(this.file_path);
    return states.size;
  }

  IsEOF() {
    var states = fs.statSync(this.file_path);
    return this.curpos - this.offset >= states.size;
  }

  GetPosition() {
    return this.curpos;
  }

  ReadBlock0(offset, size) {
    var buf = Buffer.alloc(size);
    this.offset = offset;
    var read_size = fs.readSync(this.fd, buf, 0, size, offset);
    if (read_size == 0) {
      return false;
    }
    this.curpos = offset + size;
    return buf.toString('binary');
  }

  ReadBlock1(buffer, size) {
    var states = fs.statSync(this.file_path);
    return ReadBlock0(buffer, states.size(), size);
  }

  WriteBlock(buffer, offset, size) {
    this.offset = offset;
    var buf = Buffer.from(buffer,'binary');
    var write_size = fs.writeSync(this.fd, buf,0,size,offset);
    if (write_size == size) {
      this.curpos = offset + size;
      return true;
    }
    return false;    
  }

  Flush(user_data) {
  }
}

class CustomConvertCheckCallback extends ConvertCheckCallback {
  CheckUserPermissions(user_permissions) {
    return true;
  }
}

var sn = "sv7jPzDfl1Xp7zKjQcRBSzBUyPdKu+guBygvGh6UYRIdg1leqBXgMA==";
var key = "LTceEOppvT5kiwl+7kIrRDynk1Yf2ZEWx/dcW1TEpHM5SmNMKyRHROy4VmGriH57HWffaMfF6M6MJubxQ3iyAn+JlyGdsBvv7qO3R1pqeQ5QvxjKik23m1JVmreCRjSnw0pXYuivW0vArZCljSu0y/0upmsG/QrLi3b19f80xfIvI3zR2mgmTg7QB2ggHp457yAO81nO3Cr/+T/lSfRwlr/q7fBltxATtPViSA6vpr59ipesqvq2Dvb14mim7q2O1thkJqS11UpVtRJ+5kiDgfgVb/Dqj9mAyazuO5h9fFlWnASQnBIkxr9/i3E89QFAskCSN2L0nPmam4Vat3Sy2NzQqiEIQat0hY8aGr05WIlTcr81hTBCtUsnweXtCUyG+IYF7BFl8HXItlErz+AMsXwCc9mG6E3+nLM0b7mk80rpeG+XXxbdcHZKjfjZem8qcoCITEzZsQo4DRoqeO65adCFZ7TxCzyVPQKUbFfxwmZFGRMpanuh6WJ8EcRohguAvy2sWNTQptwAzky3iXWdJVl8th5hu9AIT84xIuaXRVP9mAyvwa0fjMZQJZ/KYSwH6BEgG2oCigAjp8+/NdPy5+XrPaIjZLQxhxnJO5jtMFm/IrQmEHsytBNyJPN3TLazQhFzzgREfJ3citV7IXYw/4CUusP6I7mnNv7CHQeR4AxIL2yHZaUO9FK/YzRpuurN+Va64LVZ4Yryrw12Z40P/nrEwiaeZre/KZNjF1DBGetodpkRE/KPY739VJGI9UDb/uOQ17viH0H0ZnMFRAYvd0uQ7vfWZvGlj6jU40TheWu1yCdIqYAXa1XxDGFWU2cboGhnIC64AKS1yjv8UEUY1nWpp1tNvmykq7ZiYs1Jl0KszVDsSHDlKeSyvo4MD/J1OrR+7cFj27sya2Pt1WPhKGQ48b/vwckLzE+QyaLAaHfWuF6Xa6MzSj+PlRJo9Oa/d11N86WQV9BRj2g4vggjAbfRMGg6yS/wHadCujk6+XlVtBtpNKYV6fPKnASpn5IHPtZjm+qoyDFsuh8BHZn5UbH0JF9szdWbiEf+oZ17fna49qSPGKkl14ojW2lkb2O5e/wy/0lWFOBoI/mtUw9SA+M+VCEr6ji4xWckKKYY2eC0I3SghjMcUQgj6QyShMfl3hH9KUJ9U/eKMw4ZpDv5cG7xQ9p/I9nGX0ZrGzdV8o1pR5byw6xcRNw8rdtZS3pkVCEAuRFsicq6WRP7ro0kHaKJWzfRlQKgdZO+AHz47BzX4F6aD6KCCwIz7g==";

var error_code = Library.Initialize(sn, key);
if (ErrorCode.e_ErrSuccess != error_code) {
  if (ErrorCode.e_ErrInvalidLicense == error_code)
    console.log("[Failed] Current used Foxit PDF Conversion SDK key information is invalid.");
  else
    console.log("Library Initialize Error: %d", error_code);
  return;
}

var input_dir = "../input_files/";
var output_dir = "../output_files/pdf2office/";
if (!fs.existsSync(output_dir)) {
  fs.mkdirSync(output_dir);
}

const cb = new CustomConvertCheckCallback();
Library.SetConvertCheckCallback(cb)

var src_pdf_path = input_dir + "word.pdf";
var saved_word_file_path = output_dir + "pdf2word_result.docx";
var word_setting_data = new PDF2WordSettingData(false, true, false, false, 0);
var powerpoint_setting_data = new PDF2PowerPointSettingData(false, false);
var excel_setting_data = new PDF2ExcelSettingData("", "", WorkbookSettings.e_WorkbookSettingsEachPage, true, false)
var range = new Range();
var setting_data = new PDF2OfficeSettingData('', false, range, true, word_setting_data, powerpoint_setting_data, excel_setting_data, true, true, false);
var custom_callback = new CustomConvertCallback();

try {
  var progressive = PDF2Office.StartConvertToWordWithPath(src_pdf_path, "", saved_word_file_path, setting_data, custom_callback);
  if (progressive.GetRateOfProgress() != 100) {
    var state = State.e_ToBeContinued;
    while (State.e_ToBeContinued == state) {
      state = progressive.Continue();
    }
  }
  console.log("Convert PDF file to Word format file with path.");
} catch (e) {
  console.log(e);
}

try {
  var custom_readercallback_word = new CustomReaderCallback();
  var custom_streamcallback_word = new CustomStreamCallback();
  var src_pdf_path = input_dir + "word.pdf";
  var saved_word_file_path = output_dir + "pdf2word_stream_result.docx";
  custom_readercallback_word.LoadFile(src_pdf_path);
  custom_streamcallback_word.LoadFile(saved_word_file_path);
  var progressive = PDF2Office.StartConvertToWordWithStream(custom_readercallback_word, "", custom_streamcallback_word, setting_data, custom_callback);
  if (progressive.GetRateOfProgress() != 100) {
	var state = State.e_ToBeContinued;
	while (State.e_ToBeContinued == state) {
	  state = progressive.Continue();
	}
  }
  console.log("Convert PDF file to Word format file with stream.");
  delete custom_readercallback_word;
  delete custom_streamcallback_word;
} catch (e) {
  console.log(e);
}

try {
  var src_pdf_path = input_dir + "excel.pdf";
  var saved_excel_file_path = output_dir + "pdf2excel_result.xlsx";
  var progressive = PDF2Office.StartConvertToExcelWithPath(src_pdf_path, "", saved_excel_file_path, setting_data, custom_callback);
  if (progressive.GetRateOfProgress() != 100) {
    var state = State.e_ToBeContinued;
    while (State.e_ToBeContinued == state) {
      state = progressive.Continue();
    }
  }
  console.log("Convert PDF file to Excel format file with path.");
} catch (e) {
  console.log(e); 
}

try {
	var custom_readercallback_excel = new CustomReaderCallback();
	var custom_streamcallback_excel = new CustomStreamCallback();
	var src_pdf_path = input_dir + "excel.pdf";
	var saved_excel_file_path = output_dir + "pdf2excel_stream_result.xlsx";
	custom_readercallback_word.LoadFile(src_pdf_path);
	custom_streamcallback_word.LoadFile(saved_excel_file_path);
	var progressive = PDF2Office.StartConvertToExcelWithStream(custom_readercallback_word, "", custom_streamcallback_word, setting_data, null);
	if (progressive.GetRateOfProgress() != 100) {
		var state = State.e_ToBeContinued;
		while (State.e_ToBeContinued == state) {
		  state = progressive.Continue();
		}
	}
	console.log("Convert PDF file to Excel format file with stream.");
	delete custom_readercallback_excel;
	delete custom_streamcallback_excel;
} catch (e) {
  console.log(e); 
}

try {
  var src_pdf_path = input_dir + "powerpoint.pdf";
  var saved_powerpoint_file_path = output_dir + "pdf2powerpoint_result.pptx";
  var progressive = PDF2Office.StartConvertToPowerPointWithPath(src_pdf_path, "", saved_powerpoint_file_path, setting_data, custom_callback);
  if (progressive.GetRateOfProgress() != 100) {
    var state = State.e_ToBeContinued;
    while (State.e_ToBeContinued == state) {
      state = progressive.Continue();
    }
  }
  console.log("Convert PDF file to PowerPoint format file with path.");
} catch (e) {
  console.error(e);
}

try {
	var custom_readercallback_ppt = new CustomReaderCallback();
	var custom_streamcallback_ppt = new CustomStreamCallback();
	var src_pdf_path = input_dir + "powerpoint.pdf";
	var saved_powerpoint_file_path = output_dir + "pdf2powerpoint_stream_result.pptx";
	custom_readercallback_ppt.LoadFile(src_pdf_path);
	custom_streamcallback_ppt.LoadFile(saved_powerpoint_file_path);
	var progressive = PDF2Office.StartConvertToPowerPointWithStream(custom_readercallback_ppt, "", custom_streamcallback_ppt, setting_data, custom_callback);
	if (progressive.GetRateOfProgress() != 100) {
		var state = State.e_ToBeContinued;
		while (State.e_ToBeContinued == state) {
		  state = progressive.Continue();
		}
	  }
	console.log("Convert PDF file to PowerPoint format file with stream.");
	delete custom_readercallback_ppt;
	delete custom_streamcallback_ppt;
} catch (e) {
  console.log(e); 
}
