/*
	Antenna House PDF Tool API V8.0
	C++ Interface sample program

	概要：テキスト検索して下線、波線、取り消し線注釈

	Copyright 2025- Antenna House, Inc.
*/

#include <PdfTk.h>
#include <stdio.h>

using namespace PdfTk;

void addAnnotSquiggly(PtlAnnots&, PtlQuadPoint&, bool);
void addAnnotStrikeOut(PtlAnnots&, PtlQuadPoint&, bool);
void addAnnotUnderline(PtlAnnots&, PtlQuadPoint&, bool);

int main(int argc, char* argv[])
{
	if (argc < 4) {
		printf("usage: SearchTextAndHighlight.exe in-pdf-file out-pdf-file keyword\n");
		return 1;
	}
	try
	{
		PtlParamInput input(argv[1]);
		PtlParamOutput output(argv[2]);
		PtlParamString keyword(argv[3]);

		PtlPDFDocument doc;

		// PDFファイルをロードします。
		doc.load(input);

		PtlPages& pages = doc.getPages();

		//// ハイライト注釈の色
		//PtlColorDeviceRGB colorRed(1.0f, 0.0f, 0.0f);

		// 検索の為のパラメータ
		PtlParamSearchText paramSearchText;

		paramSearchText.appendText(keyword);
		paramSearchText.setTextType(PtlParamSearchText::TEXT_RAW);

		// 検索実行して検索結果コンテナ取得
		PtlSearchTextResults results = doc.searchText(paramSearchText);
		int numResults = results.getCount();
		for (int i=0; i < numResults; ++i) {
			// 検索結果取得
			PtlSearchTextResult& result = results.get(i);
			// 検索に使用したキーワード
			PtlParamString keyword = result.getKeyword();
			//const char* keywordC = keyword.c_str();

			// ヒットしたページ番号
			int pageNumber = result.getPageNumber();
			PtlPage page = pages.get(pageNumber);
			PtlAnnots& annots = page.getAnnots();

			// 検索結果詳細コンテナ取得
			PtlSearchTextResultDetails& details = result.getResultDetails();
			int numDetails = details.getCount();
			for (int j=0; j < numDetails; ++j) {
				// 検索結果詳細取得
				PtlSearchTextResultDetail& resultDetail = details.get(j);
				// 検索に使用したキーワードの部分文字列
				PtlParamString keyword = resultDetail.getKeyword();
				//const char* keywordC = keyword.c_str();
				// 検索に使用したキーワードの部分文字列を囲むQuadPoint
				PtlQuadPoint quad = resultDetail.getQuadPoint();
				// 検索に使用したキーワードの部分文字列が縦書きか
				bool verticalWriting = resultDetail.isVerticalWriting();

				//注釈の追加
				switch(i % 3)
				{
				case 0:
					//波状下線注釈
					addAnnotSquiggly(annots, quad, verticalWriting);
					break;
				case 1:
					//取り消し線注釈
					addAnnotStrikeOut(annots, quad, verticalWriting);
					break;
				case 2:
					//下線注釈
					addAnnotUnderline(annots, quad, verticalWriting);
					break;
				}
			}
		}

		// ファイルに保存します。
		doc.save(output);

		printf("完了!\n");
	}
	catch (const PtlException &e)
	{
		fprintf(stderr, "Error code : %d\n %s\n", e.getErrorCode(), e.getErrorMessage().c_str());
		return 1;
	}	
	return 0;
}

void addAnnotSquiggly(PtlAnnots& annots, PtlQuadPoint& quadPoint, bool verticalWriting)
{
	//波状下線注釈
	PtlAnnotSquiggly annotSquiggly;

	//矩形座標を設定 座標の単位はmmで原点(0,0)は左下
	PtlQuadPoints& quadPoints = annotSquiggly.getQuadPoints();
	quadPoints.append(quadPoint);

	//テキストを縦書き方向に囲むかどうかを設定
	annotSquiggly.setVerticalDirection(verticalWriting);

	//内容を設定（注釈用に表示されるテキスト・可読な形式での注釈コンテンツの代替説明）
	annotSquiggly.setTextContents("波状下線注釈サンプル");

	// 日時の設定(2025/01/01 00:00:00)
	annotSquiggly.setDate(PtlDate(2025, 1, 1, 0, 0, 0));

	//注釈フラグを設定（論理和） FLAG_NOROTATE = 0x00000010, /* 注釈の外観をページにあわせて回転しません。 */
	annotSquiggly.setAnnotFlags(PtlAnnotText::FLAG_NOROTATE);

	//色を設定 setColor(const PtlColorDeviceRGB& color);
	PtlColorDeviceRGB color(1.0f, 0.0f, 0.0f);
	annotSquiggly.setColor(color);

	//境界線スタイルを設定 BORDER_SOLID = 1, /* 実線(注釈を囲む実線の矩形) */
	annotSquiggly.setBorderStyle(PtlAnnotText::BORDER_SOLID);

	//境界線幅を設定 BORDER_WIDTH_THIN = 1, /* 細い */
	annotSquiggly.setBorderWidth(PtlAnnotText::BORDER_WIDTH_THIN);

	//注釈の追加
	annots.append(annotSquiggly);
}

