/**********************************************************************
will add copyright bs later

$Id: main.cpp,v 1.3 2003/03/17 01:52:00 flameshadow Exp $
**********************************************************************/

#include "objgfx30.h"
#include "ogFont.h"
#include "ogSprite.h"
#include "ogBlit.h"
//#include "ogDisplay_VESA.h"
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <time.h>

using namespace std;

void testSetPixel(ogSurface& buf) {
  uInt32 xx,yy;
  buf.ogClear(buf.ogRGB(0,255,0));
  for (yy = 0; yy<=buf.ogGetMaxY(); yy++)
    for (xx = 0; xx<=buf.ogGetMaxX(); xx++)
      buf.ogSetPixel(xx,yy,xx*yy);
  getc(stdin);
  return;
} // testSetPixel

void testRect(ogSurface& buf) {
  uInt32 count;
  if (buf.ogGetBPP()==8)
    for (count=0; count<1000; count++)
      buf.ogRect(buf.ogGetMaxX() / 2 - count, buf.ogGetMaxY() / 2 - count,
                 buf.ogGetMaxX() / 2 + count, buf.ogGetMaxY() / 2 + count,
                 count);
  else
    for (count=0; count<1000; count++)
      buf.ogRect(buf.ogGetMaxX() / 2 - count, buf.ogGetMaxY() / 2 - count,
                 buf.ogGetMaxX() / 2 + count, buf.ogGetMaxY() / 2 + count,
                 buf.ogRGB(count,count,count));
  getc(stdin);
  return;
} // testRect
  
void testLine(ogSurface & buf) {
  uInt32 count;
  uInt32 colour;
  buf.ogClear(0);
  if (buf.ogGetBPP()==8)
    for (count=0; count<(buf.ogGetMaxX()+1); count+=2) {
      buf.ogLine(count,0,buf.ogGetMaxX()-count,buf.ogGetMaxY(),count);
    } // for
  else {
    colour = 255;
    for (count = 0; count < (buf.ogGetMaxX()+1)/2; count+=4) {
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 buf.ogGetMaxX()/2-count,buf.ogGetMaxY(),
                 buf.ogRGB(colour,colour,colour));
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 buf.ogGetMaxX()/2+count,buf.ogGetMaxY(),
                 buf.ogRGB(colour,colour,colour));
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 buf.ogGetMaxX()/2-count,0,
                 buf.ogRGB(0,colour,0));
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 buf.ogGetMaxX()/2+count,0,
                 buf.ogRGB(0,colour,0));
                 
      --colour;
    } // for

    colour = 255;
    for (count = 0; count < (buf.ogGetMaxY()+1)/2; count+=4) {
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 0, buf.ogGetMaxY()/2-count,
                 buf.ogRGB(colour,0,0));
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 0, buf.ogGetMaxY()/2+count,
                 buf.ogRGB(colour,0,0));
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 buf.ogGetMaxX(), buf.ogGetMaxY()/2-count,
                 buf.ogRGB(0,0,colour));
      buf.ogLine(buf.ogGetMaxX()/2, buf.ogGetMaxY()/2,
                 buf.ogGetMaxX(), buf.ogGetMaxY()/2+count,
                 buf.ogRGB(0,0,colour));
      --colour;
    } // for
  } // else
  getc(stdin);
  return;
} // testLine

void testClear(ogSurface & buf) {
  uInt32 count;
  if (buf.ogGetBPP()==8)
    for (count=0; count<256; count++)
      buf.ogClear(count);
  else {
    for (count=0; count<256; count+=8)
      buf.ogClear(buf.ogRGB(count,0,0));
    for (count=0; count<256; count+=8)
      buf.ogClear(buf.ogRGB(0,count,0));
    for (count=0; count<256; count+=8)
      buf.ogClear(buf.ogRGB(0,0,count));
    for (count=0; count<256; count+=8)
      buf.ogClear(buf.ogRGB(count,count,count));
  } // else
  getc(stdin);
  return;
} // testClear

