#include <gpk_std.h>
#include <stdio.h>
#include "../box.h"
#include <math.h>
#include <assert.h>

#define GR

#ifdef GR
#include <graphics.h>
#define G	if(1)
#define T	if(0)
#else
#define G	if(0)
#define T	if(1)
#endif

LOCAL C vector_space S1("one");
LOCAL C vector_space S2("two");

#ifdef GR
int scale(double x)
{
 return (int)(x*100+200);
}

void drawline(C vector2& a, C vector2& b, int cell, GrRegion *p)
{
 C int maxy = p->MaxY();
 p->Line(scale(a(0)), maxy-scale(a(1)), scale(b(0)), maxy-scale(b(1)), cell);
}

void axes(GrRegion *p)
{
 drawline(vector2(-1,0), vector2(1,0), GrWhite(), p);
 drawline(vector2(0, -1), vector2(0, 1), GrWhite(), p);
}

void draw(C parallelogram& p, GrRegion *rg)
{
 static int r=128, g=12, b=55;
 C int cell = GrAllocColor(r, g, b);
 r = (2*r+17+g)%256;
 g = (3*g+19+b)%256;
 b = (5*b+23+r)%256;

 drawline(p.c(0), p.c(1), cell, rg);
 drawline(p.c(1), p.c(2), cell, rg);
 drawline(p.c(2), p.c(3), cell, rg);
 drawline(p.c(3), p.c(0), cell, rg);
 getkey();
}

#endif

main()
{
#ifdef GR
 GrSetMode(GR_default_graphics);
 GrRegion *one = GrScreenRegion()->SubRegion(0, 0, 400, 400);
 GrRegion *two = GrScreenRegion()->SubRegion(400, 0, 400, 400);
 axes(one);
 axes(two);
#endif
 box a = box::unitbox + vector2(2,2, &S1);
 ltransform i = ltransform::identity();
 parallelogram b(i, a);
 box c = b.insidebox();
 box d = c-vector2(2,2);
 T printf("ib:%g %g %g %g\n", d.c00()(0), d.c00()(1), d.c11()(0), d.c11()(1));

 {
 T printf("#\n");
 C ltransform lt(vector2(0,0,&S1), vector2(0,0,&S2),
 						matrix22::rotation(M_PI/4.3));
 parallelogram x(lt, box::unitbox);
#ifdef GR
 G draw(x, one);
 G draw(box::unitbox, two);
#endif
 T printf("%g %g  %g %g  %g %g  %g %g\n", x.c00()(0), x.c00()(1),
			x.c01()(0), x.c01()(1), x.c10()(0), x.c10()(1),
 			x.c11()(0), x.c11()(1));
 box y = x.insidebox();
 assert(y.c00().space() == &S2);
 T printf("ib:%g %g %g %g\n", y.c00()(0), y.c00()(1), y.c11()(0), y.c11()(1));
 C parallelogram back(inverse(lt), y);
 T printf("bk:(%g %g)  (%g %g)  (%g %g)  (%g %g)\n",
 			back.c00()(0), back.c00()(1),
			back.c01()(0), back.c01()(1), back.c10()(0), back.c10()(1),
 			back.c11()(0), back.c11()(1));
 C parallelogram ub = inverse(lt)*x;
 assert(ub.c00().space() == &S1);
#ifdef GR
 G draw(y, one);
 G draw(back, two);
 G draw(ub, two);
#endif
 T printf("ub:(%g %g)  (%g %g)  (%g %g)  (%g %g)\n",
 			ub.c00()(0), ub.c00()(1),
			ub.c01()(0), ub.c01()(1), ub.c10()(0), ub.c10()(1),
 			ub.c11()(0), ub.c11()(1));
}

 G getkey();
 {
 T printf("#\n");
 C ltransform lt(matrix22::rotation(M_PI/8), vector2(0.2, 0.3));
 parallelogram x(lt, box::unitbox);
#ifdef GR
 G draw(x, one);
 G draw(box::unitbox, two);
#endif
 T printf("%g %g  %g %g  %g %g  %g %g\n", x.c00()(0), x.c00()(1),
			x.c01()(0), x.c01()(1), x.c10()(0), x.c10()(1),
 			x.c11()(0), x.c11()(1));
 box y = x.insidebox();
 T printf("ib:%g %g %g %g\n", y.c00()(0), y.c00()(1), y.c11()(0), y.c11()(1));
 C parallelogram back(inverse(lt), y);
 T printf("bk:(%g %g)  (%g %g)  (%g %g)  (%g %g)\n",
 			back.c00()(0), back.c00()(1),
			back.c01()(0), back.c01()(1), back.c10()(0), back.c10()(1),
 			back.c11()(0), back.c11()(1));
 C parallelogram ub = inverse(lt)*x;
#ifdef GR
 G draw(y, one);
 G draw(back, two);
 G draw(ub, two);
#endif
 T printf("ub:(%g %g)  (%g %g)  (%g %g)  (%g %g)\n",
 			ub.c00()(0), ub.c00()(1),
			ub.c01()(0), ub.c01()(1), ub.c10()(0), ub.c10()(1),
 			ub.c11()(0), ub.c11()(1));
}
 G getkey();
 G GrSetMode(GR_default_text);
}
