/*
 * re_ui.c
 *
 * A programmers editor
 *
 * Simple UI in SDL2
 *
 * Author: Dario Rodriguez dario@softhome.net
 * This program is licensed under the terms of GNU GPL v2.1+
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include "re_ui.h"
#include "hack_regular.h"

#define DEFAULTFONTSIZE 16
#define DEFAULTTITLEPREFIX "re - "
#define DEFAULTWINDOWWIDTH 80
#define DEFAULTWINDOWHEIGHT 66

#define RECTFILL(r,rx,ry,rw,rh) (r).x=(rx),(r).y=(ry),(r).w=(rw),(r).h=(rh)

reui_t *
reui_init()
{
        reui_t *ui;
        SDL_Rect screenrect;
        if((ui=malloc(sizeof(reui_t)))==NULL)
                return(NULL);
        memset(ui,0,sizeof(reui_t));
        /* video */
        if(SDL_Init(SDL_INIT_VIDEO)<0
          || SDL_GetDisplayBounds(0,&screenrect)!=0) {
                reui_free(ui),ui=NULL;
                return(NULL);
        }
        ui->screenw=screenrect.w;
        ui->screenh=screenrect.h;
        /* font */
        ui->fontheight=DEFAULTFONTSIZE;
        ui->fontdata=SDL_RWFromConstMem(hack_regular,SIZE_HACK_REGULAR);
        SDL_RWseek(ui->fontdata,0,RW_SEEK_SET);
        if(ui->fontdata==NULL
          || TTF_Init()==-1
          || (ui->font=TTF_OpenFontRW(ui->fontdata,0,ui->fontheight))==NULL) {
                reui_free(ui),ui=NULL;
                return(NULL);
        }
        /* font width */
        {
                SDL_Surface *s;
                SDL_Color c={0,0,0,0};
                if((s=TTF_RenderUTF8_Blended(ui->font,"m",c))==NULL) {
                        reui_free(ui),ui=NULL;
                        return(NULL);
                }
                ui->fontwidth=s->w;
                SDL_FreeSurface(s),s=NULL;
        }
        /* main window */
        ui->w=ui->fontwidth*DEFAULTWINDOWWIDTH;
        ui->w=(ui->w>ui->screenw)?ui->screenw:ui->w;
        ui->h=ui->fontheight*DEFAULTWINDOWHEIGHT;
        ui->h=(ui->h>ui->screenh)?ui->screenw:ui->h;
        if((ui->win=SDL_CreateWindow(
              DEFAULTTITLEPREFIX,
              SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,
              ui->w,ui->h,0))==NULL
          || (ui->renderer=SDL_CreateRenderer(ui->win,-1,
              SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC))==NULL
          || (ui->scr=SDL_CreateTexture(ui->renderer,SDL_PIXELFORMAT_ARGB8888,
              SDL_TEXTUREACCESS_STREAMING,ui->w,ui->h))==NULL) {
                reui_free(ui),ui=NULL;
                return(NULL);
        }
        /* finished */
        ui->scrdirty=1;
        ui->rendererdirty=1;
        return(ui);
}


void
reui_free(reui_t *ui)
{
        if(ui==NULL)
                return;
        if(ui->font!=NULL)
                TTF_CloseFont(ui->font),ui->fontdata=NULL;
        if(TTF_WasInit())
                TTF_Quit();
        if(ui->fontdata!=NULL)
                SDL_FreeRW(ui->fontdata),ui->fontdata=NULL;
        if(ui->scr!=NULL)
                SDL_DestroyTexture(ui->scr),ui->scr=NULL;
        if(ui->renderer!=NULL)
                SDL_DestroyRenderer(ui->renderer),ui->renderer=NULL;
        if(ui->win!=NULL)
                SDL_DestroyWindow(ui->win),ui->win=NULL;
        SDL_Quit();
        free(ui),ui=NULL;
}

int
reui_title(reui_t *ui, char *titlefilename)
{
        char buf[1024];
        if(ui==NULL || titlefilename==NULL)
                return(-1);
        snprintf(buf,sizeof(buf),"%s%s",DEFAULTTITLEPREFIX,titlefilename);
        buf[sizeof(buf)-1]='\0';
        SDL_SetWindowTitle(ui->win,buf);
        return(0);
}


int
reui_fill(reui_t *ui, int x, int y, int w, int h, char *rgba)
{
        SDL_Rect dstrect;
        if(ui==NULL || rgba==NULL)
                return(-1);
        RECTFILL(dstrect,x,y,w,h);
        SDL_SetRenderDrawColor(ui->renderer,
                ((unsigned char *)rgba)[0],
                ((unsigned char *)rgba)[1],
                ((unsigned char *)rgba)[2],
                ((unsigned char *)rgba)[3]);
        SDL_RenderFillRect(ui->renderer, &dstrect);
        ui->rendererdirty=1;
        return(0);
}

int
reui_scr2renderer(reui_t *ui, int x, int y, int w, int h)
{
        SDL_Rect srcrect,dstrect;
        if(ui==NULL)
                return(-1);
        RECTFILL(srcrect,x,y,w,h);
        RECTFILL(dstrect,x,y,w,h);
        SDL_RenderCopy(ui->renderer,ui->scr,&srcrect,&dstrect);
        ui->rendererdirty=1;
        return(0);
}

int
reui_present(reui_t *ui)
{
        if(ui==NULL)
                return(-1);
        SDL_RenderPresent(ui->renderer);
        ui->rendererdirty=0;
        return(0);
}

int
reui_write(reui_t *ui, int x, int y, char *rgba, char *str, int nchar)
{
        char buf[1024];
        SDL_Surface *fgsurface;
        SDL_Texture *fg;
        SDL_Color c={((unsigned char *)rgba)[0],
                     ((unsigned char *)rgba)[1],
                     ((unsigned char *)rgba)[2],
                     ((unsigned char *)rgba)[3]};
        SDL_Rect dstrect;
        if(nchar<sizeof(buf)) {
                memcpy(buf,str,nchar);
                buf[nchar]='\0';
        } else {
                memcpy(buf,str,sizeof(buf)-1);
                buf[sizeof(buf)-1]='\0';
        }
        if((fgsurface=TTF_RenderUTF8_Blended(ui->font,buf,c))==NULL
          || (fg=SDL_CreateTextureFromSurface(ui->renderer,fgsurface))==NULL) {
                if(fgsurface!=NULL)
                        SDL_FreeSurface(fgsurface),fgsurface=NULL;
                return(-1);
        }
        RECTFILL(dstrect,x,y,fgsurface->w,fgsurface->h);
        SDL_RenderCopy(ui->renderer,fg,NULL,&dstrect);
        ui->rendererdirty=1;
        SDL_FreeSurface(fgsurface),fgsurface=NULL;
        SDL_DestroyTexture(fg),fg=NULL;
        return(0);
}


int
reui_printf(reui_t *ui, int x, int y, char *rgba, char *format, ...)
{
        char buf[1024];
        va_list l;
        va_start(l,format);
        vsnprintf(buf,sizeof(buf),format,l);
        va_end(l);
        buf[sizeof(buf)-1]='\0';
        if(reui_write(ui,x,y,rgba,buf,strlen(buf))!=0)
                return(-1);
        return(0);
}