// 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"

namespace {

CPDF_Page* GetPageFromFPDFPage(FPDF_PAGE page) {
  return static_cast<CPDF_Page*>(page);
}

void SetBoundingBox(CPDF_Page* page,
                    const CFX_ByteStringC& key,
                    float left,
                    float bottom,
                    float right,
                    float top) {
  CPDF_Dictionary* pPageDict = page->m_pFormDict;
  CPDF_Array* pBoundingBoxArray = new CPDF_Array;
  pBoundingBoxArray->Add(new CPDF_Number(left));
  pBoundingBoxArray->Add(new CPDF_Number(bottom));
  pBoundingBoxArray->Add(new CPDF_Number(right));
  pBoundingBoxArray->Add(new CPDF_Number(top));
  pPageDict->SetAt(key, pBoundingBoxArray);
}

FPDF_BOOL GetBoundingBox(CPDF_Page* page,
                         const CFX_ByteStringC& key,
                         float* left,
                         float* bottom,
                         float* right,
                         float* top) {
  CPDF_Dictionary* pPageDict = page->m_pFormDict;
  CPDF_Array* pArray = pPageDict->GetArray(key);
  if (!pArray)
    return FALSE;

  *left = pArray->GetFloat(0);
  *bottom = pArray->GetFloat(1);
  *right = pArray->GetFloat(2);
  *top = pArray->GetFloat(3);
  return TRUE;
}

}  // namespace

DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page,
                                            float left,
                                            float bottom,
                                            float right,
                                            float top) {
  CPDF_Page* pPage = GetPageFromFPDFPage(page);
  if (!pPage)
    return;

  SetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
}

DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page,
                                           float left,
                                           float bottom,
                                           float right,
                                           float top) {
  CPDF_Page* pPage = GetPageFromFPDFPage(page);
  if (!pPage)
    return;

  SetBoundingBox(pPage, "CropBox", left, bottom, right, top);
}

DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page,
                                                 float* left,
                                                 float* bottom,
                                                 float* right,
                                                 float* top) {
  CPDF_Page* pPage = GetPageFromFPDFPage(page);
  return pPage && GetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
}

DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page,
                                                float* left,
                                                float* bottom,
                                                float* right,
                                                float* top) {
  CPDF_Page* pPage = GetPageFromFPDFPage(page);
  return pPage && GetBoundingBox(pPage, "CropBox", left, bottom, right, top);
}

DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page,
                                                       FS_MATRIX* matrix,
                                                       FS_RECTF* clipRect) {
  CPDF_Page* pPage = GetPageFromFPDFPage(page);
  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 = new CPDF_Dictionary;
  CPDF_Stream* pStream = 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 = 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 = new CPDF_Reference(pDoc, pStream->GetObjNum());
        pContentArray->InsertAt(0, pRef);
        pContentArray->AddReference(pDoc, pEndStream);
      } else if (pDirectObj->GetType() == PDFOBJ_STREAM) {
        pContentArray = 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 = 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) {
  CPDF_Page* pPage = GetPageFromFPDFPage(page);
  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 = new CPDF_Dictionary;
  CPDF_Stream* pStream = 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 = 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 = new CPDF_Reference(pDoc, pStream->GetObjNum());
        pContentArray->InsertAt(0, pRef);
      } else if (pDirectObj->GetType() == PDFOBJ_STREAM) {
        pContentArray = new CPDF_Array();
        pContentArray->AddReference(pDoc, pStream->GetObjNum());
        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
        pPageDic->SetAtReference("Contents", pDoc,
                                 pDoc->AddIndirectObject(pContentArray));
      }
    }
  }
}
