/*
 * boxui_demo_helloworld.c
 *
 * box-ui small example with best practices.
 *
 * (c) 2024 Dario Rodriguez <antartica@whereismybit.com>
 * This program is licensed under the terms of the MIT/X license.
 */


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

#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>

#include "boxui.h"

#define DEFAULT_SCREENW 800
#define DEFAULT_SCREENH 600

typedef struct mydata_t {
        SDL_Window *window;
        SDL_Renderer *renderer;
        boxui_t *boxui;
} mydata_t;

SDL_AppResult
SDL_AppInit(void **appstate, int argc, char *argv[])
{
        boxui_t *boxui;
        static mydata_t realmydata,*mydata;
        char *p;
        char *strerror;

        memset(&realmydata,0,sizeof(realmydata));
        mydata=&realmydata;
        SDL_SetAppMetadata("Boxui demo simplified", "1.0", "org.box-ui.com.example.camera-read-and-draw");
        if((strerror="SDL_init")==NULL
         || !SDL_Init(SDL_INIT_VIDEO)
         || (strerror="SDL_CreateWindowAndRenderer")==NULL
         || !SDL_CreateWindowAndRenderer("boxui demo helloworld",DEFAULT_SCREENW,DEFAULT_SCREENH,0,&mydata->window,&mydata->renderer)
         || (strerror="boxui")==NULL
         || (boxui=mydata->boxui=boxui_init(mydata->window,mydata->renderer,DEFAULT_SCREENW,DEFAULT_SCREENH))==NULL
         || (strerror="boxui_add")==NULL
         || (p=boxui_add(boxui,_F,_L,"label:.label","-text \"Hello World!\" -click labelclicked"))==NULL
         || (strerror="boxui_pack")==NULL
         || boxui_pack(boxui,_F,_L,p,"-side top -fill both -expand true -anchor center")!=0) {
                SDL_Log("ERROR: Couldn't init UI: %s failed\n",strerror);
                return SDL_APP_FAILURE;
        }
        boxui_setuserptr(boxui,mydata);
        boxui_setsignal(boxui,SIGINT,"sigint");
        *appstate=(void *)mydata;
        return SDL_APP_CONTINUE;
}

/* NOTE: SDL_AppEvent may get called concurrently with SDL_AppEvent() for events not pushed on the main thread. */
SDL_AppResult
SDL_AppEvent(void *appstate, SDL_Event *event)
{
        mydata_t *mydata=(mydata_t *)appstate;
        if(event->type==SDL_EVENT_QUIT) {
                return SDL_APP_SUCCESS; /* exit program with code 0 (ok) */
        } else if(event->type==SDL_EVENT_WINDOW_RESIZED) {
                boxui_resize(mydata->boxui,event->window.data1,event->window.data1);
        } else if(event->type==SDL_EVENT_KEY_DOWN && event->key.key==SDLK_ESCAPE) {
                return SDL_APP_SUCCESS; /* ESC key pressed, exit program with code 0 (ok) */
        } else {
                boxui_event(mydata->boxui,event);
        }
        return SDL_APP_CONTINUE;  /* don't exit program */
}

SDL_AppResult
SDL_AppIterate(void *appstate)
{
        mydata_t *mydata=(mydata_t *)appstate;
        boxui_t *boxui;
        char *action,*actiondata;
        if(mydata==NULL || (boxui=mydata->boxui)==NULL)
                return SDL_APP_FAILURE; /* internal error, exit loop */
        /* actions */
        while((action=boxui_getaction(boxui,&actiondata))!=NULL) {
                if(strcmp(action,"sigint")==0) {
                        return SDL_APP_SUCCESS; /* interrupted by user, exit program with code 0 (ok) */
                } else if(strcmp(action,"labelclicked")==0) {
                        boxui_config(mydata->boxui,_F,_L,".label","-text \"Hello again!\"");
                }
        }
        /* rendering */
        boxui_tick(mydata->boxui);
        if(boxui_haschanged(mydata->boxui)) {
                SDL_Texture *texture;
                texture=boxui_gettexture(mydata->boxui);
                SDL_SetRenderDrawColor(mydata->renderer, 0x99, 0x99, 0x99, 255);
                SDL_RenderClear(mydata->renderer);
                SDL_RenderTexture(mydata->renderer, texture, NULL, NULL);
                SDL_RenderPresent(mydata->renderer);
        }
        return SDL_APP_CONTINUE;  /* don't exit program */
}

void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
    mydata_t *mydata=(mydata_t *)appstate;
    if(mydata!=NULL)
        boxui_free(mydata->boxui),mydata->boxui=NULL;
}