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

#ifndef CORE_FPDFAPI_EDIT_CPDF_CREATOR_H_
#define CORE_FPDFAPI_EDIT_CPDF_CREATOR_H_

#include <map>
#include <memory>
#include <vector>

#include "core/fxcrt/cfx_retain_ptr.h"
#include "core/fxcrt/cfx_unowned_ptr.h"
#include "core/fxcrt/fx_basic.h"

class CPDF_Array;
class CPDF_CryptoHandler;
class CPDF_Dictionary;
class CPDF_Document;
class CPDF_Object;
class CPDF_Parser;

#define FPDFCREATE_INCREMENTAL 1
#define FPDFCREATE_NO_ORIGINAL 2

class CPDF_Creator {
 public:
  explicit CPDF_Creator(CPDF_Document* pDoc,
                        const CFX_RetainPtr<IFX_WriteStream>& archive);
  ~CPDF_Creator();

  void RemoveSecurity();
  bool Create(uint32_t flags);
  int32_t Continue();
  bool SetFileVersion(int32_t fileVersion);

  IFX_ArchiveStream* GetArchive() { return m_Archive.get(); }

  uint32_t GetNextObjectNumber() { return ++m_dwLastObjNum; }
  uint32_t GetLastObjectNumber() const { return m_dwLastObjNum; }
  CPDF_CryptoHandler* GetCryptoHandler() { return m_pCryptoHandler.Get(); }
  CPDF_Document* GetDocument() const { return m_pDocument.Get(); }
  CPDF_Array* GetIDArray() const { return m_pIDArray.get(); }
  CPDF_Dictionary* GetEncryptDict() const { return m_pEncryptDict.Get(); }
  uint32_t GetEncryptObjectNumber() const { return m_dwEncryptObjNum; }

  uint32_t GetObjectOffset(uint32_t objnum) { return m_ObjectOffsets[objnum]; }
  bool HasObjectNumber(uint32_t objnum) {
    return m_ObjectOffsets.find(objnum) != m_ObjectOffsets.end();
  }
  void SetObjectOffset(uint32_t objnum, FX_FILESIZE offset) {
    m_ObjectOffsets[objnum] = offset;
  }
  bool IsIncremental() const { return !!(m_dwFlags & FPDFCREATE_INCREMENTAL); }
  bool IsOriginal() const { return !(m_dwFlags & FPDFCREATE_NO_ORIGINAL); }

 private:
  void Clear();

  void InitOldObjNumOffsets();
  void InitNewObjNumOffsets();
  void InitID();

  int32_t WriteDoc_Stage1();
  int32_t WriteDoc_Stage2();
  int32_t WriteDoc_Stage3();
  int32_t WriteDoc_Stage4();

  bool WriteOldIndirectObject(uint32_t objnum);
  bool WriteOldObjs();
  bool WriteNewObjs();
  bool WriteDirectObj(uint32_t objnum, const CPDF_Object* pObj, bool bEncrypt);
  bool WriteIndirectObj(uint32_t objnum, const CPDF_Object* pObj);

  bool WriteStream(const CPDF_Object* pStream,
                   uint32_t objnum,
                   CPDF_CryptoHandler* pCrypto);

  bool IsXRefNeedEnd();

  CFX_UnownedPtr<CPDF_Document> const m_pDocument;
  CFX_UnownedPtr<CPDF_Parser> const m_pParser;
  bool m_bSecurityChanged;
  CFX_UnownedPtr<CPDF_Dictionary> m_pEncryptDict;
  uint32_t m_dwEncryptObjNum;
  CFX_RetainPtr<CPDF_CryptoHandler> m_pCryptoHandler;
  CFX_UnownedPtr<CPDF_Object> m_pMetadata;
  uint32_t m_dwLastObjNum;
  std::unique_ptr<IFX_ArchiveStream> m_Archive;
  FX_FILESIZE m_SavedOffset;
  int32_t m_iStage;
  uint32_t m_dwFlags;
  uint32_t m_CurObjNum;
  FX_FILESIZE m_XrefStart;
  std::map<uint32_t, FX_FILESIZE> m_ObjectOffsets;
  std::vector<uint32_t> m_NewObjNumArray;  // Sorted, ascending.
  std::unique_ptr<CPDF_Array> m_pIDArray;
  int32_t m_FileVersion;
};

#endif  // CORE_FPDFAPI_EDIT_CPDF_CREATOR_H_
