#import <Foundation/Foundation.h>
#import "ContextTemplate.h"
#import "DynamicTemplateIndex.h"

/**
	@defgroup SwiftAPI
	@{
*/


/** \~English
	\brief Format of image data.
	\~Russian
	\brief Формат данных изображения.
*/
typedef  NS_ENUM(int32_t, CtxFormat){
	/** \~English
		\brief BGR, 24 bit per pixel, 8 bit per channel.
		\~Russian
		\brief BGR, 24 бита на пиксел, 8 бит на канал.
	*/
	CtxFORMAT_BGR = 0,

	/** \~English
		\brief RGB, 24 bit per pixel, 8 bit per channel.
		\~Russian
		\brief RGB, 24 бита на пиксел, 8 бит на канал.
	*/
	CtxFORMAT_RGB = 1,

	/** \~English
		\brief BGRA, 32 bit per pixel, 8 bit per channel.
		\~Russian
		\brief BGRA, 32 бита на пиксел, 8 бит на канал.
	*/
	CtxFORMAT_BGRA8888 = 2,

	/** \~English
		\brief YUV420 format in the YUV color coding system, the standard image format used on the Android camera preview.
		\~Russian
		\brief Формат YUV420 в цветовой системе кодирования YUV, стандартный формат изображений,  используемых в превью Android-камер.
	*/
	CtxFORMAT_YUV420 = 3,

	/** \~English
		\brief NV12 format in the YUV color coding system.
		\~Russian
		\brief Формат NV12 в цветовой системе кодирования YUV.
	*/
	CtxFORMAT_YUV_NV12 = 4,

	/** \~English
		\brief NV21 format in the YUV color coding system, the standard image format used on the Android camera preview.
		\~Russian
		\brief Формат NV21 в цветовой системе кодирования YUV, стандартный формат изображений,  используемых в превью Android-камер.
	*/
	CtxFORMAT_NV21 = 5,
};


/**
	\~English
	\brief Context is an interface object for storing data and interacting with methods from the Processing Block API.
	\~Russian
	\brief Context - интерфейсный объект для хранения данных и взаимодействия с методами из Processing Block API.
*/
@interface Context : NSObject
{
    void *_ptr;
}

@property (readonly) void* _Nonnull ptr;

-(nonnull instancetype) init: (void* _Nonnull) context;
-(void) dealloc;

/**
	\~English
		\brief adds a value of type long to the container
		\param[in] value - long value
	\~Russian
		\brief добавляет значение типа long в контейнер
		\param[in] value - значение типа long
*/
-(void) setLong: (int64_t) value;

/**
	\~English
		\brief adds a value of type double to the container
		\param[in] value - double value
	\~Russian
		\brief добавляет значение типа double в контейнер
		\param[in] value - значение типа double
*/
-(void) setDouble: (double) value;

/**
	\~English
		\brief adds a value of type bool to the container
		\param[in] value - bool value
	\~Russian
		\brief добавляет значение типа bool в контейнер
		\param[in] value - значение типа bool
*/
-(void) setBool: (bool) value;

/**
	\~English
		\brief adds a value of type std::string to the container
		\param[in] value - NSString value
	\~Russian
		\brief добавляет значение типа std::string в контейнер
		\param[in] value - значение типа NSString
*/
-(void) setString: (NSString *_Nonnull) value;

/**
	\~English
		\brief adds a pointer to the data in the container
		\param[in] value - pointer to data
		\param[in] copy_sz - the number of copied elements, if 0 is specified, then there will be no copying
	\~Russian
		\brief добавляет указатель на данные в контейнер
		\param[in] value - указатель на данные
		\param[in] copy_sz - количество копируемых элементов, если указан 0 то копирования не будет
*/
-(void) setDataPtr: (const uint8_t *_Nullable) value : (int) copy_sz;

/**
	\~English
		\brief adds a pointer to the data in the container
		\param[in] data - NSData value
	\~Russian
		\brief добавляет указатель на данные в контейнер
		\param[in] data - значение типа NSData
*/
-(void) setNSData: (NSData* _Nonnull) data;

/**
	\~English
		\brief adds another container Context
		\param[in] other - Context value
	\~Russian
		\brief добавляет другой контейнер-Контекст
		\param[in] other - значение типа Context
*/

-(void) setContextTemplate: (ContextTemplate* _Nonnull) value;
-(ContextTemplate* _Nonnull) getContextTemplate;
-(bool) isContextTemplate;

-(void) setDynamicTemplateIndex: (DynamicTemplateIndex* _Nonnull) value;
-(DynamicTemplateIndex* _Nonnull) getDynamicTemplateIndex;
-(bool) isDynamicTemplateIndex;

-(void) set: (Context* _Nonnull) other;

/**
	\~English
		\brief returns a long value from the container
		\return value
	\~Russian
		\brief возвращает значение типа long из контейнера
		\return значение
*/
-(int64_t) getLong;

/**
	\~English
		\brief returns a double value from the container
		\return value
	\~Russian
		\brief возвращает значение типа double из контейнера
		\return значение
*/
-(double) getDouble;

/**
	\~English
		\brief returns a bool value from the container
		\return value
	\~Russian
		\brief возвращает значение типа bool из контейнера
		\return значение
*/
-(bool) getBool;

/**
	\~English
		\brief returns a std::string value from the container
		\return value
	\~Russian
		\brief возвращает значение типа std::string из контейнера
		\return значение
*/
-(NSString *_Nonnull) getString;

/**
	\~English
		\brief returns a pointer to data from the container
		\return pointer to data
	\~Russian
		\brief возвращает указатель на данные из контейнера
		\return указатель на данные
*/
-(uint8_t* _Nonnull) getDataPtr;

