//---------------------------------------------------------------------------

#include <vcl.h>

#include <windows.h>		// Header File For Windows
#include "gl\gl.h"			// Header File For The OpenGL32 Library
#include "gl\glu.h"			// Header File For The GLu32 Library
#include "gl\glaux.h"		// Header File For The Glaux Library

#include <math.h>

#pragma hdrstop

#include "Display.h"
#include "Viewer.h"
#include "MT.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmDisplay *frmDisplay;
//---------------------------------------------------------------------------
void displayCube(TCube *Cube);

//---------------------------------------------------------------------------
__fastcall TfrmDisplay::TfrmDisplay(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TfrmDisplay::FormCreate(TObject *Sender)
{
   GLuint		PixelFormat;

  static	PIXELFORMATDESCRIPTOR pfd =             // pfd tells windows how we want things to be
	{
		sizeof(PIXELFORMATDESCRIPTOR),          // Size of this pixel format descriptor
		1,					// Version number
		PFD_DRAW_TO_WINDOW |			// Format must support window
		PFD_SUPPORT_OPENGL |			// Format must support OpenGL
		PFD_DOUBLEBUFFER,			// Must support double buffering
		PFD_TYPE_RGBA,				// Request an RGBA format
		16,					// Select our color depth
		0, 0, 0, 0, 0, 0,			// Color bits ignored
		0,					// No alpha buffer
		0,					// Shift bit ignored
		0,					// No accumulation buffer
		0, 0, 0, 0,				// Accumulation bits ignored
		32,					// 16Bit Z-Buffer (Depth buffer)
		0,					// No stencil buffer
		0,					// No auxiliary buffer
		PFD_MAIN_PLANE,				// Main drawing layer
		0,					// Reserved
		0, 0, 0					// Layer masks ignored
	};


  this->lookAtX = 0;
  this->lookAtY = 0;
  this->lookAtZ = 1;

  this->posX = 0;
  this->posY = 0;
  this->posZ = -8;


  (PixelFormat = ChoosePixelFormat(this->Canvas->Handle,&pfd));
  SetPixelFormat(this->Canvas->Handle,PixelFormat,&pfd);
  this->hRC = wglCreateContext(this->Canvas->Handle);
  wglMakeCurrent(this->Canvas->Handle,this->hRC);



  InitGL();

}
//---------------------------------------------------------------------------





int TfrmDisplay::InitGL(GLvoid)      // All setup for OpenGL goes here
{


  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);

  GLfloat glfLightAmbient[4] = {0.5f, 0.5f, 0.5f, 0.0f};
	GLfloat glfLightDiffuse[4] = {0.0f, 1.0f, 0.0f, 0.0f};
	GLfloat glfLightSpecular[4] = {0.0, 0.5, 0.5, 1.0f};
	GLfloat PoziceSvetla[4] = {0.0, 0.0, 1.0, 0.0};

  glLightfv(GL_LIGHT0, GL_AMBIENT, glfLightAmbient);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, glfLightSpecular);
  glLightfv(GL_LIGHT0, GL_SPECULAR,glfLightSpecular);
  glLightfv(GL_LIGHT0, GL_POSITION,PoziceSvetla);


  GLfloat ka[4] = {0.0, 0.0, 0.0, 1.0};
  GLfloat kd[4] = {0.8, 0.8, 0.8, 1.0};
  GLfloat ks[4] = {0.2, 0.2, 0.2, 1.0};
  GLint sh[1] = {0.0};




//  glDisable(GL_LIGHT0);
//  glDisable(GL_LIGHT1);
//  glDisable(GL_LIGHT2);
//  glDisable(GL_LIGHT3);
//  glDisable(GL_LIGHT4);
  glEnable(GL_NORMALIZE);
//  glEnable(GL_AUTO_NORMAL);
  GLfloat mlha=0.0;
  //glEnable(GL_FOG);
  //glFogfv(GL_FOG_DENSITY,&mlha);


//  glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, &mlha);

  glEnable(GL_COLOR_MATERIAL);

  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ka);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, kd);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ks);



  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
// GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR

  glPointSize(1.0);

  glEnable(GL_CULL_FACE);
//	glEnable(GL_TEXTURE_2D);						// Enable Texture Mapping ( NEW )
	glShadeModel(GL_FLAT);                // Enable smooth shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);   // Black background
	glClearDepth(1.0f);                     // Depth buffer setup
//	glEnable(GL_DEPTH_TEST);                // Enables depth testing
	glDepthFunc(GL_LEQUAL);                 // The type of depth testing to do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);      // Really nice perspective calculations
	return true;                            // Initialization went OK
}

int TfrmDisplay::DrawGLScene(GLvoid)         // Here's where we do all the drawing
{

  glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// clear screen and depth buffer



	glLoadIdentity();

//  if(flatShading)
//    glShadeModel(GL_FLAT);
//  else
//    glShadeModel(GL_SMOOTH);


  GLfloat PoziceSvetla[4] = {0.0, -1.0, -1.0, 0.0};

  glLightfv(GL_LIGHT0, GL_POSITION, PoziceSvetla);


  glTranslated(this->posX, this->posY, this->posZ);

  double ca = cos((-1) * M_PI * this->alpha / 180.0);
  double sa = sin((-1) * M_PI * this->alpha / 180.0);

//  double cb = cos((-1) * M_PI * this->beta / 180.0);
//  double sb = sin((-1) * M_PI * this->beta / 180.0);

  glRotated(alpha, 1, 0, 0);
  glRotated(beta, 0, ca, sa);




  glColor3f(1.0,1.0,1.0);
  glDisable(GL_LIGHTING);

  try {
    this->DrawProcess();
  }
  catch ( ... ){
  }
//  glEnable(GL_LIGHTING);





//  if(textura)
//	    glEnable(GL_TEXTURE_2D);
//    else
//    	glDisable(GL_TEXTURE_2D);

//    glBindTexture(GL_TEXTURE_2D, Texture[0]);


	return true;            // Everything went OK
}

//---------------------------------------------------------------------------

void __fastcall TfrmDisplay::FormPaint(TObject *Sender)
{
  DrawGLScene();
   SwapBuffers(this->Canvas->Handle);

}
//---------------------------------------------------------------------------



void __fastcall TfrmDisplay::FormDestroy(TObject *Sender)
{
   wglDeleteContext(this->hRC);
}
//---------------------------------------------------------------------------



void __fastcall TfrmDisplay::FormResize(TObject *Sender)
{

  int height=this->Height;
  int width=this->Width;


         if (height == 0)                        // Prevent a divide by zero by
        {
                height = 1;                     // Making height equal One
        }

  glViewport(0, 0, width, height);        // Reset the current viewport


  glMatrixMode(GL_PROJECTION);            // Select the projection matrix
	glLoadIdentity();                       // Reset the projection matrix

	// Calculate the aspect ratio of the window
	gluPerspective(40.0f,(GLfloat)width/(GLfloat)height,1.0,100.0);
//  glFrustum(-10.0, 10.0, 10.0, -10.0 ,1.0, 100.0 );

	glMatrixMode(GL_MODELVIEW);             // Select the modelview matrix
	glLoadIdentity();

  InvalidateRect(this->Handle, NULL, false);
}
//---------------------------------------------------------------------------


void __fastcall TfrmDisplay::FormMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
  if(Button == mbLeft)
  {
    this->startX = X;
    this->startY = Y;
    this->otacanie = true;
  }

  if(Button == mbRight)
  {
    this->startY = Y;
  	this->posuvanie = true;
  }
}
//---------------------------------------------------------------------------

void __fastcall TfrmDisplay::FormMouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
  if(this->otacanie)
  {
  	//sign(X - this->startX);
    this->beta += X - this->startX;
    this->alpha += Y - this->startY;
    this->startX = X;
    this->startY = Y;
    InvalidateRect(this->Handle, NULL, false);
  }

  if(this->posuvanie)
  {
  	this->posX += this->lookAtX * (Y - this->startY) * 0.5;
  	this->posY += this->lookAtY * (Y - this->startY) * 0.5;
	  this->posZ += this->lookAtZ * (Y - this->startY) * 0.5;

    this->startY = Y;

    InvalidateRect(this->Handle, NULL, false);
  }
}
//---------------------------------------------------------------------------