void addAnnotStrikeOut(PtlAnnots& annots, PtlQuadPoint& quadPoint, bool verticalWriting)
{
	//取り消し線注釈
	PtlAnnotStrikeOut annotStrikeOut;

	//矩形座標を設定 座標の単位はmmで原点(0,0)は左下
	PtlQuadPoints& quadPoints = annotStrikeOut.getQuadPoints();
	quadPoints.append(quadPoint);

	//テキストを縦書き方向に囲むかどうかを設定
	annotStrikeOut.setVerticalDirection(verticalWriting);

	//内容を設定（注釈用に表示されるテキスト・可読な形式での注釈コンテンツの代替説明）
	annotStrikeOut.setTextContents("取り消し線注釈サンプル");

	// 日時の設定(2025/01/01 00:00:00)
	annotStrikeOut.setDate(PtlDate(2025, 1, 1, 0, 0, 0));

	//注釈フラグを設定（論理和） FLAG_NOROTATE = 0x00000010, /* 注釈の外観をページにあわせて回転しません。 */
	annotStrikeOut.setAnnotFlags(PtlAnnotText::FLAG_NOROTATE);

	//色を設定 setColor(const PtlColorDeviceRGB& color);
	PtlColorDeviceRGB color(1.0f, 0.0f, 0.0f);
	annotStrikeOut.setColor(color);

	//境界線スタイルを設定 BORDER_SOLID = 1, /* 実線(注釈を囲む実線の矩形) */
	annotStrikeOut.setBorderStyle(PtlAnnotText::BORDER_SOLID);

	//境界線幅を設定 BORDER_WIDTH_THIN = 1, /* 細い */
	annotStrikeOut.setBorderWidth(PtlAnnotText::BORDER_WIDTH_THIN);

	//注釈の追加
	annots.append(annotStrikeOut);
}

void addAnnotUnderline(PtlAnnots& annots, PtlQuadPoint& quadPoint, bool verticalWriting)
{
	//下線注釈
	PtlAnnotUnderline annotUnderline;

	//矩形座標を設定 座標の単位はmmで原点(0,0)は左下
	PtlQuadPoints& quadPoints = annotUnderline.getQuadPoints();
	quadPoints.append(quadPoint);

	//テキストを縦書き方向に囲むかどうかを設定
	annotUnderline.setVerticalDirection(verticalWriting);

	//内容を設定（注釈用に表示されるテキスト・可読な形式での注釈コンテンツの代替説明）
	annotUnderline.setTextContents("下線注釈サンプル");

	//日時の設定(2025/01/01 00:00:00)
	annotUnderline.setDate(PtlDate(2025, 1, 1, 0, 0, 0));

	//注釈フラグを設定（論理和） FLAG_NOROTATE = 0x00000010, /* 注釈の外観をページにあわせて回転しません。 */
	annotUnderline.setAnnotFlags(PtlAnnotText::FLAG_NOROTATE);

	//色を設定 setColor(const PtlColorDeviceRGB& color);
	PtlColorDeviceRGB color(1.0f, 0.0f, 0.0f);
	annotUnderline.setColor(color);

	//境界線スタイルを設定 BORDER_SOLID = 1, /* 実線(注釈を囲む実線の矩形) */
	annotUnderline.setBorderStyle(PtlAnnotText::BORDER_SOLID);

	//境界線幅を設定 BORDER_WIDTH_THIN = 1, /* 細い */
	annotUnderline.setBorderWidth(PtlAnnotText::BORDER_WIDTH_THIN);

	//注釈の追加
	annots.append(annotUnderline);
}
