/*
 * Copyright (c) 2002, Adam Dunkels.
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution. 
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.  
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 * This file is part of the "ctk" console GUI toolkit for cc65
 *
 * $Id: ctk-conio-service.c,v 1.12 2006/05/28 20:38:19 oliverschmidt Exp $
 *
 */

#include <conio.h>

#include "ctk.h"
#include "ctk-draw.h"

#include "ctk-draw-service.h"

#include "ctk-conio-conf.h"
#include <string.h>

#ifndef NULL
#define NULL (void *)0
#endif /* NULL */

static unsigned char sizex, sizey;

/*unsigned char ctk_draw_windowborder_height = 1;
unsigned char ctk_draw_windowborder_width = 1;
unsigned char ctk_draw_windowtitle_height = 1;*/

// The revers function does nothing in our conio driver anyway.
#define revers(x)

#if 0
static void revers(bool invert)
{
	static bool isInverted;
	if (isInverted == invert)
		return;

	__asm
		call 0xBB9C
	__endasm
}
#endif

/*-----------------------------------------------------------------------------------*/
static void
s_ctk_draw_init(void)
{
  (void)bgcolor(SCREENCOLOR);
  (void)bordercolor(BORDERCOLOR);
  clrscr();
  screensize(&sizex, &sizey);
}
/*-----------------------------------------------------------------------------------*/


static void customchr(const unsigned char* data) __naked __preserves_regs(c, d, e)
{
    __asm
	; Cant use SCR SET MATRIX because some of our icons are in RAM under 0x4000.
	; SCR SET MATRIX then gets data from the firmware ROM...
	ld a,#0x19
	call 0xBB5a
	ld a,#0xff
	call 0xBB5a
	ld b,#8
00001$:
	ld a,(hl)
	call 0xbb5a
	inc hl
	djnz 00001$
	ret
    __endasm;
}


