// 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_edit.h"
#include "../../public/fpdf_formfill.h"
#include "../include/fsdk_define.h"

#if _FX_OS_ == _FX_ANDROID_
#include "time.h"
#else
#include <ctime>
#endif

DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() {
  CPDF_Document* pDoc = new CPDF_Document;
  pDoc->CreateNewDoc();
  time_t currentTime;

  CFX_ByteString DateStr;

  if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
    if (-1 != time(&currentTime)) {
      tm* pTM = localtime(&currentTime);
      if (pTM) {
        DateStr.Format("D:%04d%02d%02d%02d%02d%02d", pTM->tm_year + 1900,
                       pTM->tm_mon + 1, pTM->tm_mday, pTM->tm_hour, pTM->tm_min,
                       pTM->tm_sec);
      }
    }
  }

  CPDF_Dictionary* pInfoDict = NULL;
  pInfoDict = pDoc->GetInfo();
  if (pInfoDict) {
    if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
      pInfoDict->SetAt("CreationDate", new CPDF_String(DateStr));
    pInfoDict->SetAt("Creator", new CPDF_String(L"PDFium"));
  }

  return pDoc;
}

DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index) {
  CPDF_Document* pDoc = (CPDF_Document*)document;
  if (pDoc == NULL)
    return;
  if (page_index < 0 || page_index >= pDoc->GetPageCount())
    return;

  pDoc->DeletePage(page_index);
}

DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document,
                                         int page_index,
                                         double width,
                                         double height) {
  if (!document)
    return NULL;

  //	CPDF_Parser* pParser = (CPDF_Parser*)document;
  CPDF_Document* pDoc = (CPDF_Document*)document;
  if (page_index < 0)
    page_index = 0;
  if (pDoc->GetPageCount() < page_index)
    page_index = pDoc->GetPageCount();
  //	if (page_index < 0 || page_index >= pDoc->GetPageCount())
  //		return NULL;

  CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index);
  if (!pPageDict)
    return NULL;
  CPDF_Array* pMediaBoxArray = new CPDF_Array;
  pMediaBoxArray->Add(new CPDF_Number(0));
  pMediaBoxArray->Add(new CPDF_Number(0));
  pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width)));
  pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height)));

  pPageDict->SetAt("MediaBox", pMediaBoxArray);
  pPageDict->SetAt("Rotate", new CPDF_Number(0));
  pPageDict->SetAt("Resources", new CPDF_Dictionary);

  CPDF_Page* pPage = new CPDF_Page;
  pPage->Load(pDoc, pPageDict);
  pPage->ParseContent();

  return pPage;
}

DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) {
  CPDF_Page* pPage = (CPDF_Page*)page;
  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
          "Page")) {
    return -1;
  }
  CPDF_Dictionary* pDict = pPage->m_pFormDict;

  int rotate = 0;
  if (pDict != NULL) {
    if (pDict->KeyExist("Rotate"))
      rotate = pDict->GetElement("Rotate")->GetDirect()
                   ? pDict->GetElement("Rotate")->GetDirect()->GetInteger() / 90
                   : 0;
    else {
      if (pDict->KeyExist("Parent")) {
        CPDF_Dictionary* pPages =
            (CPDF_Dictionary*)pDict->GetElement("Parent")->GetDirect();
        while (pPages) {
          if (pPages->KeyExist("Rotate")) {
            rotate =
                pPages->GetElement("Rotate")->GetDirect()
                    ? pPages->GetElement("Rotate")->GetDirect()->GetInteger() /
                          90
                    : 0;
            break;
          } else if (pPages->KeyExist("Parent"))
            pPages =
                (CPDF_Dictionary*)pPages->GetElement("Parent")->GetDirect();
          else
            break;
        }
      }
    }
  } else {
    return -1;
  }

  return rotate;
}

DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page,
                                             FPDF_PAGEOBJECT page_obj) {
  CPDF_Page* pPage = (CPDF_Page*)page;
  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
          "Page")) {
    return;
  }
  CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj;
  if (pPageObj == NULL)
    return;
  FX_POSITION LastPersition = pPage->GetLastObjectPosition();

  pPage->InsertObject(LastPersition, pPageObj);
  switch (pPageObj->m_Type) {
    case FPDF_PAGEOBJ_PATH: {
      CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
      pPathObj->CalcBoundingBox();
      break;
    }
    case FPDF_PAGEOBJ_TEXT: {
      //	CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
      //	pPathObj->CalcBoundingBox();
      break;
    }
    case FPDF_PAGEOBJ_IMAGE: {
      CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pPageObj;
      pImageObj->CalcBoundingBox();
      break;
    }
    case FPDF_PAGEOBJ_SHADING: {
      CPDF_ShadingObject* pShadingObj = (CPDF_ShadingObject*)pPageObj;
      pShadingObj->CalcBoundingBox();
      break;
    }
    case FPDF_PAGEOBJ_FORM: {
      CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
      pFormObj->CalcBoundingBox();
      break;
    }
    default:
      break;
  }

  //	pPage->ParseContent();
  // pPage->GenerateContent();
}

DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) {
  CPDF_Page* pPage = (CPDF_Page*)page;
  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
          "Page")) {
    return -1;
  }
  return pPage->CountObjects();
  //	return 0;
}

DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page,
                                                     int index) {
  CPDF_Page* pPage = (CPDF_Page*)page;
  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
          "Page")) {
    return NULL;
  }
  return pPage->GetObjectByIndex(index);
  //	return NULL;
}

DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page) {
  if (!page)
    return FALSE;
  CPDF_Page* pPage = (CPDF_Page*)page;

  return pPage->BackgroundAlphaNeeded();
}

DLLEXPORT FPDF_BOOL STDCALL
FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) {
  if (!pageObject)
    return FALSE;
  CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject;

  const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
  int blend_type =
      pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
  if (blend_type != FXDIB_BLEND_NORMAL)
    return TRUE;

  CPDF_Dictionary* pSMaskDict =
      pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL;
  if (pSMaskDict)
    return TRUE;

  if (pGeneralState && pGeneralState->m_FillAlpha != 1.0f)
    return TRUE;

  if (pPageObj->m_Type == PDFPAGE_PATH) {
    if (pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f)
      return TRUE;
  }

  if (pPageObj->m_Type == PDFPAGE_FORM) {
    CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
    if (pFormObj->m_pForm &&
        (pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED))
      return TRUE;
    if (pFormObj->m_pForm &&
        (!(pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED) &&
         (pFormObj->m_pForm->m_Transparency & PDFTRANS_GROUP)))
      return TRUE;
  }
  return FALSE;
}

DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page) {
  CPDF_Page* pPage = (CPDF_Page*)page;
  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
          "Page")) {
    return FALSE;
  }
  CPDF_PageContentGenerate CG(pPage);
  CG.GenerateContent();

  return TRUE;
}

DLLEXPORT void STDCALL FPDFPageObj_Transform(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);
  pPageObj->Transform(matrix);
}
DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
                                                double a,
                                                double b,
                                                double c,
                                                double d,
                                                double e,
                                                double f) {
  if (page == NULL)
    return;
  CPDF_Page* pPage = (CPDF_Page*)page;
  CPDF_AnnotList AnnotList(pPage);
  for (int i = 0; i < AnnotList.Count(); i++) {
    CPDF_Annot* pAnnot = AnnotList.GetAt(i);
    // transformAnnots Rectangle
    CPDF_Rect rect;
    pAnnot->GetRect(rect);
    CFX_AffineMatrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
                            (FX_FLOAT)e, (FX_FLOAT)f);
    rect.Transform(&matrix);
    CPDF_Array* pRectArray = NULL;
    pRectArray = pAnnot->GetAnnotDict()->GetArray("Rect");
    if (!pRectArray)
      pRectArray = CPDF_Array::Create();
    pRectArray->SetAt(0, new CPDF_Number(rect.left));
    pRectArray->SetAt(1, new CPDF_Number(rect.bottom));
    pRectArray->SetAt(2, new CPDF_Number(rect.right));
    pRectArray->SetAt(3, new CPDF_Number(rect.top));
    pAnnot->GetAnnotDict()->SetAt("Rect", pRectArray);

    // Transform AP's rectangle
    // To Do
  }
}

DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) {
  CPDF_Page* pPage = (CPDF_Page*)page;
  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
          "Page")) {
    return;
  }
  CPDF_Dictionary* pDict = pPage->m_pFormDict;
  rotate %= 4;

  pDict->SetAt("Rotate", new CPDF_Number(rotate * 90));
}