void testCircle(ogSurface & buf) {
  uInt32 count;
  if (buf.ogGetBPP()==8)
    for (count=0; count<1000; count++)
      buf.ogCircle(buf.ogGetMaxX()/2,buf.ogGetMaxY()/2, count, count);
  else
    for (count=0; count<1000; count++)
      buf.ogCircle(buf.ogGetMaxX()/2,buf.ogGetMaxY()/2,count,buf.ogRGB(count,0,count));
  getc(stdin);
} // testCircle

void testVFlip(ogSurface & buf) {
  buf.ogVFlip();
  getc(stdin);
  return;
} // testVFlip

void testHFlip(ogSurface & buf) {
  buf.ogHFlip();
  getc(stdin);  
  return;
} // testHFlip

void testArc(ogSurface & buf) {
  uInt32 radius;
  uInt32 mid_x, mid_y;
  mid_x = buf.ogGetMaxX()/2;
  mid_y = buf.ogGetMaxY()/2;
  if (buf.ogGetBPP()==8) {
    for (radius = 1; radius <9; radius++) {
      buf.ogArc(mid_x, mid_y, radius*10, 0, 90, radius*15);
      buf.ogArc(mid_x, mid_y, radius*10, 180,270, 249-(radius-1)*16);
    } // for
  } else {
    for (radius = 1; radius <255; radius++) {
      buf.ogArc(mid_x, mid_y, radius, 0, 90, buf.ogRGB(radius,radius,0));
      buf.ogArc(mid_x, mid_y, radius, 180,270,buf.ogRGB(0,255-radius,255-radius));
    } // for
  } // else
  getchar();
  return;
} // testArc

void testCubicBezierCurve(ogSurface & buf) {
  buf.ogCubicBezierCurve(100, 100,
                         300,50,
                         400,120,
                         350,300,
                         25, buf.ogRGB(255,255,255));
  getchar();
  return;
} // testCubicBezierCurve

void testCurve(ogSurface & buf) {
  buf.ogCurve(10,10,100,30,35,160,20,buf.ogRGB(255,255,255));
  getchar();
  return;
} // testCurve
void testSprite(ogSurface & buf) {
  uInt32 count;
  uInt32 w,h;
  ogSprite * sprite = NULL;
  sprite = new ogSprite();
  
  buf.ogClear(0);
  testLine(buf);
  if (buf.ogGetBPP()==8)
    sprite->get(buf,
                buf.ogGetMaxX()/2-80,buf.ogGetMaxY()/2-80,
                buf.ogGetMaxX()/2+80,buf.ogGetMaxY()/2+80);
  else
    sprite->get(buf,
                buf.ogGetMaxX()/2-150,buf.ogGetMaxY()/2-150,
                buf.ogGetMaxX()/2+150,buf.ogGetMaxY()/2+150);

  sprite->save("test.spr");
  delete sprite;
  sprite = new ogSprite();
  sprite->load("test.spr");
  w = sprite->getWidth()/2;
  h = sprite->getHeight()/2;
  buf.ogClear(0);
  sprite->put(buf,-10000,-10000);  // test *really* off the screen
  sprite->put(buf,10000,10000);    // test *really* off the screen
  
  sprite->put(buf,buf.ogGetMaxX()/2-w,buf.ogGetMaxY()/2-h);
  sprite->put(buf,-w,-h);
  sprite->put(buf,buf.ogGetMaxX()/2-w,-h);
  sprite->put(buf,buf.ogGetMaxX()-w,-h);
  sprite->put(buf,-w,buf.ogGetMaxY()/2-h);
  sprite->put(buf,buf.ogGetMaxX()-w,buf.ogGetMaxY()/2-h);
  sprite->put(buf,-w,buf.ogGetMaxY()-h);
  sprite->put(buf,buf.ogGetMaxX()/2-w,buf.ogGetMaxY()-h);
  sprite->put(buf,buf.ogGetMaxX()-w,buf.ogGetMaxY()-h);
  getc(stdin);
  for (count = 0; count < 256; count++) {
    sprite->put(buf,random() % (buf.ogGetMaxX()+sprite->getWidth()) - sprite->getWidth(),
                    random() % (buf.ogGetMaxY()+sprite->getHeight()) - sprite->getHeight());
  } // for
  delete sprite;
  getc(stdin);
  return;
} // testSprite

