/*
 * includes
 */

#include <stdlib.h>
#include <stdio.h>

/*
 * defines
 */

#define ImagePixel(i,x,y) ((i)->pixel[(x) + ((y) * (i)->width)])

/*
 * structs
 */

struct Pixel {
  unsigned char r;
  unsigned char g;
  unsigned char b;
};

struct Image {
  unsigned int width;
  unsigned int height;
  struct Pixel *pixel;
};

struct Complex {
  double r;
  double i;
};

typedef struct Complex *C4Complex;

struct Fractal {
  struct Image *image;
  unsigned int julia_p:1;
  unsigned int red_p:1;
  unsigned int green_p:1;
  unsigned int blue_p:1;
  double r_min;
  double r_max;
  double i_min;
  double i_max;
  int itr_limit;
  struct Complex *julia_constant;
};

typedef struct Fractal *C4Fractal;

enum FractalParam {
  JuliaP,
  RealLimit,
  ImaginaryLimit,
  ItrLimit
};

/*
 * functions
 */

/* image.c */

struct Image *c4_image_create(unsigned int,  /* width   */
                              unsigned int); /* height  */

void c4_image_destroy(struct Image *);       /* image    */

void c4_image_set(struct Image *,            /* image    */
                  unsigned char,             /* red      */
                  unsigned char,             /* green    */
                  unsigned char);            /* blue     */

/* io.c */

void c4_io_out(struct Image *,              /* image    */
               char *);                     /* filename */

/* complex.c */

C4Complex c4_complex_create(double,         /* real       */
                            double);        /* imaginary  */

void c4_complex_destroy(C4Complex);         /* complex    */

C4Complex c4_complex_set(C4Complex,         /* dest       */
                         double,            /* real       */
                         double);           /* imaginary  */

C4Complex c4_complex_copy(C4Complex,        /* dest       */
                          C4Complex);       /* source     */

C4Complex c4_complex_add(C4Complex,         /* c1 +       */
                         C4Complex,         /* c2 ->      */
                         C4Complex);        /* c3         */

C4Complex c4_complex_mul(C4Complex,         /* c1 *       */
                         C4Complex,         /* c2 ->      */
                         C4Complex);        /* c3         */

double c4_complex_size(C4Complex);          /* complex    */

/* fractal.c */

C4Fractal c4_fractal_create(struct Image *, /* image       */
                            int,            /* param count */
                            ...);           /* params      */

void c4_fractal_destroy(C4Fractal);         /* fractal     */

void c4_fractal_render(C4Fractal);          /* fractal     */
