#import <Foundation/Foundation.h>

#import "VideoWorker.h"
#import "Recognizer.h"
#import "Capturer.h"
#import "Context.h"
#import "ContextTemplate.h"
#import "DynamicTemplateIndex.h"
#import "ProcessingBlock.h"

/**
	@defgroup SwiftAPI
	@{
*/

/**
	\~English \brief State of the counter assigned to a specified license element.
	\~Russian \brief Статус счетчика, назначенного определенному элементу лицензии.
*/
@interface CounterState : NSObject
{

	NSString *name;
	int value;
	int max_value;
}

/**
	\~English \brief Element name (equals to the tag name).
	\~Russian \brief Имя элемента (совпадает с именем тэга).
*/
@property (nonnull) NSString *name;

/**
		\~English \brief Current value (number of used elements).
		\~Russian \brief Текущее значение (количество используемых элементов).
	*/
@property int value;

/**
		\~English \brief Maximum counter value (equals to the tag value).
		\~Russian \brief Максимальное значение счетчика (совпадает со значением тэга).
	*/
@property int max_value;
@end

/** \~English
	\brief License status.
	\~Russian
	\brief Статус лицензии.
*/
@interface LicenseState : NSObject
{
    bool online;
    NSString *android_app_id;
    NSString *android_serial;
    NSString *ios_app_id;
    NSString *hardware_reg;
    
    NSMutableArray *counters;
}

/**
	\~English \brief Online license flag.
	\~Russian \brief Флаг онлайн-лицензии.
*/
@property bool online;

/**
	\~English \brief Android application ID. Available only on Android (tag <android_app_id>).
	\~Russian \brief ID Android приложения. Доступен только на Android (тэг <android_app_id>).
*/
@property (nonnull) NSString *android_app_id;

/**
	\~English \brief Serial number of the Android device. Only available on Android (tag <android_serial>).
	\~Russian \brief Серийный номер Android-устройства. Доступен только на Android (тэг <android_serial>).
*/
@property (nonnull) NSString *android_serial;

/**
	\~English \brief iOS application ID. Available only on iOS (tag <ios_app_id>).
	\~Russian \brief ID iOS приложения. Доступен только на iOS (тэг <ios_app_id>).
*/
@property (nonnull) NSString *ios_app_id;

/**
	\~English \brief Hardware signature (tag <Reg>).
	\~Russian \brief Ключ оборудования (тэг <Reg>).
*/
@property (nonnull) NSString *hardware_reg;

/**
	\~English \brief State of all license counters.
	\~Russian \brief Статус всех счетчиков лицензии.
*/
@property (nonnull) NSMutableArray *counters;
@property (nonatomic, nonnull) NSString *ios;

@end

/** \~English
	\brief A class used to override the configuration parameters at runtime.
	\~Russian
	\brief Класс для переопределения параметров конфигурации во время выполнения.
*/
@interface Config : NSObject{
    void *config;
    const char* file_path;
}
-(nonnull instancetype) init: (const char*_Nonnull) path;
-(void) dealloc;

/**
	\~English
	\brief
		Override the parameter value.

	\param[in] parameter
		Parameter name (a tag name from the .xml config file).

	\param[in] value
		New parameter value.

	\return
		*this

	\~Russian
	\brief
		Переопределить значение параметра.

	\param[in] parameter
		Имя параметра (имя тэга из .xml конфигурационного файла).

	\param[in] value
		Новое значение параметра.

	\return
		*this
*/
-(nonnull instancetype) overrideParameter: (const char*_Nonnull) parametr : (const double) value;
@property (readonly) void* _Nonnull config;
@end

/** \~English
	\brief Parameters of the VideoWorker constructor.
	\~Russian
	\brief Параметры конструктора VideoWorker.
*/
@interface Params : NSObject{

    Config *video_worker_config;
    Config *recognizer_config;
    int streams_count;
    int processing_threads_count;
    int matching_threads_count;
    int age_gender_estimation_threads_count;
    int emotions_estimation_threads_count;
    NSMutableArray* active_liveness_checks_order;
}
-(nonnull instancetype) init;

/**
	\~English \brief Set the VideoWorker configuration file with optionally overridden parameters. \return *this
	\~Russian \brief Задать конфигурационный файл VideoWorker с опционально переопределенными параметрами. \return *this
*/
@property (nonnull) Config *video_worker_config;

/**
	\~English \brief Set the Recognizer configuration file with optionally overridden parameters. \return *this
	\~Russian \brief Задать конфигурационный файл Recognizer с опционально переопределенными параметрами. \return *this
*/
@property (nonnull) Config *recognizer_config;

