/*  mp3player hardware test

    15.05.2001: tk, initial implementation.

    Copyright (c)2000 by Thomas Kindler, thomas.kindler@gmx.de

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of
    the License, or (at your option) any later version. Read the
    full License at http://www.gnu.org/copyleft for more details.
*/

// include files -----
//
#include <mem.h>
#include <malloc.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <io.h>
#include <stdlib.h>
#include "misc.h"
#include "ztimer.h"
#include "vs1001.h"
#include "rtos.h"
#include "checkbios.h"
#include "gfxcore.h"
#include "gfxdriver.h"
#include "gfxutil.h"
#include "gfxfont.h"
#include "remote.h"
#include "ztimer.h"

Font   *font;


/**
 * Draw a line.
 *
 * \param  gfx  Graphics context to use.
 * \param  x1, y1, x2, y2  line coordinates.
 *
 * \todo   yuck! slow spaghetti code!
 *   Perhaps we should do the right thing -
 *   fast assembly functions for horizontal
 *   and vertical lines, slow pure C functions
 *   for bresenham. Who needs lines on an mpeg
 *   player, anyway?
 */
void GFX_LineX(Graphics *gfx, int x1, int y1, int x2, int y2)
{
  int dx = (x2-x1)*2;
  if (dx<0) dx=-dx;

  int dy = (y2-y1)*2;
  if (dy<0) dy=-dy;


  if (dx > dy) {
    int fraction = dy - (dx >> 1);   // same as 2*dy - dx

    // always draw left-to-right.
    //
    if (x2<x1) { swap(x1, x2);  swap(y1, y2); }

    int w = (x2-x1)+1;
    char *dst = &gfx->bitmap->bmBits[x1 + (y1>>3)*gfx->bitmap->width];
    unsigned char mask = 1 << (y1 & 7);

    if (y1 < y2) {
      while (w--) {
        *dst++ |= mask;
        if (fraction >= 0) {
          mask <<= 1;
          if (!mask) {
            mask = 0x01;
            dst += gfx->bitmap->width;
          }
          fraction -= dx;
        }
        fraction += dy;
      }
    } else {
      while (w--) {
        *dst++ |= mask;
        if (fraction >= 0) {
          mask >>= 1;
          if (!mask) {
            mask = 0x80;
            dst -= gfx->bitmap->width;
          }
          fraction -= dx;
        }
        fraction += dy;
      }
    }

  } else {
    int fraction = dx - (dy >> 1);   // same as 2*dy - dx

    // always draw top-down
    //
    if (y2<y1) { swap(x1, x2);  swap(y1, y2); }
    int h = (y2-y1)+1;

    char *dst = &gfx->bitmap->bmBits[x1 + (y1>>3)*gfx->bitmap->width];
    unsigned char mask = 1 << (y1 & 7);

    if (x1 < x2) {
      while (h--) {
        *dst  |= mask;
        mask <<= 1;
        if (!mask) {
          mask = 1;
          dst += gfx->bitmap->width;
        }
        if (fraction >= 0) {
          dst++;
          fraction -= dy;
        }
        fraction += dx;
      }
    } else {
      while (h--) {
        *dst |= mask;
        mask <<= 1;
        if (!mask) {
          mask = 1;
          dst += gfx->bitmap->width;
        }
        if (fraction >= 0) {
          dst--;
          fraction -= dy;
        }
        fraction += dx;
      }
    }

  }
}


void  gfxTest()
{
  Bitmap *screen = BM_Alloc(122, 32);
  Bitmap *logo   = BM_Load("test.bmp");

  Graphics  gfx;
  GFX_Init(&gfx, screen);
  GFX_SetFont(&gfx, font);


  BM_Info(screen);
  BM_Info(logo);

  int x=32, y=16, u=8, v=8, w=16, h=16, op = 0;
  while (!kbhit()) {

    long key = RC_GetKey();
//    printf("%c", 12);
    switch (key & ~RCKEY_REPEAT) {
      case 0x10d52a10:   return;

      case 0x10d52a14:   x--; break;
      case 0x10d52a02:   x++; break;
      case 0x10d52a18:   y--; break;
      case 0x10d52a01:   y++; break;

      case 0x10d52a17:   u--; break;
      case 0x10d52a08:   u++; break;
      case 0x10d52a04:   v--; break;
      case 0x10d52a07:   v++; break;

      case 0x10d52a1a:   w--; break;
      case 0x10d52a03:   w++; break;
      case 0x10d52a06:   h--; break;
      case 0x10d52a09:   h++; break;

      case 0x10d52a13:   op++; break;

      case 0x10d52a19:
        BM_Save(screen, "www\\shot.bmp");
        break;

      default:
        printf("unkown code: 0x%lx\n", key);
        break;
    }
    BM_Clear(screen);

/*
    GFX_PrintAt(&gfx, 0,  0, "PalmOS Fonts rul0r3n!");
    GFX_PrintAt(&gfx, 0,  8, "K/oS MP3 Player v2");
    GFX_PrintfAt(&gfx, 0, 16, "www.kreapc.de op=%d", op);
    op &= 15;
    BM_Blit(screen, x, y, logo, u, v, -1, -1, op);
*/

/*    GFX_SetFillStyle(&gfx, xHatchFill);
    ZTimer_Start();
    GFX_FillRect(&gfx, x, y, w, h);
    int time1 = ZTimer_Stop();
    GFX_MoveTo(&gfx, 0, 0);
    GFX_Printf(&gfx, "%d,%d,%d,%d: %d us ", x, y, w, h, time1);
*/

    ZTimer_Start();
    if (w&1)
      GFX_LineX(&gfx, 1, 1, 120, 30);
    else
      GFX_LineX(&gfx, x, y, x+u, y+v);
    int time = ZTimer_Stop();

    GFX_PrintfAt(&gfx, 61, -1, "%d us", time);

    LCD_Update(screen);
  }
}


void main(int argc, char* argv[])
{
  if (!CheckBIOS())
    return;

  LCD_Init();
  RC_Init();
  VS_Init();

  font = GFX_LoadFont("fonts\\compac~1.fnt");
  font->firstChar--;
  //  font = GFX_LoadFont("fonts\\foo.fnt");
  if (font)
    gfxTest();

  VS_Done();
  RC_Done();
  LCD_Done();
}
