/*
 * 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(y1 >= clipy2) {
		h = 0;
	} else if(y1 + h > clipy2) {
		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;    
  }
}
/*--------------------------------------------------------------------------*/