/**
	\~English \brief Set the number of video streams. \return *this
	\~Russian \brief Задать количество видеопотоков. \return *this
*/
@property int streams_count;

/**
	\~English \brief Set the number of threads for creating templates. \return *this
	\~Russian \brief Задать количество потоков для создания шаблонов. \return *this
*/
@property int processing_threads_count;

/**
	\~English \brief Set the number of threads for matching templates with the database. \return *this
	\~Russian \brief Задать количество потоков для сравнения шаблонов, созданных из видеопотоков, с базой. \return *this
*/
@property int matching_threads_count;

/**
	\~English \brief Set the number of threads for age_gender estimation. \return *this
	\~Russian \brief Задать количество потоков для определения пола и возраста. \return *this
*/
@property int age_gender_estimation_threads_count;

/**
	\~English \brief Set the number of threads for estimation of emotions. \return *this
	\~Russian \brief Задать количество потоков для определения эмоций. \return *this
*/
@property int emotions_estimation_threads_count;

/**
	\~English \brief Set the order for checking the active liveness
	\~Russian \brief Задать порядок для проверки активаного (сценарного) liveness
*/
@property NSMutableArray* _Nullable active_liveness_checks_order;

@property (readonly, nonnull) void* params;
@end


/** \~English
	\brief Interface object for creating other interface objects.
	\~Russian
	\brief Интерфейсный объект для создания других интерфейсных объектов.
*/
@interface FacerecService : NSObject
{
	void *service;
}

-(nonnull instancetype)init;
-(nonnull instancetype)init: (const char*_Nonnull) lib_path : (const char*_Nonnull) conf_path : (const char*_Nonnull) license_path;

-(void) dealloc;

/**
	\~English
	\brief
		Get version of face recognition library. Thread-safe.
	\return
		The version of face recognition library.
 */
-(nonnull NSString *) getVersion;

/**
	\~English
	\brief
		Creates a Recognizer object.
		Thread-safe.

	\param[in]  config
		The Recognizer configuration file with optionally overridden parameters.

	\param[in]  processing
		Flag to toggle the Recognizer::processing method in the created recognizer.

	\param[in]  matching
		Flag to toggle the Recognizer::verifyMatch method in the created recognizer.

	\param[in]  processing_less_memory_consumption
		Flag to toggle the Recognizer::processing member
		function optimizations that consume a lot of RAM when creating the recognizer (see the docs).

	\return
		Created Recognizer object.

	\~Russian
	\brief
		Создать объект Recognizer.
		Потокобезопасный.

	\param[in]  config
		Конфигурационный файл Recognizer с опционально переопределенными параметрами.

	\param[in]  processing
		Флаг для включения / выключения метода Recognizer::processing в создаваемом разпознавателе.

	\param[in]  matching
		Флаг для включения / выключения метода Recognizer::verifyMatch в создаваемом разпознавателе.

	\param[in]  processing_less_memory_consumption
		Флаг для выключения оптимизаций метода Recognizer::processing,
		потребляющих много оперативной памяти при создании распознавателя (см. документацию).

	\return
		Созданный объект Recognizer.
*/
-(nonnull Recognizer *) createRecognizer: (Config* _Nonnull) config : (const bool) processing : (const bool) matching : (const bool)processing_less_memory_consumption;

/**
	\~English
	\brief
	\param[in]  video_worker_config
		The VideoWorker configuration file with optionally overridden parameters.

	\param[in]  recognizer_ini_file
		Name of the config file for the Recognizer that will be used inside the VideoWorker.

	\param[in]  streams_count
		Number of video streams.

	\param[in]  processing_threads_count
		Number of threads for creating templates.

	\param[in]  matching_threads_count
		Number of threads for matching templates with the database.

	\return
		Created VideoWorker object.

	\~Russian
	\brief
	\param[in]  video_worker_config
		Конфигурационный файл VideoWorker с опционально переопределенными параметрами.

	\param[in]  recognizer_ini_file
		Имя конфигурационного файла для используемого распознавателя (Recognizer).

	\param[in]  streams_count
		Количество видеопотоков.

	\param[in]  processing_threads_count
		Количество потоков для создания шаблонов.

	\param[in]  matching_threads_count
		Количество потоков для сравнения шаблонов, созданных из видеопотоков, с базой.

	\return
		Созданный объект VideoWorker.
*/
-(nonnull VideoWorker *) createVideoWorker: (Config* _Nonnull) config : (const char * _Nonnull) recognizer_ini_file : (const int) streams_count : (const int) processing_threads_count : (const int) matching_threads_count;

