/**
 * Copyright (C) 2003-2026, Foxit Software Inc..
 * All Rights Reserved.
 *
 * http://www.foxitsoftware.com
 *
 * The following code is copyrighted and is the proprietary of Foxit Software
 * Inc.. It is not allowed to distribute any parts of Foxit PDF Conversion SDK to third
 * party or public without permission unless an agreement is signed between
 * Foxit Software Inc. and customers to explicitly grant customers permissions.
 *
 * @file fs_basictypes.h
 * @brief Header file for basic types definitions.
 */

#ifndef FS_BASIC_TYPES_H_
#define FS_BASIC_TYPES_H_

#include <cstddef>
#include <string>
#include <memory>
#include <vector>
#include <exception>
#include <cmath>
#include <cfloat>
#include <stdlib.h>
#include <string.h>
#include "fxcrt/fx_basic.h"

#if defined(_WIN32) || defined(_WIN64)
#include <Windows.h>
#endif  // defined(_WIN32) || defined(_WIN64)

#define FSDK_DEFINE_ARRAY(ArrayName, Type) \
class ArrayName : public CFX_Object { \
 public: \
  /** @brief Constructor. */\
  ArrayName(); \
  /** @brief Destructor. */\
  ~ArrayName(); \
  /**
   @brief Constructor, with another array object.
   @param[in] other  Another array object.
   */\
  ArrayName(const ArrayName& other); \
  /**
   @brief Assign operator.
   @param[in] other  Another array object, whose value will be assigned to current object.
   @return Reference to current object itself.
   */\
  ArrayName& operator = (const ArrayName& other); \
  /**
   @brief Get the size of elements in current array.
   @return The size.
   */\
  size_t GetSize() const; \
  /**
  @brief Retrieve a copy of the element at position specified by index in current array.
  @param[in] index  An index to specify which element is to be retrieved.
  @return A copy of an element.
  */\
  Type GetAt(size_t index) const; \
  /**
   @brief Retrieve a reference to the element at position specified by index in current array.
   @param[in] index  An index to specify which element is to be retrieved.
   @return Reference to an element.
   */\
  Type& operator[](size_t index) const; \
  /**
   @brief Add an element to the end of current array.
   @param[in] element  New element to be added to current array.
   @return None.
   */\
  void Add(const Type& element); \
  /**
   @brief Remove the element in position specified by index.
   @param[in] index  An index to specify which element is to be removed. Valid range: from 0 to (<i>size</i>-1).
                     <i>size</i> is the size of elements in current array.
   @return None.
   */\
  void RemoveAt(size_t index); \
  /**
   @brief Insert an element before the position specified by index.
   @param[in] index    An index to specify where to insert the new element. Valid range: from 0 to (<i>size</i>-1).
                       <i>size</i> is the size of elements in current array.
   @param[in] element  New element to be inserted to current array.
   @return None.
   */\
  void InsertAt(size_t index, const Type& element); \
  /**
   @brief Remove all the element from current array.
   @return None.
   */\
  void RemoveAll(); \
     \
 private: \
  void* data_; \
};

namespace std {
class exception;
}

#ifndef TRUE
/** @brief Keyword used as value of type boolean. Value equals to 1. */
#define TRUE true
#endif

#ifndef FALSE
/** @brief Keyword used as value of type boolean. Value equals to 0. */
#define FALSE false
#endif

#ifndef NULL
/** @brief Keyword used as null-pointer value. */
#define NULL ((void*)0)
#endif

/**
 * @brief Foxit namespace.
 *
 * @details All the definitions and classes of Foxit PDF Conversion SDK are defined within this namespace.
 */