/**
	\~English
		\brief returns a NSData
		\param[in] size - data buffer size
	\~Russian
		\brief возвращает NSData
		\param[in] size - размер буфера данных
*/
-(const NSData* _Nonnull) getNSData: (int64_t) size;

/**
	\~English
		\brief indexing by index.
		\param[in] index
	\~Russian
		\brief индексация по индексу.
		\param[in] index
*/
-(Context* _Nonnull) at: (int) index;

/**
	\~English
		\brief indexing by key.
		\param[in] key
	\~Russian
		\brief индексация по ключу.
		\param[in] key
*/
-(Context* _Nonnull) get: (NSString *_Nonnull) key;

/**
	\~English
		\brief Get the size of the container.
		\return the size of the container.
	\~Russian
		\brief Получить размер контейнера.
		\return размер контейнера.
*/
-(size_t) size;

/**
	\~English
		\brief checks the existence of an element by a specific key
		\param[in] key
		\return True if the element exists
	\~Russian
		\brief проверяет существование элемента по определённому ключу
		\param[in] key
		\return True если элемент существует
*/
-(bool) contains: (NSString *_Nonnull) key;

/**
	\~English
		\brief compares two Context objects
		\param[in] other - container-Context
		\return True if the objects are the same
	\~Russian
		\brief сравнивает два объекта Context
		\param[in] other - контейнер-Context
		\return True если объекты одинаковые
*/
-(bool) compare: (Context *_Nonnull)  other;

/**
	\~English
		\brief clears the contents of the container-Context.
	\~Russian
		\brief очищает содержимое контейнера-Context.
*/
-(void) clear;

/**
	\~English
		\brief deletes the contents of the container-Context stored by key.
		\param[in] key.
	\~Russian
		\brief удаляет содержимое контейнера-Context хранящиеся по ключу.
		\param[in] key.
*/
-(void) erase: (NSString *_Nonnull) key;

/**
	\~English
		\brief allocates memory for num elements in the array.
		\param[in] size - the size of the array.
	\~Russian
		\brief выделяет память под num элементов в массиве.
		\param[in] size - размер массива.
*/
-(void) reserve: (size_t) size;

/**
	\~English
		\brief saves the contents of the container to a json file
		\param[in] path - the path to the file
	\~Russian
		\brief сохраняет содержимое контейнера в json файл
		\param[in] path - путь до файла
*/
-(void) saveToJsonFile: (NSString *_Nonnull) path;


/**
	\~English
		\brief returns a list of keys in the container-Context
		\return key list
	\~Russian
		\brief возвращает список ключей в контейнере-Context
		\return список ключей
*/
-(nonnull NSMutableArray*) getKeys;

/**
	\~English
		\brief adds a object to the container.
		\param[in] value - container-Context
	\~Russian
		\brief добавляет объект в контейнер.
		\param[in] value - контейнер-Context
*/
-(void) pushBack: (Context *_Nonnull) value;

/**
	\~English
		\brief adds a object to the container.
		\param[in] value - container-Context
	\~Russian
		\brief добавляет объект в контейнер.
		\param[in] value - контейнер-Context
*/
-(void) pushBackLong: (int64_t) value;

/**
	\~English
		\brief adds a object to the container.
		\param[in] value - container-Context
	\~Russian
		\brief добавляет объект в контейнер.
		\param[in] value - контейнер-Context
*/
-(void) pushBackDouble: (double) value;

/**
	\~English
		\brief adds a object to the container.
		\param[in] value - container-Context
	\~Russian
		\brief добавляет объект в контейнер.
		\param[in] value - контейнер-Context
*/
-(void) pushBackBool: (bool) value;

/**
	\~English
		\brief adds a object to the container.
		\param[in] value - container-Context
	\~Russian
		\brief добавляет объект в контейнер.
		\param[in] value - контейнер-Context
*/
-(void) pushBackString: (NSString *_Nonnull) value;

/**
	\~English
		\brief checks if there are no elements in the container
		\return True if the container is empty
	\~Russian
		\brief проверяет нет ли в контейнере элементов
		\return True если контейнер пуст
*/
-(bool) isNone;

/**
	\~English
		\brief checks whether the container is an object
		\return True if the container is an object
	\~Russian
		\brief проверяет является ли контейнер объектом
		\return True если контейнер является объектом
*/
-(bool) isObject;

/**
	\~English
		\brief checks whether the container is an array
		\return True if the container is an array
	\~Russian
		\brief проверяет является ли контейнере массивом
		\return True если контейнер является массивом
*/
-(bool) isArray;

/**
	\~English
		\brief checks whether the container is a bool type value
		\return True if the container is a bool type value
	\~Russian
		\brief проверяет является ли контейнер значением типа bool
		\return True если контейнер является значением типа bool
*/
-(bool) isBool;

/**
	\~English
		\brief checks whether the container is a long type string
		\return True if the container is a string type value
	\~Russian
		\brief проверяет является ли контейнер значением типа string
		\return True если контейнер является значением типа string
*/
-(bool) isString;

/**
	\~English
		\brief checks whether the container is a long type double
		\return True if the container is a double type value
	\~Russian
		\brief проверяет является ли контейнер значением типа double
		\return True если контейнер является значением типа double
*/
-(bool) isDouble;

/**
	\~English
		\brief проверяет является ли контейнер значением типа long
		\return True если контейнер является значением типа long
	\~Russian
		\brief проверяет является ли контейнер значением типа long
		\return True если контейнер является значением типа long
*/
-(bool) isLong;

/**
	\~English
		\brief checks whether the container is a pointer to the data
		\return True if the container is a pointer to the data
	\~Russian
		\brief проверяет является ли контейнер указателем на данные
		\return True если контейнер является указателем на данные
*/
-(bool) isDataPtr;

@end

/** @} */
