/*
 * icon-gen.c - Zygaena marine-dark launcher icon generator.
 *
 * Renders three 48x48 ARGB launcher glyphs - terminal, files, editor - in
 * the Hammerhead teal palette (matching wallpaper-gen.c). tint2 loads these
 * by ABSOLUTE path (Icon=/usr/local/share/hammerhead-desktop/launcher/*.png),
 * so no freedesktop icon theme / hicolor index.theme is required - which is
 * exactly why the stock launcher was illegible (st shipped no icon, xnedit's
 * png was loose, hicolor had no index.theme).
 *
 * Build: gcc icon-gen.c $(pkg-config --cflags --libs cairo) -lm -o ig
 * Usage: ./ig /output/dir   (writes terminal.png, files.png, editor.png,
 *                            and preview.png for design review)
 */
#include <cairo.h>
#include <math.h>
#include <stdio.h>

#define S 48   /* icon canvas size */

/* palette - matches wallpaper-gen.c */
#define TILE_R   0x12/255.0
#define TILE_G   0x2e/255.0
#define TILE_B   0x34/255.0
#define TEAL_R   0x1f/255.0
#define TEAL_G   0xb6/255.0
#define TEAL_B   0xb6/255.0
#define TEALBR_R 0x54/255.0
#define TEALBR_G 0xe0/255.0
#define TEALBR_B 0xe0/255.0
#define TEXT_R   0xcf/255.0
#define TEXT_G   0xe0/255.0
#define TEXT_B   0xe0/255.0

static void
rrect(cairo_t *cr, double x, double y, double w, double h, double r)
{
    cairo_new_sub_path(cr);
    cairo_arc(cr, x + w - r, y + r,     r, -M_PI / 2, 0);
    cairo_arc(cr, x + w - r, y + h - r, r, 0, M_PI / 2);
    cairo_arc(cr, x + r,     y + h - r, r, M_PI / 2, M_PI);
    cairo_arc(cr, x + r,     y + r,     r, M_PI, 3 * M_PI / 2);
    cairo_close_path(cr);
}

/* subtle elevated chip so the three icons read as one branded set */
static void
tile(cairo_t *cr)
{
    rrect(cr, 2.5, 2.5, S - 5, S - 5, 10);
    cairo_set_source_rgb(cr, TILE_R, TILE_G, TILE_B);
    cairo_fill_preserve(cr);
    cairo_set_source_rgba(cr, TEAL_R, TEAL_G, TEAL_B, 0.40);
    cairo_set_line_width(cr, 1.5);
    cairo_stroke(cr);
}

/* Terminal: a prompt chevron ">" plus a cursor underscore "_". */
static void
draw_terminal(cairo_t *cr)
{
    tile(cr);
    cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
    cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);

    cairo_set_source_rgb(cr, TEALBR_R, TEALBR_G, TEALBR_B);
    cairo_set_line_width(cr, 4.4);
    cairo_move_to(cr, 15, 16);
    cairo_line_to(cr, 25, 24);
    cairo_line_to(cr, 15, 32);
    cairo_stroke(cr);

    cairo_set_source_rgb(cr, TEXT_R, TEXT_G, TEXT_B);
    cairo_set_line_width(cr, 4.0);
    cairo_move_to(cr, 27, 33);
    cairo_line_to(cr, 34, 33);
    cairo_stroke(cr);
}

/* Files: a two-tone manila folder (tab + body). */
static void
draw_files(cairo_t *cr)
{
    tile(cr);
    cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);

    /* tab peeking above the body's top-left */
    cairo_set_source_rgb(cr, TEAL_R, TEAL_G, TEAL_B);
    rrect(cr, 11, 14, 14, 8, 2.5);
    cairo_fill(cr);

    /* back body */
    rrect(cr, 11, 18, 26, 17, 3);
    cairo_fill(cr);

    /* front pocket, lighter, slightly inset - gives the folder depth */
    cairo_set_source_rgb(cr, TEALBR_R, TEALBR_G, TEALBR_B);
    rrect(cr, 13, 23, 22, 12, 2.5);
    cairo_fill(cr);
}

