#ifndef LIBMEGAPIXELS_HEADER
#define LIBMEGAPIXELS_HEADER

#include <stdint.h>
#include <linux/videodev2.h>
#include <stdio.h>

#define EXPORT __attribute__((__visibility__("default")))


EXPORT int
libmegapixels_find_config(ssize_t maxlen, char *configfile);

EXPORT int
libmegapixels_find_config_verbose(ssize_t maxlen, char *configfile, int print);

#define LIBMEGAPIXELS_CMD_LINK 1
#define LIBMEGAPIXELS_CMD_MODE 2
#define LIBMEGAPIXELS_CMD_CROP 3
#define LIBMEGAPIXELS_CMD_INTERVAL 4

#define LIBMEGAPIXELS_CFA_NONE 0
#define LIBMEGAPIXELS_CFA_BGGR 1
#define LIBMEGAPIXELS_CFA_GBRG 2
#define LIBMEGAPIXELS_CFA_GRBG 3
#define LIBMEGAPIXELS_CFA_RGGB 4

#define LIBMEGAPIXELS_XFER_RAW 0
#define LIBMEGAPIXELS_XFER_SRGB 8

#define LIBMEGAPIXELS_FLASH_SCREEN 0
#define LIBMEGAPIXELS_FLASH_V4L 1
#define LIBMEGAPIXELS_FLASH_LED 2

struct _lmp_cmd {
		int type;
		const char *entity_from;
		const char *entity_to;
		int pad_from;
		int pad_to;
		int width;
		int height;
		int top;
		int left;
		int format;
		int rate;

		uint32_t entity_from_id;
		int pad_from_id;
		uint32_t entity_to_id;
		int pad_to_id;
		int skip_try;
		int exact_name;
};
typedef struct _lmp_cmd libmegapixels_cmd;

struct _lmp_mode {
		int width;
		int height;
		int rate;
		int format;
		int rotation;
		int mirrored;
		int xfer;
		double focal_length;
		double f_number;

		uint32_t v4l_pixfmt;
		uint32_t media_busfmt;

		int num_cmds;
		libmegapixels_cmd **cmds;
};
typedef struct _lmp_mode libmegapixels_mode;

struct _lmp_subdev {
		char *path;
		int fd;
		uint32_t entity_id;
};
typedef struct _lmp_subdev libmegapixels_subdev;

struct _lmp_camera {
		int index;
		char *name;
		char *sensor_name;
		char *bridge_name;

		char *media_path;
		char *sensor_path;
		char *video_path;
		char *flash_path;
		char *lens_path;
		int flash_type;
		int media_fd;
		int sensor_fd;
		int video_fd;
		int flash_fd;
		int lens_fd;

		int num_modes;
		libmegapixels_mode **modes;
		libmegapixels_mode *current_mode;

		int num_handles;
		libmegapixels_subdev **handles;
};
typedef struct _lmp_camera libmegapixels_camera;

struct _lmp_device_config {
		char *path;
		const char *make;
		const char *model;
		int count;
		int loaded_config;
		int loaded_uvc;
		libmegapixels_camera **cameras;
};
typedef struct _lmp_device_config libmegapixels_devconfig;


typedef struct _lmp_aaa {
		float matrix1[9];
		float matrix2[9];
		float avg_r;
		float avg_g;
		float avg_b;
		int exposure;
		float temp;
		float tint;
		int focus;
		int blacklevel;
} libmegapixels_aaa_stats;

EXPORT int
libmegapixels_init(libmegapixels_devconfig **config);

EXPORT void
libmegapixels_loglevel(int loglevel);

EXPORT int
libmegapixels_load_file(libmegapixels_devconfig *config, const char *file);

EXPORT int
libmegapixels_load_file_lint(libmegapixels_devconfig *config, const char *file, int linting);

EXPORT int
libmegapixels_load_uvc(libmegapixels_devconfig *config);

EXPORT int
libmegapixels_open(libmegapixels_camera *camera);

EXPORT void
libmegapixels_close(libmegapixels_camera *camera);

EXPORT unsigned int
libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode, struct v4l2_format *format);

EXPORT char *
libmegapixels_v4l_pixfmt_to_string(uint32_t pixfmt);

EXPORT char *
libmegapixels_format_name(int format);

EXPORT const char *
libmegapixels_format_cfa(int format);

EXPORT const char *
libmegapixels_format_cfa_pattern(int format);

EXPORT uint32_t
libmegapixels_mode_raw_width_to_width(int index, uint32_t width);

EXPORT uint32_t
libmegapixels_mode_width_to_padding(int index, uint32_t width);

EXPORT uint32_t
libmegapixels_mode_width_to_bytes(int index, uint32_t width);

EXPORT uint32_t
libmegapixels_format_to_v4l_pixfmt(int index);

EXPORT uint32_t
libmegapixels_format_to_media_busfmt(int index);

EXPORT uint32_t
libmegapixels_format_bits_per_pixel(int format);

EXPORT int
libmegapixels_mode_equals(libmegapixels_mode *a, libmegapixels_mode *b);

EXPORT int
libmegapixels_v4l_pixfmt_to_index(uint32_t pixfmt);

EXPORT int
libmegapixels_mode_is_packed(int index);

// The AAA API is considered completely unstable and shouldn't be used yet

EXPORT void
libmegapixels_aaa_init(libmegapixels_aaa_stats *stats);

EXPORT void
libmegapixels_aaa_set_matrix(libmegapixels_aaa_stats *stats, const float matrix1[9], const float matrix2[9]);

EXPORT void
libmegapixels_aaa_software_statistics(libmegapixels_aaa_stats *stats, const unsigned int *frame, int width, int height);

EXPORT void
libmegapixels_flash_on(libmegapixels_camera *camera);

EXPORT void
libmegapixels_flash_off(libmegapixels_camera *camera);

#endif
