#ifndef BMP_H
#define BMP_H

#include <stdint.h>

typedef struct bitmap_header {
	/* File Header */
	/* The header field used to identify the BMP and DIB file is 0x42 0x4D in hexadecimal, same as BM in ASCII. The following entries are possible:
	
	BM
	    Windows 3.1x, 95, NT, ... etc.
	BA
	    OS/2 struct bitmap array
	CI
	    OS/2 struct color icon
	CP
	    OS/2 const color pointer
	IC
	    OS/2 struct icon
	PT
	    OS/2 pointer */
	uint16_t padding_alignment; /* The compiler will pad structs automatically to ensure the struct is byte aligned. (i.e 54 bytes to 56). We declare padding allignment ourselves and we will make sure to account for this. */
	uint8_t header_field[2];
	uint32_t file_size_bytes;
	uint16_t reserved1;
	uint16_t reserved2;
	uint32_t image_data_start_offset;		
	
	/* Bitmap Info Header */
	uint32_t info_header_size_bytes;
	int32_t image_width;
	int32_t image_height;
	uint16_t color_planes_used;
	uint16_t bits_per_pixel;
	uint32_t compression_method; 
	uint32_t image_size; 
	int32_t horizontal_resolution_pixels_per_metre;
	int32_t vertical_resolution_pixels_per_metre;
	uint32_t colors_in_palette;
	uint32_t important_colors; 
} bitmap_header;

typedef struct bitmap_file {
	char *filename;
	bitmap_header *bitmap_metadata;
	uint8_t fd;
} bitmap_file;

typedef struct bitmap_pixel_color {
	uint8_t blue;
	uint8_t green;
	uint8_t red;
} bitmap_pixel_color;

/* Initialises and writes a new bitmap file with correctly set headers and a blank pixel array. Returns a bitmap_header struct containing all bitmap header info. */
bitmap_header init_bitmap_header(const int32_t image_width_in, const int32_t image_height_in);
/* Initialises and returns a new bitmap_file struct which contains a str pointer to the filename, the bitmap header metadata and an open file descriptor */ 
bitmap_file init_bitmap_file(const bitmap_header *bitmap_in, const char *filename);

/* Calculate byte position a particular row starts */
uint32_t calc_bitmap_row_byte_position_start(const bitmap_header *bitmap_in, const uint32_t row_in);
/* Calculate full size of the bitmap */
uint32_t calc_bitmap_file_size_bytes(const bitmap_header *bitmap_in);
/* Calculate size of bitmap pixel array only */
uint32_t calc_bitmap_pixel_array_size_bytes(const bitmap_header *bitmap_in);
/* Calculate size of bitmap header only */
uint32_t calc_bitmap_header_size_bytes();

/* Write bitmap pixel at particular coordinate */
int write_bitmap_pixel(const bitmap_file *bitmap_file_in, const bitmap_pixel_color *bitmap_pixel_in, const int32_t x_in, const int32_t y_in); 

#endif
