// 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 "../../public/fpdf_transformpage.h"
#include "../include/fsdk_define.h"
#include "../include/fpdfxfa/fpdfxfa_doc.h"
#include "../include/fpdfxfa/fpdfxfa_page.h"

DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page, float left, float bottom, float right, float top)
{
	if(!page)
		return;
	CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
	if (!pPage) return;
	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
	CPDF_Array* pMediaBoxArray = FX_NEW CPDF_Array;
	pMediaBoxArray->Add(FX_NEW CPDF_Number(left));
	pMediaBoxArray->Add(FX_NEW CPDF_Number(bottom));
	pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(right)));
	pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(top)));

	pPageDict->SetAt("MediaBox", pMediaBoxArray);
}


DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page, float left, float bottom, float right, float top)
{
	if(!page)
		return;
	CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
	if (!pPage) return;
	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
	CPDF_Array* pCropBoxArray = FX_NEW CPDF_Array;
	pCropBoxArray->Add(FX_NEW CPDF_Number(left));
	pCropBoxArray->Add(FX_NEW CPDF_Number(bottom));
	pCropBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(right)));
	pCropBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(top)));


	pPageDict->SetAt("CropBox", pCropBoxArray);
}


DLLEXPORT FX_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page, float* left, float* bottom, float* right, float* top)
{
	if(!page)
		return FALSE;
	CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
	if (!pPage) return FALSE;
	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
	CPDF_Array* pArray = pPageDict->GetArray("MediaBox");
	if(pArray)
	{
		*left = pArray->GetFloat(0);
		*bottom = pArray->GetFloat(1);
		*right = pArray->GetFloat(2);
		*top = pArray->GetFloat(3);
		return TRUE;
	}
	return FALSE;
}

DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page, float* left, float* bottom, float* right, float* top)
{
	if(!page)
		return FALSE;
	CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
	if (!pPage) return FALSE;
	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
	CPDF_Array* pArray = pPageDict->GetArray("CropBox");
	if(pArray)
	{
		*left = pArray->GetFloat(0);
		*bottom = pArray->GetFloat(1);
		*right = pArray->GetFloat(2);
		*top = pArray->GetFloat(3);
		return TRUE;
	}
	return FALSE;
}

DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect)
{
	if(!page)
		return FALSE;

	CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
	if (!pPage)
		return FALSE;

	CFX_ByteTextBuf textBuf;
	textBuf<<"q ";
	CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right, clipRect->top);
	rect.Normalize();
	CFX_ByteString bsClipping;
	bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height());
	textBuf<<bsClipping;

	CFX_ByteString bsMatix;
	bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b,matrix->c,matrix->d,matrix->e,matrix->f);
	textBuf<<bsMatix;


	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic ? pPageDic->GetElement("Contents") : NULL;
	if(!pContentObj)
		pContentObj = pPageDic ? pPageDic->GetArray("Contents") : NULL;
	if(!pContentObj)
		return FALSE;

	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return FALSE;
	pDoc->AddIndirectObject(pStream);

	pDic = new CPDF_Dictionary;
	CPDF_Stream* pEndStream = new CPDF_Stream(NULL,0, pDic);
	pEndStream->SetData((const uint8_t*)" Q", 2, FALSE, FALSE);
	pDoc->AddIndirectObject(pEndStream);

	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		pContentArray->AddReference(pDoc,pEndStream);

	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				pContentArray->AddReference(pDoc,pEndStream);

			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pContentArray->AddReference(pDoc, pEndStream);
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}

	//Need to transform the patterns as well.
	CPDF_Dictionary* pRes = pPageDic->GetDict(FX_BSTRC("Resources"));
	if(pRes)
	{
		CPDF_Dictionary* pPattenDict = pRes->GetDict(FX_BSTRC("Pattern"));
		if(pPattenDict)
		{
			FX_POSITION pos = pPattenDict->GetStartPos();
			while(pos)
			{
				CPDF_Dictionary* pDict = NULL;
				CFX_ByteString key;
				CPDF_Object* pObj = pPattenDict->GetNextElement(pos, key);
				if(pObj->GetType() == PDFOBJ_REFERENCE)
					pObj = pObj->GetDirect();
				if(pObj->GetType() == PDFOBJ_DICTIONARY)
				{
					pDict = (CPDF_Dictionary*)pObj;
				}
				else if(pObj->GetType() == PDFOBJ_STREAM)
				{
					pDict = ((CPDF_Stream*)pObj)->GetDict();
				}
				else
					continue;

				CFX_AffineMatrix m = pDict->GetMatrix(FX_BSTRC("Matrix"));
				CFX_AffineMatrix t = *(CFX_AffineMatrix*)matrix;
				m.Concat(t);
				pDict->SetAtMatrix(FX_BSTRC("Matrix"), m);
			}
		}
	}

	return TRUE;
}