static void
draw_widget(struct ctk_widget *w,
	    unsigned char x, unsigned char y,
	    unsigned char clipx,
	    unsigned char clipy,
	    unsigned char clipy1, unsigned char clipy2,
	    unsigned char focus)
{
  unsigned char xpos, ypos, xscroll;
  unsigned char i, j;
  char c;
  const char* text;
  unsigned char len, wfocus;

  wfocus = 0;
  if(focus & CTK_FOCUS_WINDOW) {    
    (void)textcolor(WIDGETCOLOR_FWIN);
    if(focus & CTK_FOCUS_WIDGET) {
      (void)textcolor(WIDGETCOLOR_FOCUS);
      wfocus = 1;
    }
  } else if(focus & CTK_FOCUS_DIALOG) {
    (void)textcolor(WIDGETCOLOR_DIALOG);
    if(focus & CTK_FOCUS_WIDGET) {
      (void)textcolor(WIDGETCOLOR_FOCUS);
      wfocus = 1;
    }
  } else {
    (void)textcolor(WIDGETCOLOR);
  }
  
  xpos = x + w->x;
  ypos = y + w->y;
    
  switch(w->type) {
  case CTK_WIDGET_SEPARATOR:
    if(ypos >= clipy1 && ypos < clipy2) {
      chlinexy(xpos, ypos, w->w);
    }
    break;
  case CTK_WIDGET_LABEL:
    text = w->widget.label.text;
    for(i = 0; i < w->h; ++i) {
      if(ypos >= clipy1 && ypos < clipy2) {
	gotoxy(xpos, ypos);
	cputsn(text, w->w);
	if(w->w - (wherex() - xpos) > 0) {
	  cclear(w->w - (wherex() - xpos));
	}
      }
      ++ypos;
      text += w->w;
    }
    break;
  case CTK_WIDGET_BUTTON:
    if(ypos >= clipy1 && ypos < clipy2) {
      revers(wfocus != 0);
      cputcxy(xpos, ypos, '[');
      cputsn(w->widget.button.text, w->w);
      cputc(']');
      revers(0);
    }
    break;
  case CTK_WIDGET_HYPERLINK:
    if(ypos >= clipy1 && ypos < clipy2) {
      (void)textcolor(WIDGETCOLOR_HLINK);
      revers(wfocus == 0);
      gotoxy(xpos, ypos);
      cputsn(w->widget.button.text, w->w);
      revers(0);
    }
    break;
  case CTK_WIDGET_TEXTENTRY:
    text = w->widget.textentry.text;
    xscroll = 0;
    if(w->widget.textentry.xpos >= w->w - 1) {
      xscroll = w->widget.textentry.xpos - w->w + 1;
    }
    for(j = 0; j < w->h; ++j) {
      if(ypos >= clipy1 && ypos < clipy2) {
	if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT &&
	   w->widget.textentry.ypos == j) {
	  revers(0);
	  cputcxy(xpos, ypos, '>');
	  c = 1;
	  for(i = 0; i < w->w; ++i) {
	    if(c != 0) {
	      c = text[i + xscroll];
	    }
            revers(i == w->widget.textentry.xpos - xscroll);
	    if(c == 0) {
	      cputc(' ');
	    } else {
	      cputc(c);
	    }
	  }
	  revers(0);
	  cputc('<');
	} else {
	  revers(wfocus != 0 && j == w->widget.textentry.ypos);
	  cvlinexy(xpos, ypos, 1);
	  gotoxy(xpos + 1, ypos);
	  cputsn(text, w->w);
	  i = wherex();
	  if(i - xpos - 1 < w->w) {
	    cclear(w->w - (i - xpos) + 1);
	  }
	  cvline(1);
	}
      }
      ++ypos;
      text += w->widget.textentry.len + 1;
    }
    revers(0);
    break;
  case CTK_WIDGET_ICON:

    if(ypos >= clipy1 && ypos < clipy2) {
      revers(wfocus != 0);
#if CTK_CONF_ICON_BITMAPS
      gotoxy(xpos, ypos);
      if(w->widget.icon.bitmap != NULL) {
	  const unsigned char* ptr  = w->widget.icon.bitmap;
	for(i = 0; i < 3; ++i) {
	  gotoxy(xpos, ypos);
	  //gotox(xpos); gotoy(ypos);
	  if(ypos >= clipy1 && ypos < clipy2) {
	    customchr(ptr);
	    cputc(0xff);
	    ptr += 8;
	    customchr(ptr);
	    cputc(0xff);
	    ptr += 8;
	    customchr(ptr);
	    cputc(0xff);
	    ptr += 8;
	  }
	  ++ypos;
	}
      }
#elif CTK_CONF_ICON_TEXTMAPS
      gotoxy(xpos, ypos);
      if(w->widget.icon.textmap != NULL) {
	for(i = 0; i < 3; ++i) {
	  gotoxy(xpos, ypos);
	  if(ypos >= clipy1 && ypos < clipy2) {
	    cputc(w->widget.icon.textmap[0 + 3 * i]);
	    cputc(w->widget.icon.textmap[1 + 3 * i]);
	    cputc(w->widget.icon.textmap[2 + 3 * i]);
	  }
	  ++ypos;
	}
      }
#endif
      x = xpos;
  
      len = strlen(w->widget.icon.title);
      if(x + len >= sizex) {
	x = sizex - len;
      }

      gotoxy(x, ypos);
      if(ypos >= clipy1 && ypos < clipy2) {
	cputs(w->widget.icon.title);
      }
      revers(0);
    }
    break;

  default:
    break;
  }
}
/*-----------------------------------------------------------------------------------*/
static void
s_ctk_draw_widget(struct ctk_widget *w,
		  unsigned char focus,
		  unsigned char clipy1,
		  unsigned char clipy2)
{
  struct ctk_window *win = w->window;
  unsigned char posx, posy;

  posx = win->x + 1;
  posy = win->y + 2;

  if(w == win->focused) {
    focus |= CTK_FOCUS_WIDGET;
  }
  
  draw_widget(w, posx, posy,
	      posx + win->w,
	      posy + win->h,
	      clipy1, clipy2,
	      focus);
  
#ifdef CTK_CONIO_CONF_UPDATE
  CTK_CONIO_CONF_UPDATE();
#endif /* CTK_CONIO_CONF_UPDATE */
}
/*-----------------------------------------------------------------------------------*/

static void clearrect(unsigned char y2, unsigned char x2,
	unsigned char y1, unsigned char x1) __naked __z88dk_callee
{
	// Y2 is in A
	// X2 is in L
	// Stack has:
	// - Return value
	// - Y1
	// - X1
  __asm
		LD d,l
		LD e,A

		pop bc ; RV
		pop hl ; x1 y1
		push bc

		call	0xBB99 ; TXT GET PAPER

		; A contains PAPER number

		call	0xBC2C ; SCR INK ENCODE

		; A contains encoded PEN

		; Here we need:
		; H = X1
		; L = Y1
		; D = X2
		; E = Y2
		; A = encoded pen

		jp	0xBC44 ; SCR FILL BOX
    __endasm;
}