void testBlit(ogSurface & buf) {
  int32 xx, yy, count;
  ogBlit * blit = NULL;
  blit = new ogBlit();
  buf.ogClear(0);
  for (xx= 0; xx<= 20; xx++) {
    buf.ogLine(128,0,128-xx*6,255,buf.ogRGB(255,255,255));
    buf.ogLine(128,0,128+xx*6,255,buf.ogRGB(255,255,255));
    buf.ogLine(128,255,128-xx*6,0,buf.ogRGB(255,255,255));
    buf.ogLine(128,255,128+xx*6,0,buf.ogRGB(255,255,255));
  } // for

  buf.ogFillCircle(128,128,60,buf.ogRGB(255,255,255));
  blit->get(buf,0,0,255,255);
  for (yy = 0; yy<=(int32)buf.ogGetMaxY(); yy++)
    for (xx = 0; xx<=(int32)buf.ogGetMaxX(); xx++)
      buf.ogSetPixel(xx,yy,xx*yy);
  blit->save("test.blt");
  delete blit;
  blit = new ogBlit();
  blit->load("test.blt");
  
  blit->put(buf,-10000,-10000);  // test *really* off the screen
  blit->put(buf,10000,10000);    // test *really* off the screen

  blit->put(buf,-128,-128);
  blit->put(buf,buf.ogGetMaxX()/2-128,-128);
  blit->put(buf,buf.ogGetMaxX()-128,-128);
  blit->put(buf,-128,buf.ogGetMaxY()/2-128);
  blit->put(buf,buf.ogGetMaxX()/2-128,buf.ogGetMaxY()/2-128);
  blit->put(buf,buf.ogGetMaxX()-128,buf.ogGetMaxY()/2-128);
  blit->put(buf,-128,buf.ogGetMaxY()-128);
  blit->put(buf,buf.ogGetMaxX()/2-128,buf.ogGetMaxY()-128);
  blit->put(buf,buf.ogGetMaxX()-128,buf.ogGetMaxY()-128);

  getc(stdin);
  buf.ogClear(0);
  for (yy = 0; yy<=(int32)buf.ogGetMaxY(); yy++)
    for (xx = 0; xx<=(int32)buf.ogGetMaxX(); xx++)
      buf.ogSetPixel(xx,yy,xx*yy);
  blit->getBlitWithMask(buf,
                        buf.ogGetMaxX()/2-blit->getWidth(),
                        buf.ogGetMaxY()/2-blit->getHeight());
  buf.ogClear(0);
  blit->put(buf,-10000,-10000);  // test *really* off the screen
  blit->put(buf,10000,10000);    // test *really* off the screen
  
  blit->put(buf,-128,-128);
  blit->put(buf,buf.ogGetMaxX()/2-128,-128);
  blit->put(buf,buf.ogGetMaxX()-128,-128);
  blit->put(buf,-128,buf.ogGetMaxY()/2-128);
  blit->put(buf,buf.ogGetMaxX()/2-128,buf.ogGetMaxY()/2-128);
  blit->put(buf,buf.ogGetMaxX()-128,buf.ogGetMaxY()/2-128);
  blit->put(buf,-128,buf.ogGetMaxY()-128);
  blit->put(buf,buf.ogGetMaxX()/2-128,buf.ogGetMaxY()-128);
  blit->put(buf,buf.ogGetMaxX()-128,buf.ogGetMaxY()-128);
  
  getc(stdin);
  for (count = 0; count < 1000; count++) {
    blit->put(buf,random() % (buf.ogGetMaxX()+blit->getWidth()) - blit->getWidth(),
                  random() % (buf.ogGetMaxY()+blit->getHeight()) - blit->getHeight());
  } // for
  getc(stdin);
  for (yy = 0; yy<=(int32)buf.ogGetMaxY(); yy++)
    for (xx = 0; xx<=(int32)buf.ogGetMaxX(); xx++)
      buf.ogSetPixel(xx,yy,xx*yy);

  blit->getBlitWithMask(buf,buf.ogGetMaxX()/2,buf.ogGetMaxY()-128);
  buf.ogClear(buf.ogRGB(128,128,128));
  blit->put(buf,buf.ogGetMaxX()/2-128,buf.ogGetMaxY()/2-128);  
  getc(stdin);
  delete blit;
  
  return;
} // testBlit

