#ifndef FS_OFD_TEXTPAGE_H_
#define FS_OFD_TEXTPAGE_H_

#include "common/fs_common.h"

/**
 * @brief Foxit 命名空间。
 *
 * @details Foxit PDF SDK 的所有定义和类都在此命名空间内定义。
 */
namespace foxit {
/**
* @brief ofd 命名空间。
*/
namespace ofd {
class OFDPage;

/** 此类表示OFD文本页面字符信息。*/
class TextPageCharInfo FS_FINAL : public Object {
 public:
  /**
   * @brief 带参数的构造函数。
   *
   * @param[in] rect            字符的边界矩形。
   * @param[in] char_code       字符的Unicode编码。
   * @param[in] text_object_id  字符所属的文本对象ID。
   */
  explicit TextPageCharInfo(const foxit::RectF& rect, foxit::uint32 char_code, foxit::uint32 text_object_id) :
    rect(rect),
    char_code(char_code),
    text_object_id(text_object_id) {}

  /**
   * @brief 构造函数，通过另一个OFD文本页面字符信息对象。
   *
   * @param[in] other  另一个OFD文本页面字符信息对象。
   */
  TextPageCharInfo(const TextPageCharInfo& other) {
    this->rect = other.rect;
    this->char_code = other.char_code;
    this->text_object_id = other.text_object_id;
  }

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other  另一个OFD文本页面字符信息对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  TextPageCharInfo& operator = (const TextPageCharInfo& other) {
    this->rect = other.rect;
    this->char_code = other.char_code;
    this->text_object_id = other.text_object_id;
    return *this;
  }

  /**
   * @brief 设置值。
   *
   * @param[in] rect            字符的边界矩形。
   * @param[in] char_code       字符的Unicode编码。
   * @param[in] text_object_id  字符所属的文本对象ID。
   *
   * @return 无。
   */
  void Set(const foxit::RectF& rect, foxit::uint32 char_code, foxit::uint32 text_object_id) {
    this->rect = rect;
    this->char_code = char_code;
    this->text_object_id = text_object_id;
  }

  /**
   * @brief 字符的边界矩形。
   */
  foxit::RectF rect;

  /**
   * @brief 字符的Unicode编码。
   */
  foxit::uint32 char_code;

  /**
   * @brief 字符所属的文本对象ID。
   */
  foxit::uint32 text_object_id;
};

/** 此类表示和OFD文本页面相关的方法。*/
class TextPage FS_FINAL : public Base {
 public:
  /**
   * @brief 带参数的构造函数。
   *
   * @param[in] page  页面对象。
   */
  explicit TextPage(OFDPage page);

  /** @brief 析构函数。 */
  ~TextPage();

  /**
   * @brief 构造函数，通过另一个OFD文本页面对象。
   *
   * @param[in] other  另一个OFD文本页面对象。
   */
  TextPage(const TextPage& other);

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other  另一个OFD文本页面对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  TextPage& operator = (const TextPage& other);

  /**
   * @brief 相等操作符。
   *
   * @param[in] other  另一个OFD文本页面对象。此函数将检查当前对象是否等于这个对象。
   *
   * @return <b>true</b> 表示相等，<b>false</b> 表示不相等。
   */
  bool operator == (const TextPage& other) const;

  /**
   * @brief 不相等操作符。
   *
   * @param[in] other  另一个OFD文本页面对象。此函数将检查当前对象是否不等于这个对象。
   *
   * @return <b>true</b> 表示不相等，<b>false</b> 表示相等。
   */
  bool operator != (const TextPage& other) const;

  /**
   * @brief 检查当前对象是否为空。
   *
   * @details 当前对象为空时，表示当前对象是无用的。
   *
   * @return <b>true</b> 表示当前对象为空，<b>false</b> 表示不为空。
   */
  bool IsEmpty() const;

  /**
   * @brief 获取字符信息数量。
   *
   * @return 字符信息数量。
   */
  int GetCharInfoCount();

  /**
   * @brief 获取指定索引的字符信息。
   *
   * @param[in] index   字符信息索引号。有效范围：从0到(<i>count</i>-1)。
   *                    <i>count</i> 由函数 @link foxit::ofd::TextPage::GetCharInfoCount @endlink 返回。
   *
   * @return 指定索引的字符信息。
   */
  TextPageCharInfo GetCharInfo(int index);

  /**
   * @brief 获取指定位置的字符索引。
   *
   * @param[in] x_pos       字符的X坐标位置。
   * @param[in] y_pos       字符的Y坐标位置。
   * @param[in] tolerance   坐标容差值。
   *
   * @return 指定位置的字符索引，若未找到则返回-1。
   */
  int GetCharIndexAtPos(float x_pos, float y_pos, float tolerance);

  /**
   * @brief 获取文本内容。
   *
   * @param[in] start_index   文本内容的起始字符索引。有效范围：从0到(<i>count</i>-1)。
   *                          <i>count</i> 由函数 @link foxit::ofd::TextPage::GetCharInfoCount @endlink 返回。
   * @param[in] count         文本内容的字符数量。有效范围：从0到(<i>count</i>-<i>start_index</i>)。
   *                          <i>count</i> 由函数 @link foxit::ofd::TextPage::GetCharInfoCount @endlink 返回。
   *
   * @return 文本内容。
   */
  String GetText(int start_index, int count);