static void
s_ctk_draw_clear_window(struct ctk_window *window,
		      unsigned char focus,
		      unsigned char clipy1,
		      unsigned char clipy2)
{
  unsigned char i;
  unsigned char h;

  /*
  if(focus & CTK_FOCUS_WINDOW) {
    (void)textcolor(WINDOWCOLOR_FOCUS);
  } else {
    (void)textcolor(WINDOWCOLOR);
  }
  */
    
  i = window->y + 2; // +1 for the border, +1 for ctk > cpc conversion
  h = i + window->h;

  if (i >= clipy2 || h < clipy1)
	  return;

  if (i < clipy1) i = clipy1;
  if (h >= clipy2) h = clipy2 - 1;

  clearrect(h, window->x + window->w, i, window->x + 1);
}
/*-----------------------------------------------------------------------------------*/
static void
draw_window_contents(struct ctk_window *window, unsigned char focus,
		     unsigned char clipy1, unsigned char clipy2,
		     unsigned char x1, unsigned char x2,
		     unsigned char y1, unsigned char y2)
{
  struct ctk_widget *w;
  unsigned char wfocus;
  
  /* Draw inactive widgets. */
  for(w = window->inactive; w != NULL; w = w->next) {
    draw_widget(w, x1, y1, x2, y2,
		clipy1, clipy2,
		focus);
  }
  
  /* Draw active widgets. */
  for(w = window->active; w != NULL; w = w->next) {  
    wfocus = focus;
    if(w == window->focused) {
      wfocus |= CTK_FOCUS_WIDGET;
    }

   draw_widget(w, x1, y1, x2, y2, 
	       clipy1, clipy2,
	       wfocus);
  }

#ifdef CTK_CONIO_CONF_UPDATE
  CTK_CONIO_CONF_UPDATE();
#endif /* CTK_CONIO_CONF_UPDATE */
}
/*-----------------------------------------------------------------------------------*/
static void
s_ctk_draw_window(struct ctk_window *window, unsigned char focus,
		  unsigned char clipy1, unsigned char clipy2,
		  unsigned char draw_borders)
{
  unsigned char x, y;
  unsigned char h;
  unsigned char x1, y1, x2, y2;

  if(window->y + 1 >= clipy2) {
    return;
  }
    
  x = window->x;
  y = window->y + 1;
  x1 = x + 1;
  y1 = y + 1;
  x2 = x1 + window->w;
  y2 = y1 + window->h;

  if(draw_borders) {  

    /* Draw window frame. */
    if(focus & CTK_FOCUS_WINDOW) {
      (void)textcolor(WINDOWCOLOR_FOCUS);
    } else {
      (void)textcolor(WINDOWCOLOR);
    }

    if(y >= clipy1) {
      cputcxy(x, y, CH_ULCORNER);
      gotoxy(wherex() + window->titlelen + CTK_CONF_WINDOWMOVE * 2, wherey());
      chline(window->w - (wherex() - x) - 2);
      cputcxy(x2, y, CH_URCORNER);
    }

    h = window->h;
  
    if(clipy1 > y1) {
      if(clipy1 - y1 < h) {
	h = clipy1 - y1;
	      y1 = clipy1;
      } else {
	h = 0;
      }
    }

    if(clipy2 < y1 + h) {
      if(y1 >= clipy2) {
	h = 0;
      } else {
	h = clipy2 - y1;
      }
    }

    cvlinexy(x, y1, h);
    cvlinexy(x2, y1, h);  

    if(y + window->h >= clipy1 &&
       y + window->h < clipy2) {
      cputcxy(x, y2, CH_LLCORNER);
      chlinexy(x1, y2, window->w);
      cputcxy(x2, y2, CH_LRCORNER);
    }
  }

  draw_window_contents(window, focus, clipy1, clipy2,
		       x1, x2, y + 1, y2);
}
/*-----------------------------------------------------------------------------------*/
static void
s_ctk_draw_dialog(struct ctk_window *dialog)
{
  unsigned char x, y;
  unsigned char x1, y1, x2, y2;
  
  (void)textcolor(DIALOGCOLOR);

  x = dialog->x;
  y = dialog->y + 1;

  x1 = x + 1;
  y1 = y + 1;
  x2 = x1 + dialog->w;
  y2 = y1 + dialog->h;

  /* Draw dialog frame. */
  cvlinexy(x, y1,
	   dialog->h);
  cvlinexy(x2, y1,
	   dialog->h);

  chlinexy(x1, y,
	   dialog->w);
  chlinexy(x1, y2,
	   dialog->w);

  cputcxy(x, y, CH_ULCORNER);
  cputcxy(x, y2, CH_LLCORNER);
  cputcxy(x2, y, CH_URCORNER);
  cputcxy(x2, y2, CH_LRCORNER);
  
  /* Clear dialog contents. */
  clearrect(y2 - 1, x1 + dialog->w - 1, y1, x1);

  draw_window_contents(dialog, CTK_FOCUS_DIALOG, 0, sizey,
		       x1, x2, y1, y2);
}
/*-----------------------------------------------------------------------------------*/
static void
s_ctk_draw_clear(unsigned char y1, unsigned char y2) __naked
{
  __asm
	  pop de
	  pop hl
	  push hl
	  push de

		push af

		ld		e,h
		ld		h,#1
		ld d,#40

		dec e

		call	0xBB99 ; TXT GET PAPER
		call	0xBC2C ; SCR INK ENCODE

		call	0xBC44 ; SCR FILL BOX

		pop af
		ret
    __endasm;
}
/*-----------------------------------------------------------------------------------*/
static void
draw_menu(struct ctk_menu *m, unsigned char open)
{
  unsigned char x, x2, y;

  if(open) {
    x = x2 = wherex();
    if(x2 + CTK_CONF_MENUWIDTH > sizex) {
      x2 = sizex - CTK_CONF_MENUWIDTH;
    }

    for(y = 0; y < m->nitems; ++y) {
      if(y == m->active) {
	(void)textcolor(ACTIVEMENUITEMCOLOR);
      } else {
	(void)textcolor(SCREENCOLOR);	  
      }
      gotoxy(x2, y + 1);
      if(m->items[y].title[0] == '-') {
	chline(CTK_CONF_MENUWIDTH);
      } else {
	cputs(m->items[y].title);
      }
      if(x2 + CTK_CONF_MENUWIDTH > wherex()) {
	cclear(x2 + CTK_CONF_MENUWIDTH - wherex());
      }
    }

    gotoxy(x, 0);
    (void)textcolor(OPENMENUCOLOR);
  }

  cputs(m->title);
  cputc(' ');
}
/*-----------------------------------------------------------------------------------*/
static void
s_ctk_draw_menus(struct ctk_menus *menus)
{
  struct ctk_menu *m;

  /* Draw menus */
  (void)bgcolor(MENUCOLOR);
  (void)textcolor(SCREENCOLOR);	  
  gotoxy(0, 0);
  cputc(' ');
  for(m = menus->menus->next; m != NULL; m = m->next) {
    draw_menu(m, m == menus->open);
  }

  /* Draw desktopmenu */
  if(wherex() + strlen(menus->desktopmenu->title) + 1 >= sizex) {
    gotoxy(sizex - strlen(menus->desktopmenu->title) - 1, 0);
  } else {
    cclear(sizex - wherex() -
	   strlen(menus->desktopmenu->title) - 1);
  }
  draw_menu(menus->desktopmenu, menus->desktopmenu == menus->open);

  (void)bgcolor(SCREENCOLOR);
}
/*-----------------------------------------------------------------------------------*/
static unsigned char
s_ctk_draw_height(void)
{
  return sizey;
}
/*-----------------------------------------------------------------------------------*/
static unsigned char
s_ctk_draw_width(void)
{
  return sizex;
}
/*-----------------------------------------------------------------------------------*/
static unsigned short
s_ctk_mouse_xtoc(unsigned short x)
{
  return x / 8;
}
/*-----------------------------------------------------------------------------------*/
static unsigned short
s_ctk_mouse_ytoc(unsigned short y)
{
  return y / 8;
}
/*-----------------------------------------------------------------------------------*/
static const struct ctk_draw_service_interface interface =
  {CTK_DRAW_SERVICE_VERSION,
   1,
   1,
   1,
   s_ctk_draw_init,
   s_ctk_draw_clear,
   s_ctk_draw_clear_window,
   s_ctk_draw_window,
   s_ctk_draw_dialog,
   s_ctk_draw_widget,
   s_ctk_draw_menus,
   s_ctk_draw_width,
   s_ctk_draw_height,
   s_ctk_mouse_xtoc,
   s_ctk_mouse_ytoc,
  };

EK_EVENTHANDLER(eventhandler, ev, data);
EK_PROCESS(proc, CTK_DRAW_SERVICE_NAME ": text", EK_PRIO_NORMAL,
	   eventhandler, NULL, (void *)&interface);

/*--------------------------------------------------------------------------*/
LOADER_INIT_FUNC(ctk_conio_service_init, arg)
{
  s_ctk_draw_init();
  ek_service_start(CTK_DRAW_SERVICE_NAME, &proc);
}
/*--------------------------------------------------------------------------*/
EK_EVENTHANDLER(eventhandler, ev, data)
{
  EK_EVENTHANDLER_ARGS(ev, data);
  
  switch(ev) {
  case EK_EVENT_INIT:
  case EK_EVENT_REPLACE:
    s_ctk_draw_init();
    ctk_restore();
    break;
  case EK_EVENT_REQUEST_REPLACE:
    ek_replace((struct ek_proc *)data, NULL);
    LOADER_UNLOAD();
    break;    
  }
}
/*--------------------------------------------------------------------------*/