namespace foxit {
/** @brief Signed 64-bit integer. */
typedef FX_INT64        int64;
/** @brief Unsigned 64-bit integer. */
typedef FX_UINT64       uint64;
/** @brief 32-bit signed integer. */
typedef FX_INT32        int32;
/** @brief 32-bit unsigned integer. */
typedef FX_UINT32       uint32;
/** @brief 16-bit signed integer. */
typedef FX_INT16        int16;
/** @brief 16-bit unsigned integer. */
typedef FX_UINT16       uint16;
/** @brief 8-bit signed integer. */
typedef FX_INT8         int8;
/** @brief 8-bit unsigned integer. */
typedef FX_UINT8        uint8;
/** @brief Handle type. */
typedef void* FS_HANDLE;

/** @brief Object type. */
typedef CFX_Object Object;
/** @brief Wide string. */
typedef CFX_WideString WString;
/** @brief Byte string. */
typedef CFX_ByteString String;

/** This class represents an array of WString objects. */
FSDK_DEFINE_ARRAY(WStringArray, WString)

namespace file {
/**
 * This class represents a callback object to do file reading.
 * All the pure virtual functions in this class are used as callback functions and should be implemented by user
 * to do file reading in a customized way.
 */
typedef IFX_FileRead ReaderCallback;
/**
 * This class represents a callback object to do file reading and writing.
 * All the pure virtual functions in this class are used as callback functions and should be implemented by user
 * to do file reading and writing in a customized way.
 */
typedef IFX_FileStream StreamCallback;
}

/**
 * @brief Enumeration for error code.
 *
 * @details Values of this enumeration should be used alone.
 */
typedef enum _ErrorCode {
  /** @brief Success, and no error occurs. */
  e_ErrSuccess = 0,
  /** @brief File cannot be found or could not be opened. */
  e_ErrFile = 1,
  /** @brief Format is invalid. For files, this may also mean that file is corrupted. */
  e_ErrFormat = 2,
  /**
   * @brief Invalid password. Usually, this error may occur when loading a PDF document with password.
   *       When meet this, user should load document again with correct password.
   */
  e_ErrPassword = 3,
  /** @brief Error handle. */
  e_ErrHandle = 4,
  /**
   * @brief Certificate error: PDF document is encrypted by digital certificate 
   *       but current user does not have the correct certificate.
   */
  e_ErrCertificate = 5,
  /** @brief Any unknown error occurs. */
  e_ErrUnknown = 6,
  /** @brief Invalid license is used to initialize Foxit PDF Conversion SDK library. */
  e_ErrInvalidLicense = 7,
  /** @brief Parameter error: value of any input parameter for a function is invalid.*/
  e_ErrParam = 8,
  /** @brief Some types are not supported.*/
  e_ErrUnsupported = 9,
  /** @brief Out-of-memory error occurs.*/
  e_ErrOutOfMemory = 10,
  /** @brief PDF document is encrypted by some unsupported security handler. */
  e_ErrSecurityHandler = 11,
  /** @brief Content has not been parsed yet. Usually, this represents PDF page has not been parsed yet. */
  e_ErrNotParsed = 12,
  /** @brief Expected data or object is not found. */
  e_ErrNotFound = 13,
  /** @brief The type of input object or current object is invalid. */
  e_ErrInvalidType = 14,
  /** @brief Any unknown state occurs. */
  e_ErrUnknownState = 16,
  /**
   * @brief Data is not ready. Usually this is used as an exception error code
   *       when loading document in asynchronous way.
   */
  e_ErrDataNotReady = 17,
  /** @brief Current object has not been loaded yet.*/
  e_ErrNotLoaded = 20,
  /** @brief No "PDF2Office" module right. */
  e_ErrNoPDF2OfficeModuleRight = 77,
  /** @brief No "Office2PDF" module right. */
  e_ErrNoOffice2PDFModuleRight = 78,
  /** @brief No document permission to operate. */
  e_ErrNoDocumentPermission = 80,
  /** @brief Not match font . */
  e_ErrNotMatchFont = 82
} ErrorCode;


/** The base class in Foxit PDF Conversion SDK. */
class Base : public Object {
 public:
  /**
   * @brief Get the handle of current object.
   *
   * @return The handle.
   */
  FS_HANDLE Handle() const {
    return handle_;
  }
  virtual ~Base(){}

 protected:
  explicit Base(FS_HANDLE handle = NULL) : handle_(handle) {}
  FS_HANDLE handle_;
};
  
/** This class represents the Foxit PDF Conversion SDK exception. */
class Exception : public std::exception , public Object {
 public:
  /**
   * @brief Constructor, with parameters.
   *
   * @param[in] file_name      The name of the file, where the exception occurs.
   * @param[in] line_number    The number of line, where the exception occurs.
   * @param[in] function_name  The name of function, where the exception occurs.
   * @param[in] error_code     The error code value, which represents the meaning of current exception.
   *                           Please refer to values starting from @link foxit::e_ErrSuccess @endlink and
   *                           this should be one of these values.
   */
  Exception(const char* file_name, int line_number, const char* function_name, ErrorCode error_code);

  /**
   * @brief Constructor, with another exception object.
   *
   * @param[in] exception  Another exception object.
   */
  Exception(const Exception& exception)
      : error_code_(exception.error_code_)
      , error_message_(exception.error_message_)
      , name_(exception.name_) {}

  /**
   * @brief Assign operator.
   *
   * @param[in] exception  Another exception object, whose value would be assigned to current object.
   *
   * @return Reference to current object itself.
   */
  Exception& operator = (const Exception& exception) {
    error_code_ = exception.error_code_;
    error_message_ = exception.error_message_;
    return *this;
  }

  /** @brief Destructor. */
  ~Exception() throw() {}

  /**
   * @brief Get the error code.
   *
   * @return The error code.
   */
  ErrorCode GetErrCode() const {
    return error_code_;
  }

  /**
   * @brief Get the error message string.
   *
   * @return Error message string.
   */

  String GetMessage() const {
    return error_message_;
  }

  /**
   * @brief Get the string of error code.
   *
   * @return A string of error code.
   */
  String GetName() const
  { return name_; }

 private:
  ErrorCode error_code_;
  String error_message_;
  String name_;
};
  
#define throw(Exception)

#if __cpluscplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700)
#define FS_FINAL final
#else
#define FS_FINAL 
#endif

#if __cpluscplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
#define FS_OVERRIDE override
#else
#define FS_OVERRIDE 
#endif

}  // namespace foxit
#endif