void
testBlit2(ogSurface & buf) {
  ogBlit * blit = new ogBlit();
  ogSurface * buf2 = new ogSurface();
  ogSurface * blitsource = new ogSurface();
  uInt32 xx,yy,count,colour;
  buf.ogClear(0);
  buf2->ogClone(buf);
  blitsource->ogClone(buf);

  colour = 255;
  for (count = 0; count < (buf2->ogGetMaxX()+1)/2; count+=4) {
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               buf2->ogGetMaxX()/2-count,buf2->ogGetMaxY(),
               buf2->ogRGB(colour,colour,colour));
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               buf2->ogGetMaxX()/2+count,buf2->ogGetMaxY(),
               buf2->ogRGB(colour,colour,colour));
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               buf2->ogGetMaxX()/2-count,0,
               buf2->ogRGB(0,colour,0));
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               buf2->ogGetMaxX()/2+count,0,
               buf2->ogRGB(0,colour,0));
    --colour;
  } // for

  colour = 255;
  for (count = 0; count < (buf.ogGetMaxY()+1)/2; count+=4) {
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               0, buf2->ogGetMaxY()/2-count,
               buf2->ogRGB(colour,0,0));
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               0, buf2->ogGetMaxY()/2+count,
               buf2->ogRGB(colour,0,0));
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               buf2->ogGetMaxX(), buf2->ogGetMaxY()/2-count,
               buf2->ogRGB(0,0,colour));
    buf2->ogLine(buf2->ogGetMaxX()/2, buf2->ogGetMaxY()/2,
               buf2->ogGetMaxX(), buf2->ogGetMaxY()/2+count,
               buf2->ogRGB(0,0,colour));
    --colour;
  } // for
  for (yy = 0; yy<=buf2->ogGetMaxY(); yy++)
    for (xx = 0; xx<=buf2->ogGetMaxX(); xx++)
      buf2->ogSetPixel(xx,yy,xx*yy);
  for (count = 0; count<200; count++)
    blitsource->ogFillCircle(random() % blitsource->ogGetMaxX(), random() % blitsource->ogGetMaxY(),
                             random() % 35+1,blitsource->ogRGB(255,255,255));

  blit->get(*blitsource,0,0,blitsource->ogGetMaxX(),blitsource->ogGetMaxY());
  blit->save("bigblit.blt");
  delete blit;
  blit = new ogBlit;
  blit->load("bigblit.blt");
  for (count = 0; count<=256; count+=4) {
  for (yy = 0; yy<=buf2->ogGetMaxY(); yy++)
    for (xx = 0; xx<=buf2->ogGetMaxX(); xx++)
      buf2->ogSetPixel(xx,yy,xx*yy*count);
  
    blit->getBlitWithMask(*buf2,0,0);
    blit->put(buf,0,0);
  } // for

  getc(stdin);
  delete blitsource;
  delete buf2;
  delete blit;
  return;
} // testBlit2

