// Copyright 2016 The PDFium Authors
// 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_PAGE_CPDF_PAGEOBJECT_H_
#define CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECT_H_

#include <stdint.h>

#include "core/fpdfapi/page/cpdf_contentmarks.h"
#include "core/fpdfapi/page/cpdf_graphicstates.h"
#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/fx_coordinates.h"

class CPDF_FormObject;
class CPDF_ImageObject;
class CPDF_PathObject;
class CPDF_ShadingObject;
class CPDF_TextObject;

// Represents an object within the page, like a form or image. Not to be
// confused with the PDF spec's page object that lives in a page tree, which is
// represented by CPDF_Page.
class CPDF_PageObject : public CPDF_GraphicStates {
 public:
  // Values must match corresponding values in //public.
  enum class Type {
    kText = 1,
    kPath,
    kImage,
    kShading,
    kForm,
  };

  static constexpr int32_t kNoContentStream = -1;

  explicit CPDF_PageObject(int32_t content_stream);
  CPDF_PageObject(const CPDF_PageObject& src) = delete;
  CPDF_PageObject& operator=(const CPDF_PageObject& src) = delete;
  ~CPDF_PageObject() override;

  virtual Type GetType() const = 0;
  virtual void Transform(const CFX_Matrix& matrix) = 0;
  virtual bool IsText() const;
  virtual bool IsPath() const;
  virtual bool IsImage() const;
  virtual bool IsShading() const;
  virtual bool IsForm() const;
  virtual CPDF_TextObject* AsText();
  virtual const CPDF_TextObject* AsText() const;
  virtual CPDF_PathObject* AsPath();
  virtual const CPDF_PathObject* AsPath() const;
  virtual CPDF_ImageObject* AsImage();
  virtual const CPDF_ImageObject* AsImage() const;
  virtual CPDF_ShadingObject* AsShading();
  virtual const CPDF_ShadingObject* AsShading() const;
  virtual CPDF_FormObject* AsForm();
  virtual const CPDF_FormObject* AsForm() const;

  void SetDirty(bool value) { m_bDirty = value; }
  bool IsDirty() const { return m_bDirty; }
  void TransformClipPath(const CFX_Matrix& matrix);
  void TransformGeneralState(const CFX_Matrix& matrix);

  void SetOriginalRect(const CFX_FloatRect& rect) { m_OriginalRect = rect; }
  const CFX_FloatRect& GetOriginalRect() const { return m_OriginalRect; }
  void SetRect(const CFX_FloatRect& rect) { m_Rect = rect; }
  const CFX_FloatRect& GetRect() const { return m_Rect; }
  FX_RECT GetBBox() const;
  FX_RECT GetTransformedBBox(const CFX_Matrix& matrix) const;

  CPDF_ContentMarks* GetContentMarks() { return &m_ContentMarks; }
  const CPDF_ContentMarks* GetContentMarks() const { return &m_ContentMarks; }
  void SetContentMarks(const CPDF_ContentMarks& marks) {
    m_ContentMarks = marks;
  }

  // Get what content stream the object was parsed from in its page. This number
  // is the index of the content stream in the "Contents" array, or 0 if there
  // is a single content stream. If the object is newly created,
  // |kNoContentStream| is returned.
  //
  // If the object is spread among more than one content stream, this is the
  // index of the last stream.
  int32_t GetContentStream() const { return m_ContentStream; }
  void SetContentStream(int32_t new_content_stream) {
    m_ContentStream = new_content_stream;
  }

  const ByteString& GetResourceName() const { return m_ResourceName; }
  void SetResourceName(const ByteString& resource_name) {
    m_ResourceName = resource_name;
  }

  const ByteString& GetGraphicsResourceName() const {
    return m_GraphicsResourceName;
  }
  void SetGraphicsResourceName(const ByteString& resource_name) {
    m_GraphicsResourceName = resource_name;
  }

 protected:
  void CopyData(const CPDF_PageObject* pSrcObject);

 private:
  CFX_FloatRect m_Rect;
  CFX_FloatRect m_OriginalRect;
  CPDF_ContentMarks m_ContentMarks;
  bool m_bDirty = false;
  int32_t m_ContentStream;
  ByteString m_ResourceName;          // The resource name for this object.
  ByteString m_GraphicsResourceName;  // Like `m_ResourceName` but for graphics.
};

#endif  // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECT_H_