/**
	\~English
	\brief
		Creates a VideoWorker object.
		Thread-safe.<br>
		When VideoWorker is created with <i>matching_thread=0</i> and <i>processing_thread=0</i>,
		then the standard Capturer license is used. <br>Depending on the settings, VideoWorker uses either the
		<i>VideoClient</i> license (face tracking on video streams) or the <i>VideoClientExt</i> license (face tracking, template
		creation and matching with the database).

	\param[in]  params
		Parameters of the VideoWorker constructor.

	\return
		Created VideoWorker object.

	\~Russian
	\brief
		Создать объект VideoWorker.
		Потокобезопасный.<br>
		Если при создании VideoWorker указаны параметры <i>matching_thread=0</i> и
		<i>processing_thread=0</i>, то потребляется обычная лицензия Capturer. <br>В зависимости от настроек,
		VideoWorker потребляет лицензию <i>VideoClient</i> (детекция лиц на видеопотоках)
		либо <i>VideoClientExt</i> (детекция лиц на видеопотоках, создание шаблонов и сравнение с базой).

	\param[in]  params
		Параметры конструктора VideoWorker.

	\return
		Созданный объект VideoWorker.
*/
-(nonnull VideoWorker *) createVideoWorker: (Params *_Nonnull)params;

/**
	\~English
	\brief
		Creates a Capturer object.
		Type and features depend on the content of the configuration file.
		Thread-safe.

	\param[in]  config
		Сonfiguration file with optionally overridden parameters.

	\return
		Created Capturer object.

	\~Russian
	\brief
		Создать объект Capturer.
		Тип и возможности зависят от указанного конфигурационного файла.
		Потокобезопасный.

	\param[in]  config
		Конфигурационный файл с опционально переопределенными параметрами.

	\return
		Созданный объект Capturer.
*/
-(nonnull Capturer *) createCapturer: (Config* _Nonnull) config;

/**
	\~English
		\brief creates a container-Context
		\return container-Context
	\~Russian
		\brief создаёт контейнер-Context
		\return контейнер-Context
*/
-(nonnull Context *) createContext;

/**
	\~English
		\brief creates a container-Context from an encoded image
		\param[in] data - pointer to data
		\param[in] dataSize - the size of the data
		\return container-Context
	\~Russian
		\brief создаёт контейнер-Context из закодированного изображения
		\param[in] data - указатель на данные
		\param[in] dataSize - размер данных
		\return контейнер-Context
*/
-(nonnull Context *) createContextFromEncodedImage: (uint8_t* _Nonnull) data : (uint64_t) dataSize;

/**
	\~English
		\brief creates a container-Context from an image
		\param[in] data - image bytes
		\param[in] width - the width of the image in pixels
		\param[in] height - the height of the image in pixels
		\param[in] format - image format
		\param[in] base_angle - the type of angle the purpose of which the image is expanded
		\return container-Context
	\~Russian
		\brief создаёт контейнер-Context из изображения
		\param[in] data - байты изображения
		\param[in] width - ширина изображения в пикселях
		\param[in] height - высота изображения в пикселях
		\param[in] format - формат изображения
		\param[in] base_angle - тип угла на значение которого развёрнуто изображение
		\return контейнер-Context
*/
-(nonnull Context *) createContextFromFrame: (uint8_t* _Nonnull) data : (int) width : (int) height : (int) format : (int) baseAngle;

/**
	\~English
		\brief creates a container-Context from an CMSampleBuffer
		\param[in] sampleBuffer
		\return container-Context
	\~Russian
		\brief создаёт контейнер-Context из CMSampleBuffer
		\param[in] sampleBuffer
		\return контейнер-Context
*/
-(nonnull Context *) createContextCMSampleBuffer: (CMSampleBufferRef _Nullable)sampleBuffer  : (int) format;

/**
	\~English
		\brief creates a processing block
		\param[in] config - container-Context containing the configuration of the processing block
		\return processing block
	\~Russian
		\brief создаёт процессинг блок
		\param[in] config - контейнер-Context содержащий конфигурацию процессинг-блока
		\return процессинг-блок
*/


-(nonnull DynamicTemplateIndex*) createDynamicTemplateIndex: (Context* _Nonnull) config;

-(nonnull ContextTemplate*) loadContextTemplate: (NSInputStream* _Nonnull) stream;

-(nonnull ProcessingBlock*) createProcessingBlock: (Context* _Nonnull) config;

/**
    \~English
    \brief
        Get the license state. Thread-safe.
    \return
        License state.
 */
-(nonnull LicenseState *) getLicenseState;
@end


/** @} */