void
testBlit3(ogSurface & buf) {
  int32 count;
  ogBlit * blit = NULL;
  ogSurface * buf2 = NULL;
  buf2 = new ogSurface();
  blit = new ogBlit();
  buf.ogClear(0);
  buf.ogFillCircle(buf.ogGetMaxX()/2,buf.ogGetMaxY()/2,14,buf.ogRGB(255,255,255));
  blit->get(buf,buf.ogGetMaxX()/2-20,buf.ogGetMaxY()/2-20,
                buf.ogGetMaxX()/2+20,buf.ogGetMaxY()/2+20);
  blit->put(buf,0,0);
  for (count=0; count<(int32)buf.ogGetMaxX(); count++)
    buf.ogLine(count,0,count,buf.ogGetMaxY(),count);
  buf2->ogClone(buf);    
  blit->getBlitWithMask(*buf2,10,10);
  buf.ogClear(buf.ogRGB(63,63,63));
  for (count=-40; count<(int32)buf.ogGetMaxX()+10; count++) {
    blit->getBlitWithMask(*buf2,count,buf2->ogGetMaxY()/2-20);
    blit->put(buf,count,buf.ogGetMaxY()/2-20);
    blit->getBlitWithMask(*buf2,buf2->ogGetMaxX()/2-20,count);
    blit->put(buf,buf.ogGetMaxX()/2-20,count);
   }
  getc(stdin);
  delete blit;
  return;
} // testBlit3

void
testSaveLoadPal(ogSurface & buf) {
  uInt32 count;
  testRect(buf);
  for (count=0; count<256; count++)
    buf.ogSetRGBPalette(count,count,count,count);
  if (buf.ogSavePal("test.pal")==false) cout << "ogSavePal() failed" << endl;
  for (count=0; count<256; count++)
    buf.ogSetRGBPalette(count,0,0,0);
  if (buf.ogLoadPal("test.pal")==false) cout << "ogLoadPal() failed" << endl;
  testRect(buf);
} // testSaveLoadPal

void
testPolygon(ogSurface & buf) {
  ogPoint points[16];
  uInt32 count;
  buf.ogClear(0);
  for (count=0; count<16; count++) {
    points[count].x = random() % buf.ogGetMaxX();
    points[count].y = random() % buf.ogGetMaxY();
  } // for
  buf.ogFillPolygon(16, points, buf.ogRGB(random() & 255,random() & 255,random() & 255));
  getc(stdin);
  return;
} // testPolygon

void
testSpline(ogSurface & buf) {
  ogPoint points[8];
  uInt32 i;
  for (i=0; i<8; i++) {
    points[i].x = random() % buf.ogGetMaxX();
    points[i].y = random() % buf.ogGetMaxY();
  } // for
  buf.ogClear(0);
  buf.ogPolygon(8, points, buf.ogRGB(22,229,52));
  buf.ogSpline(8, points, 24, buf.ogRGB(64,64,255));
  buf.ogBSpline(8, points, 24, buf.ogRGB(255,128,128));
  getchar();
  return;
} // testSpline

int main() {
  ogSurface* buf    = NULL;
//  ogSurface* screen = NULL;
  buf = new ogSurface();
//  screen = new ogDisplay_VESA();
  if (buf->ogCreate(1024,768,OG_PIXFMT_32BPP)==false) exit(1);
//  screen->ogCreate(800,600,OG_PIXFMT_32BPP);
  srandom(time(NULL));
  
cout << "TestRect()" << endl;
  testRect(*buf);
cout << "testCircle()" << endl;
  testCircle(*buf);
cout << "TestLine()" << endl;
  testLine(*buf);
cout << "TestVFlip()" << endl;
  testVFlip(*buf);
cout << "TestHFlip()" << endl;
  testHFlip(*buf);
cout << "TestArc()" << endl;
  testArc(*buf);
cout << "TestSetPixel()" << endl;
  testSetPixel(*buf);
cout << "TestClear()" << endl;
  testClear(*buf);
cout << "TestSprite()" << endl;
  testSprite(*buf);
 cout << "TestBlit()" << endl;
   testBlit(*buf);
// cout << "TestBlit2()" << endl;
//   testBlit2(*buf);
//  testBlit3(*buf);  // special test for 320x200x8bpp
//  testSaveLoadPal(*buf);    // use an 8bpp mode
cout << "TestPolygon()" << endl;
  testPolygon(*buf);
cout << "TestCurve()" << endl;
  testCurve(*buf);
cout << "TestSpline()" << endl;
  testSpline(*buf);
  delete buf;
//  delete screen;
  return(0);
}