void __fastcall TfrmDisplay::FormMouseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
  if(Button == mbLeft)
  {
    this->otacanie = false;
  }
  if(Button == mbRight)
  {
  	this->posuvanie = false;
  }
}
//---------------------------------------------------------------------------



void __fastcall TfrmDisplay::FormMouseWheelDown(TObject *Sender,
      TShiftState Shift, TPoint &MousePos, bool &Handled)
{
  this->posX += this->lookAtX;
  this->posY += this->lookAtY;
  this->posZ += this->lookAtZ;

  InvalidateRect(this->Handle, NULL, false);
}
//---------------------------------------------------------------------------

void __fastcall TfrmDisplay::FormMouseWheelUp(TObject *Sender,
      TShiftState Shift, TPoint &MousePos, bool &Handled)
{
  this->posX -= this->lookAtX;
  this->posY -= this->lookAtY;
  this->posZ -= this->lookAtZ;

  InvalidateRect(this->Handle, NULL, false);
}
//---------------------------------------------------------------------------

void TfrmDisplay::DrawProcess(){
  int abc = 0;
  
  if(FrmMonitor->chkDrawPatches->Checked){
    for(int i = 0; i < HASHSIZE; i++){
      for(TCubesHash* AC = FrmMonitor->p.FoundCubes[i]; AC != NULL; AC = AC->Next){
        glColor3d(1.0, 0.0, 0.0);
        displayCube(&(AC->Cube.Cube));
      }
    }
  }

  if(FrmMonitor->chkWire->Checked){
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  }
  else {
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }

  if(FrmMonitor->chkSmooth->Checked){
    glShadeModel(GL_SMOOTH);
  }
  else {
    glShadeModel(GL_FLAT);
  }

  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);
  for(TTriangles *AT = FrmMonitor->p.FoundTriangles; AT != NULL; AT = AT->Next){
    glBegin(GL_TRIANGLES);
    for(int i = 0; i < 3; i++){
       glColor3d(0.5, 0.5, 0.5);
       if(AT == FrmMonitor->p.FoundTriangles) glColor3d(1.0, 0.0, 0.0);

      glNormal3d(AT->Triangle.Normals[i]->Normal.X,
                 AT->Triangle.Normals[i]->Normal.Y,
                  AT->Triangle.Normals[i]->Normal.Z);
      glVertex3d(AT->Triangle.Vertices[i]->Point.X,
                 AT->Triangle.Vertices[i]->Point.Y,
                 AT->Triangle.Vertices[i]->Point.Z );

    }
    glEnd();
  }
  glDisable(GL_DEPTH_TEST);
  glDisable(GL_LIGHTING);

