/* A small p1 image-lib */
/* Author: Florent Monnier */
/* Date: Jan, 2026 */

#include "imglib.h"

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

struct _img *
create_img(unsigned int w, unsigned int h)
{
  struct _img *usr_img;

  usr_img = malloc(sizeof(struct _img));

  usr_img->ds = malloc((w * h * 1) * sizeof(unsigned char));
  memset(usr_img->ds, 0, (w * h * 1) * sizeof(unsigned char));

  usr_img->w = w;
  usr_img->h = h;

  return usr_img;
}

void
free_img(struct _img *img)
{
  free(img->ds);
  free(img);
}

void
draw_rect(struct _img *img, struct _rect *rect, unsigned char value)
{
  int _x = rect->x;
  int _y = rect->y;
  unsigned int _w = rect->w;
  unsigned int _h = rect->h;

  int x;
  int y;
  unsigned long n;

  for (y = _y; y < (_y + _h); y++) {
    for (x = _x; x < (_x + _w); x++) {
      if (x >= 0 && x < img->w) {
        if (y >= 0 && y < img->h) {
          n = (y * img->w) + x;
          img->ds[n] = value;
        }
      }
    }
  }
}

void
put_px(struct _img *img, int x, int y, unsigned char value)
{
  unsigned long n;

  if (x >= 0 && x < img->w) {
    if (y >= 0 && y < img->h) {
      n = (y * img->w) + x;
      img->ds[n] = value;
    }
  }
}

void
draw_losng(struct _img *img, struct _pnt *p, unsigned int d, unsigned char value)
{
  int _x;
  int _y;

  unsigned int _d;

  _x = p->x;
  _y = p->y;

  for (_d = 0; _d < d; _d++) {
    _x += 1;
    _y += 1;
    put_px(img, _x, _y, value);
  }

  for (_d = 0; _d < d; _d++) {
    _x += 1;
    _y -= 1;
    put_px(img, _x, _y, value);
  }

  for (_d = 0; _d < d; _d++) {
    _x -= 1;
    _y -= 1;
    put_px(img, _x, _y, value);
  }

  for (_d = 0; _d < d; _d++) {
    _x -= 1;
    _y += 1;
    put_px(img, _x, _y, value);
  }
}

unsigned int
sq_dist(struct _pnt *p1, struct _pnt *p2)
{
  int x1;
  int y1;
  int x2;
  int y2;
  int dx;
  int dy;

  unsigned int sq_dist;

  x1 = p1->x;
  y1 = p1->y;

  x2 = p2->x;
  y2 = p2->y;

  dx = x2 - x1;
  dy = y2 - y1;

  sq_dist = (dx * dx) + (dy * dy);

  return (sq_dist);
}

void
draw_circ(struct _img *img, struct _pnt *c, unsigned int r, unsigned char value)
{
  unsigned int w;
  unsigned int h;

  int cx;
  int cy;

  int _x1;
  int _y1;
  int _x2;
  int _y2;

  int x;
  int y;

  unsigned int d;
  unsigned long n;

  w = img->w;
  h = img->h;

  cx = c->x;
  cy = c->y;

  _x1 = cx - r;
  _y1 = cy - r;
  _x2 = cx + r;
  _y2 = cy + r;

  for (y = _y1; y < _y2; y++) {
    for (x = _x1; x < _x2; x++) {
      struct _pnt p;
      p.x = x;
      p.y = y;
      d = sq_dist(c, &p);
      if (x >= 0 && x < w) {
        if (y >= 0 && y < h) {
          if (d < (r * r)) {
            n = (y * img->w) + x;
            img->ds[n] = value;
          }
        }
      }
    }
  }
}

void
print_img(struct _img *img)
{
  unsigned int x;
  unsigned int y;
  unsigned int w;
  unsigned int h;
  unsigned char d;
  unsigned long n;
  w = img->w;
  h = img->h;
  printf("P1\n");
  printf("%d %d\n", w, h);
  for (y = 0; y < h; y++) {
    for (x = 0; x < w; x++) {
      n = (y * w) + x;
      d = img->ds[n];
      if (x == 0)
        printf("%d", d);
      else
        printf(" %d", d);
    }
    printf("\n");
  }
}