/* Editor: a pencil at 45 degrees (eraser, shaft, nib, tip). */
static void
draw_editor(cairo_t *cr)
{
    tile(cr);
    cairo_save(cr);
    cairo_translate(cr, 24, 24);
    cairo_rotate(cr, -M_PI / 4);

    double pw = 8, half = pw / 2;

    /* shaft */
    cairo_set_source_rgb(cr, TEAL_R, TEAL_G, TEAL_B);
    rrect(cr, -half, -13, pw, 19, 1.5);
    cairo_fill(cr);

    /* eraser (top) */
    cairo_set_source_rgb(cr, TEXT_R, TEXT_G, TEXT_B);
    rrect(cr, -half, -16.5, pw, 4, 1.2);
    cairo_fill(cr);

    /* nib (bottom), brighter teal */
    cairo_set_source_rgb(cr, TEALBR_R, TEALBR_G, TEALBR_B);
    cairo_move_to(cr, -half, 6);
    cairo_line_to(cr,  half, 6);
    cairo_line_to(cr,  0,   14);
    cairo_close_path(cr);
    cairo_fill(cr);

    /* graphite tip */
    cairo_set_source_rgb(cr, TILE_R, TILE_G, TILE_B);
    cairo_move_to(cr, -2.2, 10.5);
    cairo_line_to(cr,  2.2, 10.5);
    cairo_line_to(cr,  0,   14);
    cairo_close_path(cr);
    cairo_fill(cr);

    cairo_restore(cr);
}

typedef void (*drawfn)(cairo_t *);

static void
emit(const char *dir, const char *name, drawfn fn)
{
    char path[1024];
    cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, S, S);
    cairo_t *cr = cairo_create(s);
    fn(cr);
    snprintf(path, sizeof path, "%s/%s", dir, name);
    cairo_surface_write_to_png(s, path);
    printf("wrote %s\n", path);
    cairo_destroy(cr);
    cairo_surface_destroy(s);
}

/* Review sheet: each glyph at 3x (detail) over the same glyph at 22px
 * (real launcher size) on a panel-tone strip, so legibility is judged at
 * the size it will actually render. */
static void
emit_preview(const char *dir)
{
    drawfn fns[3] = { draw_terminal, draw_files, draw_editor };
    int cw = 160, W = cw * 3, H = 210;
    char path[1024];

    cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, W, H);
    cairo_t *cr = cairo_create(s);

    cairo_set_source_rgb(cr, 0x0d / 255.0, 0x11 / 255.0, 0x17 / 255.0);
    cairo_paint(cr);

    for (int i = 0; i < 3; i++) {
        cairo_save(cr);
        cairo_translate(cr, i * cw + (cw - 144) / 2.0, 8);
        cairo_scale(cr, 144.0 / S, 144.0 / S);
        fns[i](cr);
        cairo_restore(cr);
    }

    /* panel strip */
    cairo_set_source_rgb(cr, 0x0e / 255.0, 0x1c / 255.0, 0x1f / 255.0);
    cairo_rectangle(cr, 0, 168, W, 42);
    cairo_fill(cr);
    for (int i = 0; i < 3; i++) {
        cairo_save(cr);
        cairo_translate(cr, i * cw + (cw - 22) / 2.0, 178);
        cairo_scale(cr, 22.0 / S, 22.0 / S);
        fns[i](cr);
        cairo_restore(cr);
    }

    snprintf(path, sizeof path, "%s/preview.png", dir);
    cairo_surface_write_to_png(s, path);
    printf("wrote %s\n", path);
    cairo_destroy(cr);
    cairo_surface_destroy(s);
}

int
main(int argc, char **argv)
{
    const char *dir = (argc > 1) ? argv[1] : ".";
    emit(dir, "terminal.png", draw_terminal);
    emit(dir, "files.png",    draw_files);
    emit(dir, "editor.png",   draw_editor);
    emit_preview(dir);
    return 0;
}