DLLEXPORT void STDCALL FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object,double a, double b, double c, double d, double e, double f)
{
	CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
	if(pPageObj == NULL)
		return;
	CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f);

	//Special treatment to shading object, because the ClipPath for shading object is already transformed.
	if(pPageObj->m_Type != PDFPAGE_SHADING)
		pPageObj->TransformClipPath(matrix);
	pPageObj->TransformGeneralState(matrix);
}


DLLEXPORT FPDF_CLIPPATH STDCALL FPDF_CreateClipPath(float left, float bottom, float right, float top)
{
	CPDF_ClipPath* pNewClipPath =  FX_NEW CPDF_ClipPath();
	pNewClipPath->GetModify();
	CPDF_Path Path;
	Path.GetModify();
	Path.AppendRect(left, bottom, right, top);
	pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, FALSE);
	return pNewClipPath;
}

DLLEXPORT void STDCALL FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath)
{
    delete (CPDF_ClipPath*)clipPath;
}

void OutputPath(CFX_ByteTextBuf& buf, CPDF_Path path)
{
	const CFX_PathData* pPathData = path;
	if (pPathData == NULL) return;

	FX_PATHPOINT* pPoints = pPathData->GetPoints();

	if (path.IsRect()) {
		buf << (pPoints[0].m_PointX) << " " << (pPoints[0].m_PointY) << " "
			<< (pPoints[2].m_PointX - pPoints[0].m_PointX) << " "
			<< (pPoints[2].m_PointY - pPoints[0].m_PointY) << " re\n";
		return;
	}

	CFX_ByteString temp;
	for (int i = 0; i < pPathData->GetPointCount(); i ++) {
		buf << (pPoints[i].m_PointX) << " " << (pPoints[i].m_PointY);
		int point_type = pPoints[i].m_Flag & FXPT_TYPE;
		if (point_type == FXPT_MOVETO)
			buf << " m\n";
		else if (point_type == FXPT_BEZIERTO) {
			buf << " " << (pPoints[i+1].m_PointX) << " " << (pPoints[i+1].m_PointY) << " " <<
				(pPoints[i+2].m_PointX) << " " << (pPoints[i+2].m_PointY);
			if (pPoints[i+2].m_Flag & FXPT_CLOSEFIGURE)
				buf << " c h\n";
			else
				buf << " c\n";
			i += 2;
		} else if (point_type == FXPT_LINETO) {
			if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE)
				buf << " l h\n";
			else
				buf << " l\n";
		}
	}
}

DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clipPath)
{
	if(!page)
		return;
	CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
	if (!pPage) return;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic ? pPageDic->GetElement("Contents") : NULL;
	if(!pContentObj)
		pContentObj = pPageDic ? pPageDic->GetArray("Contents") : NULL;
	if(!pContentObj)
		return;

	CFX_ByteTextBuf strClip;
	CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
	FX_DWORD i;
	for (i = 0; i < pClipPath->GetPathCount(); i ++) {
		CPDF_Path path = pClipPath->GetPath(i);
		int iClipType = pClipPath->GetClipType(i);
		if (path.GetPointCount() == 0) {
			// Empty clipping (totally clipped out)
			strClip << "0 0 m W n ";
		} else {
			OutputPath(strClip, path);
			if (iClipType == FXFILL_WINDING)
				strClip << "W n\n";
			else
				strClip << "W* n\n";
		}
	}
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return;
	pDoc->AddIndirectObject(pStream);

	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);

	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);

			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}
}

