#ifndef FS_OFD_BOOKMARK_H_
#define FS_OFD_BOOKMARK_H_

#include "common/fs_common.h"

/**
 * @brief Foxit 命名空间。
 *
 * @details Foxit PDF SDK 的所有定义和类都在此命名空间内定义。
 */
namespace foxit {
/**
* @brief ofd 命名空间。
*/
namespace ofd {
/** 此类表示和OFD书签目标信息相关的属性。*/
class BookmarkDestinationInfo FS_FINAL : public Object {
 public:
  /**
   * @brief 带参数的构造函数。
   *
   * @param[in] page_index 目标页索引。正常跳转范围：从0到(<i>count - 1</i>)。
   *                       <i>count</i>由函数 @link foxit::ofd::OFDDoc::GetPageCount @endlink 返回。
   * @param[in] x_pos      目标页X坐标。
   * @param[in] y_pos      目标页Y坐标。
   */
  explicit BookmarkDestinationInfo(int page_index, float x_pos, float y_pos) :
    page_index(page_index),
    x_pos(x_pos),
    y_pos(y_pos) {}

  /**
   * @brief 构造函数，通过另一个书签目标信息对象。
   *
   * @param[in] other 另一个书签目标信息对象。
   */
  BookmarkDestinationInfo(const BookmarkDestinationInfo& other) {
    this->page_index = other.page_index;
    this->x_pos = other.x_pos;
    this->y_pos = other.y_pos;
  }

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other 另一个书签目标信息对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  BookmarkDestinationInfo& operator = (const BookmarkDestinationInfo& other) {
    this->page_index = other.page_index;
    this->x_pos = other.x_pos;
    this->y_pos = other.y_pos;
    return *this;
  }

  /**
   * @brief 设置值。
   *
   * @param[in] page_index 目标页索引。
   * @param[in] x_pos      目标页X坐标。
   * @param[in] y_pos      目标页Y坐标。
   *
   * @return 无。
   */
  void Set(int page_index, float x_pos, float y_pos) {
    this->page_index = page_index;
    this->x_pos = x_pos;
    this->y_pos = y_pos;
  }

  /**
   * @brief 目标页索引。
   *
   */
  int page_index;

  /**
   * @brief 目标页X坐标。
   *
   */
  float x_pos;

  /**
   * @brief 目标页Y坐标。
   *
   */
  float y_pos;
};

/** 此类表示OFD书签对象相关的操作。 */
class Bookmark FS_FINAL : public Base {
 public:
  /** @brief 析构函数。 */
  ~Bookmark();

  /**
   * @brief 构造函数，通过另一个书签对象。
   *
   * @param[in] other 另一个书签对象。
   */
  Bookmark(const Bookmark& other);

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

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

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

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

  /**
   * @brief 获取书签目标信息。
   *
   * @return 书签目标信息。详见 @link foxit::ofd::BookmarkDestinationInfo @endlink。
   */
  BookmarkDestinationInfo GetDest();

  /**
   * @brief 设置书签目标信息。
   *
   * @param[in] info  书签目标信息。详见 @link foxit::ofd::BookmarkDestinationInfo @endlink。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool SetDest(const BookmarkDestinationInfo& info);

  /**
   * @brief 获取名称。
   *
   * @return 名称。
   */
  String GetName();

  /**
   * @brief 设置名称。
   *
   * @param[in] name  名称。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool SetName(const String& name);

  explicit Bookmark(FS_HANDLE handle);
};

/** 此类表示和OFD书签集合相关的操作。 */
class Bookmarks FS_FINAL : public Base {
 public:
  /** @brief 析构函数。 */
  ~Bookmarks();

  /**
   * @brief 构造函数，通过另一个书签集合对象。
   *
   * @param[in] other 另一个书签集合对象。
   */
  Bookmarks(const Bookmarks& other);

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other 另一个书签集合对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  Bookmarks& operator = (const Bookmarks& other);

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

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

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

  /**
   * @brief 获取书签数量。
   *
   * @return 书签数量。
   */
  int GetBookmarkCount();

  /**
   * @brief 获取指定索引的书签对象。
   *
   * @param[in] index 指定的书签索引，有效范围：从0到(<i>count - 1</i>)。
   *                  <i>count</i>由函数 @link foxit::ofd::Bookmarks::GetBookmarkCount @endlink 返回。
   *
   * @return 指定索引的书签对象。
   */
  Bookmark GetBookmark(int index);

  /**
   * @brief 添加书签对象。
   *
   * @return 新添加的书签对象。
   */
  Bookmark AddBookmark();

  /**
   * @brief 删除书签对象。
   *
   * @param[in] index 指定的书签索引，有效范围：从0到(<i>count</i>)。
   *                  <i>count</i>由函数 @link Bookmarks::GetBookmarkCount @endlink 返回。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool RemoveBookmark(int index);

  explicit Bookmarks(FS_HANDLE handle);
};

}  // namespace ofd
}  // namespace foxit

#endif  // FS_OFD_BOOKMARK_H_
