// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../include/fsdk_define.h"
#include "../include/fpdfdoc.h"

static int this_module = 0;

static CPDF_Bookmark FindBookmark(CPDF_BookmarkTree& tree, CPDF_Bookmark This, const CFX_WideString& title)
{
	if (This != NULL) {
		// First check this item
		CFX_WideString this_title = This.GetTitle();
		if (this_title.CompareNoCase(title) == 0)
			return This;
	}
	// go into children items
	CPDF_Bookmark Child = tree.GetFirstChild(This);
	while (Child != NULL) {
		// check if this item
		CPDF_Bookmark Found = FindBookmark(tree, Child, title);
		if (Found) return Found;
		Child = tree.GetNextSibling(Child);
	}
	return NULL;
}

DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document, FPDF_WIDESTRING title)
{
	if (document == NULL) return NULL;
	if (title == NULL || title[0] == 0) return NULL;

	CPDF_Document* pDoc = (CPDF_Document*)document;
	CPDF_BookmarkTree tree(pDoc);

	CFX_WideString wstr = CFX_WideString::FromUTF16LE(title);
	return FindBookmark(tree, NULL, wstr);
}

DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark)
{
	if (document == NULL) return NULL;
	if (bookmark == NULL) return NULL;

	CPDF_Bookmark Bookmark = (CPDF_Dictionary*)bookmark;
	CPDF_Document* pDoc = (CPDF_Document*)document;
	CPDF_Dest dest = Bookmark.GetDest(pDoc);
	if (dest != NULL) return dest;

	// If this bookmark is not directly associated with a dest, we try to get action
	CPDF_Action Action = Bookmark.GetAction();
	if (Action == NULL) return NULL;
	return Action.GetDest(pDoc);
}

DLLEXPORT FPDF_ACTION STDCALL FPDFBookmark_GetAction(FPDF_BOOKMARK bookmark)
{
	if (bookmark == NULL) return NULL;

	CPDF_Bookmark Bookmark = (CPDF_Dictionary*)bookmark;
	return Bookmark.GetAction();
}

DLLEXPORT unsigned long STDCALL FPDFAction_GetType(FPDF_ACTION action)
{
	if (action == NULL) return 0;

	CPDF_Action Action = (CPDF_Dictionary*)action;
	CPDF_Action::ActionType type = Action.GetType();
	switch (type) {
	case CPDF_Action::GoTo:
		return PDFACTION_GOTO;
	case CPDF_Action::GoToR:
		return PDFACTION_REMOTEGOTO;
	case CPDF_Action::URI:
		return PDFACTION_URI;
	case CPDF_Action::Launch:
		return PDFACTION_LAUNCH;
	default:
		return PDFACTION_UNSUPPORTED;
	}
	return PDFACTION_UNSUPPORTED;
}

DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document, FPDF_ACTION action)
{
	if (document == NULL) return NULL;
	if (action == NULL) return NULL;
	CPDF_Document* pDoc = (CPDF_Document*)document;
	CPDF_Action Action = (CPDF_Dictionary*)action;

	return Action.GetDest(pDoc);
}

DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document, FPDF_ACTION action, 
											  void* buffer, unsigned long buflen)
{
	if (document == NULL) return 0;
	if (action == NULL) return 0;
	CPDF_Document* pDoc = (CPDF_Document*)document;
	CPDF_Action Action = (CPDF_Dictionary*)action;

	CFX_ByteString path = Action.GetURI(pDoc);
	unsigned long len = path.GetLength() + 1;
	if (buffer != NULL && buflen >= len)
		FXSYS_memcpy(buffer, (FX_LPCSTR)path, len);
	return len;
}

DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document, FPDF_DEST dest)
{
	if (document == NULL) return 0;
	if (dest == NULL) return 0;
	CPDF_Document* pDoc = (CPDF_Document*)document;
	CPDF_Dest Dest = (CPDF_Array*)dest;

	return Dest.GetPageIndex(pDoc);
}

static void ReleaseLinkList(FX_LPVOID data)
{
	delete (CPDF_LinkList*)data;
}

DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page, double x, double y)
{
	if (page == NULL) return NULL;
	CPDF_Page* pPage = (CPDF_Page*)page;

	// Link list is stored with the document
	CPDF_Document* pDoc = pPage->m_pDocument;
	CPDF_LinkList* pLinkList = (CPDF_LinkList*)pDoc->GetPrivateData(&this_module);
	if (pLinkList == NULL) {
		pLinkList = FX_NEW CPDF_LinkList(pDoc);
		pDoc->SetPrivateData(&this_module, pLinkList, ReleaseLinkList);
	}

	return pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y);
}

DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document, FPDF_LINK link)
{
	if (document == NULL) return NULL;
	CPDF_Document* pDoc = (CPDF_Document*)document;
	if (link == NULL) return NULL;
	CPDF_Link Link = (CPDF_Dictionary*)link;

	FPDF_DEST dest = Link.GetDest(pDoc);
	if (dest) return dest;

	// If this link is not directly associated with a dest, we try to get action
	CPDF_Action Action = Link.GetAction();
	if (Action == NULL) return NULL;
	return Action.GetDest(pDoc);
}

DLLEXPORT FPDF_ACTION STDCALL FPDFLink_GetAction(FPDF_LINK link)
{
	if (link == NULL) return NULL;
	CPDF_Link Link = (CPDF_Dictionary*)link;

	return Link.GetAction();
}

DLLEXPORT FPDF_BOOL STDCALL FPDFLink_Enumerate(FPDF_PAGE page, int* startPos, FPDF_LINK* linkAnnot)
{
	if(!page || !startPos || !linkAnnot)
		return FALSE;
	CPDF_Page* pPage = (CPDF_Page*)page;
	if(!pPage->m_pFormDict) return FALSE;
	CPDF_Array* pAnnots = pPage->m_pFormDict->GetArray("Annots");
	if(!pAnnots) return FALSE;
	for (int i = *startPos; i < (int)pAnnots->GetCount(); i ++) {
		CPDF_Dictionary* pDict = (CPDF_Dictionary*)pAnnots->GetElementValue(i);
		if (pDict == NULL || pDict->GetType() != PDFOBJ_DICTIONARY) continue;
		if(pDict->GetString(FX_BSTRC("Subtype")).Equal(FX_BSTRC("Link")))
		{
			*startPos = i+1;
			*linkAnnot = (FPDF_LINK)pDict; 
			return TRUE;
		}
	}
	return FALSE;
}

DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetAnnotRect(FPDF_LINK linkAnnot, FS_RECTF* rect)
{
	if(!linkAnnot || !rect)
		return FALSE;
	CPDF_Dictionary* pAnnotDict = (CPDF_Dictionary*)linkAnnot;
	CPDF_Rect rt = pAnnotDict->GetRect(FX_BSTRC("Rect"));
	rect->left = rt.left;
	rect->bottom = rt.bottom;
	rect->right = rt.right;
	rect->top = rt.top;
	return TRUE;
}

DLLEXPORT int STDCALL FPDFLink_CountQuadPoints(FPDF_LINK linkAnnot)
{
	if(!linkAnnot)
		return 0;
	CPDF_Dictionary* pAnnotDict = (CPDF_Dictionary*)linkAnnot;
	CPDF_Array* pArray = pAnnotDict->GetArray(FX_BSTRC("QuadPoints"));
	if (pArray == NULL)
		return 0;
	else
		return pArray->GetCount() / 8;
}

DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetQuadPoints(FPDF_LINK linkAnnot, int quadIndex, FS_QUADPOINTSF* quadPoints)
{
	if(!linkAnnot || !quadPoints)
		return FALSE;
	CPDF_Dictionary* pAnnotDict = (CPDF_Dictionary*)linkAnnot;
	CPDF_Array* pArray = pAnnotDict->GetArray(FX_BSTRC("QuadPoints"));
	if (pArray) {
		if (0 > quadIndex || quadIndex >= (int)pArray->GetCount()/8 ||
			((quadIndex*8+7) >= (int)pArray->GetCount())) return FALSE;
		quadPoints->x1 = pArray->GetNumber(quadIndex*8);
		quadPoints->y1 = pArray->GetNumber(quadIndex*8+1);
		quadPoints->x2 = pArray->GetNumber(quadIndex*8+2);
		quadPoints->y2 = pArray->GetNumber(quadIndex*8+3);
		quadPoints->x3 = pArray->GetNumber(quadIndex*8+4);
		quadPoints->y3 = pArray->GetNumber(quadIndex*8+5);
		quadPoints->x4 = pArray->GetNumber(quadIndex*8+6);
		quadPoints->y4 = pArray->GetNumber(quadIndex*8+7);
		return TRUE;
	} 
	return FALSE;
}


DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc, FPDF_BYTESTRING tag,
												 void* buffer, unsigned long buflen)
{
	if (doc == NULL || tag == NULL) return 0;

	CPDF_Document* pDoc = (CPDF_Document*)doc;
	// Get info dictionary
	CPDF_Dictionary* pInfo = pDoc->GetInfo();
	if (pInfo == NULL) return 0;

	CFX_WideString text = pInfo->GetUnicodeText(tag);

	// Use UTF-16LE encoding
	CFX_ByteString bstr = text.UTF16LE_Encode();
	unsigned long len = bstr.GetLength();
	if (buffer != NULL || buflen >= len+2) {
		FXSYS_memcpy(buffer, (FX_LPCSTR)bstr, len);
		// use double zero as trailer
		((FX_BYTE*)buffer)[len] = ((FX_BYTE*)buffer)[len+1] = 0;
	}
	return len+2;
}