//draw active edges
  for(TTriangleEdges *AE = FrmMonitor->p.ActiveEdge; AE != NULL; AE = AE->NextInList){
    glBegin(GL_LINES);

    if(AE->Inactive){
      glColor3d(0.0, 0.0, 1.0);
    }
    else {
      glColor3d(1.0, 1.0, 1.0);
    }

    glVertex3d(AE->Edge.Vertices[0]->Point.X,
               AE->Edge.Vertices[0]->Point.Y,
               AE->Edge.Vertices[0]->Point.Z);
    glVertex3d(AE->Edge.Vertices[1]->Point.X,
               AE->Edge.Vertices[1]->Point.Y,
               AE->Edge.Vertices[1]->Point.Z);
    glEnd();
  }

  glColor3d(0.0, 1.0, 0.0);
  if(FrmMonitor->p.ActiveEdge != NULL){
    glBegin(GL_LINES);
    glVertex3d(FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point.X,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point.Y,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point.Z);
    glVertex3d(FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.X,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Y,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Z);
    glEnd();
    glColor3d(0.5, 1.0, 0.5);
    glBegin(GL_LINES);
    glVertex3d(FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.X - FrmMonitor->p.ActiveEdge->Edge.Normals[1]->Normal.X,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Y - FrmMonitor->p.ActiveEdge->Edge.Normals[1]->Normal.Y,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Z - FrmMonitor->p.ActiveEdge->Edge.Normals[1]->Normal.Z);
    glVertex3d(FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.X,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Y,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Z);
    glEnd();

    glBegin(GL_LINES);
    glColor3d(1.0, 0.0, 1.0);
    glVertex3d(FrmMonitor->p.ActiveEdge->Left->Edge.Vertices[0]->Point.X,
               FrmMonitor->p.ActiveEdge->Left->Edge.Vertices[0]->Point.Y,
               FrmMonitor->p.ActiveEdge->Left->Edge.Vertices[0]->Point.Z);
    glVertex3d(FrmMonitor->p.ActiveEdge->Left->Edge.Vertices[1]->Point.X,
               FrmMonitor->p.ActiveEdge->Left->Edge.Vertices[1]->Point.Y,
               FrmMonitor->p.ActiveEdge->Left->Edge.Vertices[1]->Point.Z);
    glEnd();
    glBegin(GL_LINES);
    glColor3d(1.0, 1.0, 0.0);
    glVertex3d(FrmMonitor->p.ActiveEdge->Right->Edge.Vertices[0]->Point.X,
               FrmMonitor->p.ActiveEdge->Right->Edge.Vertices[0]->Point.Y,
               FrmMonitor->p.ActiveEdge->Right->Edge.Vertices[0]->Point.Z);
    glVertex3d(FrmMonitor->p.ActiveEdge->Right->Edge.Vertices[1]->Point.X,
               FrmMonitor->p.ActiveEdge->Right->Edge.Vertices[1]->Point.Y,
               FrmMonitor->p.ActiveEdge->Right->Edge.Vertices[1]->Point.Z);

    glEnd();
  }

  glColor3d(0.5, 0.5, 1.0);
  if(FrmMonitor->p.ActiveEdge != NULL){
  for(TPatch *Patch = FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Patch;;){
    TPatch *NextPatch;
    glBegin(GL_LINES);
    glVertex3d(Patch->CubeEdge->Intersection.X,
              Patch->CubeEdge->Intersection.Y,
              Patch->CubeEdge->Intersection.Z);

    FindNextPatchEdge(&(FrmMonitor->p),
                       Patch,
                       &NextPatch);
    Patch = NextPatch;
    glVertex3d(Patch->CubeEdge->Intersection.X,
              Patch->CubeEdge->Intersection.Y,
              Patch->CubeEdge->Intersection.Z);
    glEnd();
    if(Patch == FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Patch) break;
  }
  }

  if(FrmMonitor->chkNormals->Checked){
  glColor3d(1.0, 1.0, 1.0);
  for(TTriangles *AT = FrmMonitor->p.FoundTriangles; AT != NULL; AT = AT->Next){
    for(int i = 0; i < 3; i++){
      glBegin(GL_LINES);
       glColor3d(0.5, 1.0, 0.5);
       glVertex3d(AT->Triangle.Vertices[i]->Point.X - (0.1) * AT->Triangle.Normals[i]->Normal.X,
                 AT->Triangle.Vertices[i]->Point.Y - (0.1) * AT->Triangle.Normals[i]->Normal.Y,
                 AT->Triangle.Vertices[i]->Point.Z - (0.1) * AT->Triangle.Normals[i]->Normal.Z);
      glVertex3d(AT->Triangle.Vertices[i]->Point.X,
                 AT->Triangle.Vertices[i]->Point.Y,
                 AT->Triangle.Vertices[i]->Point.Z );
      glEnd();
    }

  }
  }

  if(FrmMonitor->p.FoundTriangles != NULL){
  glColor3d(1.0, 1.0, 1.0);

  glBegin(GL_LINES);
   glVertex3d(FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Point.X,
               FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Point.Y,
               FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Point.Z);
   glVertex3d(FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Point.X - FrmMonitor->p.FoundTriangles->Triangle.Normals[2]->Normal.X,
               FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Point.Y - FrmMonitor->p.FoundTriangles->Triangle.Normals[2]->Normal.Y,
               FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Point.Z - FrmMonitor->p.FoundTriangles->Triangle.Normals[2]->Normal.Z);

  glEnd();

  glColor3d(0.7, 0.5, 0.3);

  for(TPatch *Patch = FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Patch;;){
    TPatch *NextPatch;
    glBegin(GL_LINES);
    glVertex3d(Patch->CubeEdge->Intersection.X,
              Patch->CubeEdge->Intersection.Y,
              Patch->CubeEdge->Intersection.Z);

    FindNextPatchEdge(&(FrmMonitor->p),
                       Patch,
                       &NextPatch);
    Patch = NextPatch;
    glVertex3d(Patch->CubeEdge->Intersection.X,
              Patch->CubeEdge->Intersection.Y,
              Patch->CubeEdge->Intersection.Z);
    glEnd();
    if(Patch == FrmMonitor->p.FoundTriangles->Triangle.Vertices[2]->Patch) break;
  }

  }

  glColor3d(0.2, 0.9, 0.2);
  if(FrmMonitor->p.ActiveEdge != NULL){
  for(TPatch *Patch = FrmMonitor->p.ActiveEdge->Edge.Patch;Patch != NULL;){
    TPatch *NextPatch;
    glBegin(GL_LINES);
    glVertex3d(Patch->CubeEdge->Intersection.X,
              Patch->CubeEdge->Intersection.Y,
              Patch->CubeEdge->Intersection.Z);

    FindNextPatchEdge(&(FrmMonitor->p),
                       Patch,
                       &NextPatch);
    Patch = NextPatch;
    glVertex3d(Patch->CubeEdge->Intersection.X,
              Patch->CubeEdge->Intersection.Y,
              Patch->CubeEdge->Intersection.Z);
    glEnd();
    if(Patch == FrmMonitor->p.ActiveEdge->Edge.Patch) break;
  }
  }

  if((FrmMonitor->p.NewVertex != NULL) && (FrmMonitor->p.ActiveEdge != NULL)){


    double a2 = (FrmMonitor->p.NewVertex->Point - FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point)
              * (FrmMonitor->p.NewVertex->Point - FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point);
    double b2 = (FrmMonitor->p.NewVertex->Point - FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point)
              * (FrmMonitor->p.NewVertex->Point - FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point);
    double c2 = (FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point - FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point)
                * (FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point - FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point);

    T3DPoint Center = (  (a2 *(b2 + c2 - a2)) * FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point
            + (b2 *(a2 + c2 - b2)) * FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point
            + (c2 *(a2 + b2 - c2)) * FrmMonitor->p.NewVertex->Point )
        / (2*(a2 * b2 + a2*c2 + b2*c2) - (a2*a2 + b2*b2 + c2*c2)) ;
    double diam = sqrt((Center - FrmMonitor->p.NewVertex->Point)
                * (Center - FrmMonitor->p.NewVertex->Point));

    GLUquadricObj* sphere1 = gluNewQuadric();
    GLUquadricObj* sphere2 = gluNewQuadric();

    glColor3d(1.0, 0.5, 0.5);
    glBegin(GL_TRIANGLES);
    glVertex3d(FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.X,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Y,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[1]->Point.Z);
    glVertex3d(FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point.X,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point.Y,
               FrmMonitor->p.ActiveEdge->Edge.Vertices[0]->Point.Z);
    glVertex3d(FrmMonitor->p.NewVertex->Point.X,
               FrmMonitor->p.NewVertex->Point.Y,
               FrmMonitor->p.NewVertex->Point.Z);
    glEnd();

    glEnable(GL_DEPTH_TEST);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glPushMatrix();
    glTranslatef(Center.X, Center.Y, Center.Z);
    glColor4f(0.0, 1.0, 0.0, 0.3);
    gluSphere(sphere1, diam, 10, 10);
    glColor4f(0.0, 0.0, 1.0, 0.3);
    gluSphere(sphere1, diam * 1.5, 10, 10);
    glPopMatrix();
    glDisable(GL_DEPTH_TEST);

    if(FrmMonitor->chkWire->Checked){
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  }
  else {
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }



  }