  /**
   * @brief 将文本内容导出到文件中。
   *
   * @param[in] file_path       导出文本内容的文件路径。
   *
   * @return <b>true</b>表示导出成功，<b>false</b>表示导出失败。
   */
  bool ExportToFile(const String& file_path);

  /**
   * @brief 将文本内容导出到文件中。
   *
   * @param[in] file_path       导出文本内容的文件路径。
   *
   * @return <b>true</b>表示导出成功，<b>false</b>表示导出失败。
   */
  bool ExportToFile(const WString& file_path);

  /**
   * @brief 将文本内容导出到文件中。
   *
   * @param[in] file_writer     用户实现的 @link common::file::WriterCallback @endlink 对象，用于保存文本内容。
   *
   * @return <b>true</b>表示导出成功，<b>false</b>表示导出失败。
   */
  bool ExportToFile(foxit::common::file::WriterCallback* file_writer);

  explicit TextPage(FS_HANDLE handle);
};

/** 此类表示和OFD文本页面选择相关的方法。*/
class TextPageSelect FS_FINAL : public Base {
 public:
  /**
   * @brief OFD文本选择模式定义枚举类型。
   *
   * @details 该枚举值应单独使用。
   */
  typedef enum _TextSelectMode {
    /** @brief 模式类型：矩形选择。 */
    e_ModeRectBox   =  0,
    /** @brief 模式类型：段落选择。 */
    e_ModeParagraph  =  1
  } TextSelectMode;
  

  /**
   * @brief 带参数的构造函数。
   *
   * @param[in] page  页面对象。
   */
  explicit TextPageSelect(OFDPage page);

  /** @brief 析构函数。 */
  ~TextPageSelect();

  /**
   * @brief 构造函数，通过另一个OFD文本页面选择对象。
   *
   * @param[in] other  另一个OFD文本页面选择对象。
   */
  TextPageSelect(const TextPageSelect& other);

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other  另一个OFD文本页面选择对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  TextPageSelect& operator = (const TextPageSelect& other);

  /**
   * @brief 相等操作符。
   *
   * @param[in] other  另一个OFD文本页面选择对象。此函数将检查当前对象是否等于这个对象。
   *
   * @return <b>true</b> 表示相等，<b>false</b> 表示不相等。
   */
  bool operator == (const TextPageSelect& other) const;

  /**
   * @brief 不相等操作符。
   *
   * @param[in] other  另一个OFD文本页面选择对象。此函数将检查当前对象是否不等于这个对象。
   *
   * @return <b>true</b> 表示不相等，<b>false</b> 表示相等。
   */
  bool operator != (const TextPageSelect& other) const;

  /**
   * @brief 检查当前对象是否为空。
   *
   * @details 当前对象为空时，表示当前对象是无用的。
   *
   * @return <b>true</b> 表示当前对象为空，<b>false</b> 表示不为空。
   */
  bool IsEmpty() const;

  /**
   * @brief 获取文本ID数量。
   *
   * @return 文本ID数量。
   */
  int GetTextIDCount();

  /**
   * @brief 获取指定索引的文本ID。
   *
   * @param[in] index   文本ID索引号。有效范围：从0到(<i>count</i>-1)。
   *                    <i>count</i> 由函数 @link foxit::ofd::TextPageSelect::GetTextIDCount @endlink 返回。
   *
   * @return 指定索引的文本ID。
   */
  int GetTextID(int index);

  /**
   * @brief 获取文本内容。
   *
   * @return 文本内容。
   */
  String GetText();

  /**
   * @brief 获取矩形数量。
   *
   * @return 矩形数量。
   */
  int GetRectCount();

  /**
   * @brief 获取指定索引的矩形。
   *
   * @param[in] index   矩形索引号。有效范围：从0到(<i>count</i>-1)。
   *                    <i>count</i> 由函数 @link foxit::ofd::TextPageSelect::GetRectCount @endlink 返回。
   *
   * @return 指定索引的矩形。
   */
  foxit::RectF GetRect(int index);

  /**
   * @brief 设置选择模式。
   *
   * @param[in] mode          选择模式。请参考从 @link foxit::ofd::TextPageSelect::e_ModeRectBox @endlink 开始的值，
   *                          应该是这些值中的一个。
   *
   * @return 无。
   */
  void SetMode(TextSelectMode mode);

  /**
   * @brief 设置选择范围。
   *
   * @param[in] start_point     选择起始点。
   * @param[in] end_point       选择结束点。
   *
   * @return 无。
   */
  void SetRange(foxit::PointF start_point, foxit::PointF end_point);

  explicit TextPageSelect(FS_HANDLE handle);
};

}  // namespace ofd
}  // namespace foxit

#endif  // FS_OFD_TEXTPAGE_H_
