#ifndef __NLL_IMAGE_H_INCLUDED__
#define __NLL_IMAGE_H_INCLUDED__

typedef unsigned int image_draw_count_t;

typedef enum {
  IMAGE_TYPE_NONE = -1,

  /* the index of image_procs[] */
  IMAGE_TYPE_FULLCOLOR = 0,
  IMAGE_TYPE_MONOCOLOR,
  IMAGE_TYPE_MONOBCOLOR,
  IMAGE_TYPE_ROUGHCOLOR,
  IMAGE_TYPE_GRAYCOLOR,
  IMAGE_TYPE_HALFCOLOR,
} image_type_t;

typedef enum {
  IMAGE_STATUS_NONE = 0,
  IMAGE_STATUS_ACTIVE,
  IMAGE_STATUS_FREE,
} image_status_t;

typedef struct image *image_t;

struct image_procs {
  int bytesize;
  int (*index)(image_t image, int width, int x, int y, int *indexp, int *offsetp);
  int (*get_color)(image_t image, int x, int y);
  int (*set_color)(image_t image, int x, int y, int color, unsigned int flags);
  int (*copy_get_color)(image_t image, int x, int y);
  int (*copy_save)(image_t image, int x, int y, int width, int height);
  int (*copy_save_color)(image_t image, int x, int y);
};

union image_bitmap {
  void *p;
  int *word;
  unsigned char *byte;
  unsigned short *half;
};

struct image {
  int index;
  int width;
  int height;
  int size;
  image_type_t type;
  unsigned int flags;
  struct {
    int fg;
    int bg;
    int from;
    int to;
  } color;
  struct {
    int x;
    int y;
    int width;
    int height;
    int mulx;
    int muly;
  } range;
  struct {
    int x;
    int y;
  } offset;
  struct {
    struct {
      int x;
      int y;
    } mul;
    struct {
      int x;
      int y;
    } div;
  } scale;
  struct {
    int x;
    int y;
    int width;
    int height;
  } dot;
  struct {
    int x;
    int y;
    int color;
  } current;
  union image_bitmap bitmap;
  volatile image_status_t status;
  struct image_draw {
    image_draw_count_t count;
    image_draw_count_t *line;
    int column_per;
    int column_num;
    image_draw_count_t *column;
    image_draw_count_t *pixel;
  } draw;
  struct image_copy {
    union image_bitmap bitmap;
  } copy;
  struct image_procs *procs;
};

int image_init(void);
int image_done(void);
int image_check(void);
int image_is_draw_line(image_t image, image_draw_count_t count, int y);
int image_is_draw_column(image_t image, image_draw_count_t count, int x, int y);
int image_is_draw_pixel(image_t image, image_draw_count_t count, int x, int y);
int image_set_draw_line(image_t image, image_draw_count_t count, int y);
int image_set_draw_column(image_t image, image_draw_count_t count, int x, int y);
int image_set_draw_pixel(image_t image, image_draw_count_t count, int x, int y);
int image_get_color(image_t image, int x, int y);
int image_set_color(image_t image, int x, int y, int color, unsigned int flags);
int image_copy_save(image_t image, int x, int y, int width, int height);
int image_copy_get_color(image_t image, int x, int y);
int image_copy_save_color(image_t image, int x, int y);
int image_get_index(image_t image);
image_t image_get_image(int index);
int image_reset_draw(image_t image);
int image_destroy(image_t image);
int image_create(image_t image, int width, int height, void *bitmap,
		 image_type_t type, unsigned int flags);
image_t image_get(int width, int height, void *bitmap,
		  image_type_t type, unsigned int flags);

#endif