/**  if(FrmMonitor->chkNormals->Checked){

    for(TTriangles *AT = FrmMonitor->p.FoundTriangles; AT != NULL; AT = AT->Next){
      for(int i = 0; i < 3; i++){
        glBegin(GL_LINES);
        glColor3d(0.5, 1.0, 0.5);
        glVertex3d(AT->Triangle.Vertices[i]->Point.X - (0.1) * AT->Triangle.Normals[i]->Normal.X,
                 AT->Triangle.Vertices[i]->Point.Y - (0.1) * AT->Triangle.Normals[i]->Normal.Y,
                 AT->Triangle.Vertices[i]->Point.Z - (0.1) * AT->Triangle.Normals[i]->Normal.Z);
        glVertex3d(AT->Triangle.Vertices[i]->Point.X,
                 AT->Triangle.Vertices[i]->Point.Y,
                 AT->Triangle.Vertices[i]->Point.Z );
        glEnd();
      }
    }
  }       /**/



}
//---------------------------------------------------------------------------
void displayCube(TCube *Cube){
/**
  glEnable(GL_DEPTH_TEST);
  if(Cube->Subdivide && (Cube->Children[0] != NULL ) && Cube->SubdivisionLevel < 4){
    for(int i = 0; i < 8; i++){
      displayCube(&(Cube->Children[i]->Cube));
    }
  } else {
//    if((Cube->Configuration != 255) && (Cube->Configuration != 0) ){
      if(Cube->SubdivisionLevel < 3) return;
      glColor3d(1.0 - IS_RIGHT(Cube->SubdivisionLevel),
            1.0 - IS_TOP(Cube->SubdivisionLevel),
            1.0 - IS_FRONT(Cube->SubdivisionLevel) );
      if(Cube->Subdivide){
          glColor3d(0.0, 1.0, 0.0);
        }
      for(int i = 0; i < 6; i++){
        glBegin(GL_QUADS);
        for(int j = 0; j < 4; j++){
          glVertex3d(Cube->Vertices[DIR_VERTICES[i][3-j]]->Index.I * FrmMonitor->p.Config.STEP,
                    Cube->Vertices[DIR_VERTICES[i][3-j]]->Index.J * FrmMonitor->p.Config.STEP,
                    Cube->Vertices[DIR_VERTICES[i][3-j]]->Index.K * FrmMonitor->p.Config.STEP);
        }
        glEnd();
      }
 //   }
  }
/**/



  if(Cube->Subdivide && (Cube->Children[0] != NULL )){
    for(int i = 0; i < 8; i++){
      displayCube(&(Cube->Children[i]->Cube));
    }
  } else {
//    if(Cube->SubdivisionLevel > 3) return;
//    if() return;
    glColor3d(1.0 - IS_RIGHT(Cube->SubdivisionLevel),
            1.0 - IS_TOP(Cube->SubdivisionLevel),
            1.0 - IS_FRONT(Cube->SubdivisionLevel) );

    for(int j = 0; j < 12; j++){
      if((Cube->Edges[j] != NULL) && (Cube->Edges[j]->Subdivide == 0)){
        if(Cube->Edges[j]->Subdivide){
//          glColor3d(0.0, 1.0, 0.0);
        }
        for(int neighbour = 0; neighbour < 4; neighbour++){
          if(Cube->Edges[j]->Neighbours[neighbour] != NULL){
/**/            glBegin(GL_LINES);
            glVertex3d(Cube->Edges[j]->Intersection.X,
              Cube->Edges[j]->Intersection.Y,
              Cube->Edges[j]->Intersection.Z);
            glVertex3d(Cube->Edges[j]->Neighbours[neighbour]->Intersection.X,
              Cube->Edges[j]->Neighbours[neighbour]->Intersection.Y,
              Cube->Edges[j]->Neighbours[neighbour]->Intersection.Z);
            glEnd();   /**/
          }
        }
      }
    }
  }
}

//---------------------------------------------------------------------------
