#ifndef FS_OFD_CUSTOMTAG_H_
#define FS_OFD_CUSTOMTAG_H_

#include "common/fs_common.h"

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

/** 此类表示和OFD自定义标签相关的操作。*/
class CustomTag FS_FINAL : public Base {
 public:
  /** @brief 析构函数。 */
  ~CustomTag();

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

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

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

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

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

  /**
   * @brief 获取类型。
   *
   * @return 类型。
   */
  String GetType();

  /**
   * @brief 设置类型。
   *
   * @param[in] type  类型。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool SetType(const String& type);

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

  /**
   * @brief 通过文件设置内容。
   *
   * @param[in] file  指定的文件路径。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool SetFile(const String& file);

  explicit CustomTag(FS_HANDLE handle);
};

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

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

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

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

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

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

  /**
   * @brief 获取自定义标签的数量。
   *
   * @return 自定义标签的数量。
   */
  int GetCustomTagCount();

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

  /**
   * @brief 添加一个自定义标签对象。
   *
   * @param[in] index 指定的自定义标签索引，有效范围：从0到(<i>count</i>)。
   *                  <i>count</i>由函数 @link foxit::ofd::CustomTags::GetCustomTagCount @endlink 返回。
   *
   * @return 自定义标签对象。
   */
  CustomTag AddCustomTag(int index);

  /**
   * @brief 通过XML缓冲区创建公文语义节点。
   *
   * @param[in] data      指向XML数据缓冲区的指针。
   * @param[in] data_len  XML数据缓冲区的长度，以字节为单位。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool CreateOfficeNodeByXmlBuffer(const void* data, size_t data_len);

  /**
   * @brief 通过XML文件创建公文语义节点。
   *
   * @param[in] file_path  指定的XML文件路径。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool CreateOfficeNodeByXmlFile(const String& file_path);

  /**
   * @brief 通过XML文件创建公文语义节点。
   *
   * @param[in] file_path  指定的XML文件路径。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool CreateOfficeNodeByXmlFile(const WString& file_path);

  /**
   * @brief 通过XML文件创建公文语义节点。
   *
   * @param[in] file_reader 用户实现的 @link foxit::common::file::ReaderCallback @endlink 对象，用于读取XML文件。
   *
   * @return <b>true</b> 表示成功，<b>false</b> 表示失败。
   */
  bool CreateOfficeNodeByXmlFile(foxit::common::file::ReaderCallback* file_reader);

  /**
   * @brief 创建一个空的公文语义节点。
   *
   * @return 公文语义节点对象。
   */
  OfficeNode CreateOfficeNode();

  /**
   * @brief 获取公文语义节点。
   *
   * @return 公文语义节点对象。
   */
  OfficeNode GetOfficeNode();

  /**
   * @brief 开始新的公文语义节点标标签。
   *
   * @param[in] tag_name  指定的标签名称。
   *
   * @return 无。
   */
  void BeginOfficeNode(const String& tag_name);

  /**
   * @brief 结束当前公文语义节点标标签。
   *
   * @param[in] tag_name  指定的标签名称。
   *
   * @return 无。
   */
  void EndOfficeNode(const String& tag_name);

  explicit CustomTags(FS_HANDLE handle);
};

}  // namespace ofd
}  // namespace foxit

#endif  // FS_OFD_CUSTOMTAG_H_
