/*************************************************************************
 * Copyright (c) 2011 AT&T Intellectual Property 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors: Details at https://graphviz.org
 *************************************************************************/

#include "config.h"

#include "glexpose.h"
#include "draw.h"
#include "topviewfuncs.h"
#include <glcomp/glutils.h>
#include "topfisheyeview.h"
#include "gui/toolboxcallbacks.h"
#include "arcball.h"
#include "hotkeymap.h"
#include "polytess.h"
#include <stdbool.h>
#include <stdint.h>

static void drawRotatingAxis(void)
{
    static GLUquadricObj *quadratic;
    float AL = 45;

    if (get_mode(view) != MM_ROTATE)
	    return;

    if (!quadratic) {
	quadratic = gluNewQuadric();	// Create A Pointer To The Quadric Object
	gluQuadricNormals(quadratic, GLU_SMOOTH);	// Create Smooth Normals
	gluQuadricDrawStyle(quadratic, GLU_LINE);


    }

	glPushMatrix();
	glLoadIdentity();
	glMultMatrixd(view->arcball->Transform.M);	/*arcball transformations , experimental */
	glLineWidth(3);
	glBegin(GL_LINES);
	glColor3f(1, 1, 0);

	glVertex3f(0, 0, 0);
	glVertex3f(0, AL, 0);

	glVertex3f(0, 0, 0);
	glVertex3f(AL, 0, 0);

	glVertex3f(0, 0, 0);
	glVertex3f(0, 0, AL);

	glEnd();
	glColor4f(0, 1, 0, 0.3f);
	gluSphere(quadratic, AL, 20, 20);
	glLineWidth(1);
	glPopMatrix();


}



/*
	refreshes camera settings using view parameters such as pan zoom etc
	if a camera is selected viewport is switched to 3D
	params:ViewInfo	, global view variable defined in viewport.c
	return value:always 1
*/
static int glupdatecamera(ViewInfo * vi)
{
    if (vi->active_camera == SIZE_MAX)
	glTranslated(-vi->panx, -vi->pany, 0);


    /*toggle to active camera */
    else {
	glMultMatrixd(vi->arcball->Transform.M);	/*arcball transformations , experimental */
	glTranslated(-vi->cameras[vi->active_camera]->targetx,
		     -vi->cameras[vi->active_camera]->targety, 0);
    }
    vi->clipX1=0;
    vi->clipX2=0;
    vi->clipY1=0;
    vi->clipY2=0;
    GetOGLPosRef(1, vi->h - 5, &vi->clipX1, &vi->clipY1);
    GetOGLPosRef(vi->w - 1, 1, &vi->clipX2, &vi->clipY2);

    if (vi->active_camera == SIZE_MAX) {
	glScaled(1 / vi->zoom * -1, 1 / vi->zoom * -1, 1 / vi->zoom * -1);
    } else {
	glScaled(1 / vi->cameras[vi->active_camera]->r,
		 1 / vi->cameras[vi->active_camera]->r,
		 1 / vi->cameras[vi->active_camera]->r);
    }


    return 1;
}

/*
	draws grid (little dots , with no use)
	params:ViewInfo	, global view variable defined in viewport.c
	return value:none
*/
static void glexpose_grid(ViewInfo * vi)
{
    //drawing grids
    if (vi->gridVisible) {
	glPointSize(1);
	glBegin(GL_POINTS);
	glColor4d(vi->gridColor.R, vi->gridColor.G, vi->gridColor.B,
		  vi->gridColor.A);
	for (double x = vi->bdxLeft; x <= vi->bdxRight; x += vi->gridSize) {
	    for (double y = vi->bdyBottom; y <= vi->bdyTop; y += vi->gridSize) {
		glVertex3d(x, y, 0);
	    }
	}
	glEnd();
    }
}

/*
	draws active graph depending on graph type
	params:ViewInfo	, global view variable defined in viewport.c
	return value:1 if there is a graph to draw else 0 
*/
static int glexpose_drawgraph(ViewInfo * vi)
{

    if (vi->activeGraph > -1) {
	if (!vi->Topview->fisheyeParams.active)
	    renderSmGraph(vi->Topview);
	else {
	    drawtopologicalfisheye(vi->Topview);
	}

	return 1;
    }
    return 0;
}

int glexpose_main(ViewInfo * vi)
{
    static bool doonce;
    if (!glupdatecamera(vi))
	return 0;

    if (vi->activeGraph >= 0) {
	if (!doonce) {
	    doonce = true;
	    btnToolZoomFit_clicked(NULL, NULL);
	    btnToolZoomFit_clicked(NULL, NULL);
	}
    }
    else
	return 0;



    glexpose_grid(vi);
    drawBorders(vi);
    glexpose_drawgraph(vi);
    drawRotatingAxis();
    draw_selpoly(&vi->Topview->sel.selPoly);
    glCompSetDraw(vi->widgets);

	 /*DEBUG*/ return 1;
}
