/*****************************************************************************
*   An SGI 4D driver using Open GL.					     *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Gershon Elber			     Ver 0.1, October 1994.  *
*****************************************************************************/

#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/DialogS.h>
#include <GL/GLwMDrawA.h>
#include <GL/glu.h>
#include <GL/gl.h>

#include "irit_sm.h"
#include "genmat.h"
#include "iritprsr.h"
#include "allocate.h"
#include "attribut.h"
#include "iritgrap.h"
#include "xmtdrvs.h"

/* Handle the positional as well as possible RGB attribute of a vertex. */
#define HANDLE_VERTEX(V) { char *Str; \
			   int Color[3]; \
			   if ((Str = AttrGetStrAttrib((V) -> Attrs, \
						       "RGB")) != NULL && \
			       sscanf(Str, "%d,%d,%d", \
				      &Color[0], &Color[1], &Color[2]) == 3) {\
			       glColor3b(Color[0] >> 1, \
					 Color[1] >> 1, \
					 Color[2] >> 1); \
			   } \
			   glVertex3dv((V) -> Coord); \
			 }
#define INVALID_WIDGET	((Widget) -1)

typedef enum {
    GLXcolorIndexSingleBuffer,
    GLXcolorIndexDoubleBuffer,
    GLXrgbSingleBuffer,
    GLXrgbDoubleBuffer
} GLXWindowType;

static GLXContext GlxContext;
static Widget
    ViewWidget = INVALID_WIDGET;

static short Colors[IG_MAX_COLOR + 1][3] =
{
    { 0,   0,   0   },  /* 0. BLACK */
    { 0,   0,   170 },  /* 1. BLUE */
    { 0,   170, 0   },  /* 2. GREEN */
    { 0,   170, 170 },  /* 3. CYAN */
    { 170, 0,   0   },  /* 4. RED */
    { 170, 0,   170 },  /* 5. MAGENTA */
    { 170, 170, 0   },  /* 6. BROWN */
    { 170, 170, 170 },  /* 7. LIGHTGREY */
    { 85,  85,  85  },  /* 8. DARKGRAY */
    { 85,  85,  255 },  /* 9. LIGHTBLUE */
    { 85,  255, 85  },  /* 10. LIGHTGREEN */
    { 85,  255, 255 },  /* 11. LIGHTCYAN */
    { 255, 85,  85  },  /* 12. LIGHTRED */
    { 255, 85,  255 },  /* 13. LIGHTMAGENTA */
    { 255, 255, 85  },  /* 14. YELLOW */
    { 255, 255, 255 }   /* 15. WHITE */
};

static void SetColorRGB(int Color[3]);
static void SetColorIndex(int c);
static void ViewInput(Widget w, XtPointer p1, XtPointer p2);
static void ViewExpose(Widget w, XtPointer ClientData, XtPointer Call);
static void ViewInitWindow(Widget w, XtPointer p1, XtPointer p2);
static void ViewObject(IPObjectStruct *PObj, MatrixType Mat);

/*****************************************************************************
* DESCRIPTION:                                                               M
* Draw a single Point/Vector object using current modes and transformations. M
*                                                                            *
* PARAMETERS:                                                                M
*   PObj:     A point/vector object to draw.                                 M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGDrawPtVec                                                              M
*****************************************************************************/
void IGDrawPtVec(IPObjectStruct *PObj)
{
    int i;
    PointType Ends[6], Zero;
    RealType
	*Pt = PObj -> U.Pt;

    for (i = 0; i < 6; i++)
	PT_COPY(Ends[i], Pt);

    Ends[0][0] -= IGGlblPointWidth;
    Ends[1][0] += IGGlblPointWidth;
    Ends[2][1] -= IGGlblPointWidth;
    Ends[3][1] += IGGlblPointWidth;
    Ends[4][2] -= IGGlblPointWidth;
    Ends[5][2] += IGGlblPointWidth;

    for (i = 0; i < 6; i += 2) {
	glBegin(GL_LINE_STRIP);
	glVertex3dv(Ends[i]);
	glVertex3dv(Ends[i+1]);
	glEnd();
    }

    if (IP_IS_VEC_OBJ(PObj)) {
	glBegin(GL_LINE_STRIP);
	glVertex3dv(Pt);
	Zero[0] = Zero[1] = Zero[2] = 0.0;
	glVertex3dv(Zero);
	glEnd();
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Draw a single Poly object using current modes and transformations.	     M
*                                                                            *
* PARAMETERS:                                                                M
*   PObj:     A poly object to draw.                                         M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGDrawPoly                                                               M
*****************************************************************************/
void IGDrawPoly(IPObjectStruct *PObj)
{
    IPVertexStruct *V;
    IPPolygonStruct
	*Pl = PObj -> U.Pl;

    if (IP_IS_POLYLINE_OBJ(PObj)) {
	for (; Pl != NULL; Pl = Pl -> Pnext) {
	    glBegin(GL_LINE_STRIP);
	    for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
		HANDLE_VERTEX(V);
	    }
	    glEnd();
	}
    }
    else if (IP_IS_POINTLIST_OBJ(PObj)) {
	for (; Pl != NULL; Pl = Pl -> Pnext) {
	    for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
		int i;
		PointType Ends[6];
		RealType
		    *Pt = V -> Coord;

		for (i = 0; i < 6; i++)
		    PT_COPY(Ends[i], Pt);

		Ends[0][0] -= IGGlblPointWidth;
		Ends[1][0] += IGGlblPointWidth;
		Ends[2][1] -= IGGlblPointWidth;
		Ends[3][1] += IGGlblPointWidth;
		Ends[4][2] -= IGGlblPointWidth;
		Ends[5][2] += IGGlblPointWidth;

		for (i = 0; i < 6; i += 2) {
		    glBegin(GL_LINE_STRIP);
		    glVertex3dv(Ends[i]);
		    glVertex3dv(Ends[i+1]);
		    glEnd();
		}
	    }
	}
    }
    else if (IP_IS_POLYGON_OBJ(PObj)) {
	int i, j,
	    NumOfVertices;
	PointType PNormal, VNormal;

	for (; Pl != NULL; Pl = Pl -> Pnext) {
	    if (IGGlblBackFaceCull) {
	        RealType P1[3], P2[3];

		MatMultVecby4by4(P1, Pl -> PVertex -> Coord,
				 IritPrsrViewMat);
		PT_ADD(PNormal, Pl -> PVertex -> Coord, Pl -> Plane);
		MatMultVecby4by4(P2, PNormal, IritPrsrViewMat);
		if (P2[2] - P1[2] > 0.0)
		    continue;
	    }

	    if (IGGlblDrawPNormal) {
		NumOfVertices = 0;
		PNormal[0] = PNormal[1] = PNormal[2] = 0.0;
	    }

	    if (IGGlblDrawSolid) {
		glBegin(GL_POLYGON);
		for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
		    float n[3];

		    switch (IGGlblShadingModel) {
			case IG_SHADING_NONE:
			    break;
			case IG_SHADING_FLAT:
			    n[0] = -Pl -> Plane[0];
			    n[1] = -Pl -> Plane[1];
			    n[2] = -Pl -> Plane[2];
			    glNormal3fv(n);
			    break;
			case IG_SHADING_GOURAUD:
			case IG_SHADING_PHONG:
			    n[0] = -V -> Normal[0];
			    n[1] = -V -> Normal[1];
			    n[2] = -V -> Normal[2];
			    glNormal3fv(n);
			    break;
		    }

		    HANDLE_VERTEX(V);

		    if (IGGlblDrawPNormal) {
			for (j = 0; j < 3; j++)
			    PNormal[j] += V -> Coord[j];
			NumOfVertices++;
		    }
		}
		glEnd();
	    }
	    else {
		glBegin(GL_LINE_STRIP);
		for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
		    HANDLE_VERTEX(V);

		    if (IP_IS_INTERNAL_VRTX(V) && !IGGlblDrawInternal) {
			glEnd();
			glBegin(GL_LINE_STRIP);
		    }

		    if (IGGlblDrawPNormal) {
			for (j = 0; j < 3; j++)
			    PNormal[j] += V -> Coord[j];
			NumOfVertices++;
		    }
		}
		HANDLE_VERTEX(Pl -> PVertex);
		glEnd();
	    }

	    if (IGGlblDrawPNormal && IP_HAS_PLANE_POLY(Pl)) {
		glBegin(GL_LINES);
		for (i = 0; i < 3; i++)
		    PNormal[i] /= NumOfVertices;
		glVertex3dv(PNormal);
		for (i = 0; i < 3; i++)
		    PNormal[i] += Pl -> Plane[i] * IGGlblNormalLen;
		glVertex3dv(PNormal);
		glEnd();
	    }

	    if (IGGlblDrawVNormal) {
		for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
		    if (IP_HAS_NORMAL_VRTX(V)) {
			for (j = 0; j < 3; j++)
			    VNormal[j] = V -> Coord[j] +
				         V -> Normal[j] * IGGlblNormalLen;
			glBegin(GL_LINE_STRIP);
			glVertex3dv(V ->Coord);
			glVertex3dv(VNormal);
			glEnd();
		    }
		}
	    }
	}
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Sets the color of an object according to its color/rgb attributes.	     M
*   If object has an RGB attribute it will be used. Otherwise, if the object M
* has a COLOR attribute it will use. Otherwise, WHITE will be used.	     M
*                                                                            *
* PARAMETERS:                                                                M
*   PObj:      To set the drawing color to its color.                        M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGSetColorObj                                                            M
*****************************************************************************/
void IGSetColorObj(IPObjectStruct *PObj)
{
    int c, Color[3];

    if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
	SetColorRGB(Color);
    }
    else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
	SetColorIndex(c);
    }
    else {
	/* Use white as default color: */
	SetColorIndex(IG_IRIT_WHITE);
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Sets the line width to draw the given object, in pixels.		     M
*                                                                            *
* PARAMETERS:                                                                M
*   Width:    In pixels of lines to draw with.                               M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGSetWidthObj                                                            M
*****************************************************************************/
void IGSetWidthObj(int Width)
{
    glLineWidth((GLfloat) Width);
}

/*****************************************************************************
* DESCRIPTION:                                                               *
* Sets the color according to the given color index.		    	     *
*                                                                            *
* PARAMETERS:                                                                *
*   color:     Index of color to use. Must be between 0 and IG_MAX_COLOR.    *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void SetColorIndex(int color)
{
    int Color[3];

    if (color < 0 || color > IG_MAX_COLOR)
        color = IG_IRIT_WHITE;

    Color[0] = Colors[color][0];
    Color[1] = Colors[color][1];
    Color[2] = Colors[color][2];

    SetColorRGB(Color);
}

/*****************************************************************************
* DESCRIPTION:                                                               *
* Sets the color according to the given RGB values.			     *
*                                                                            *
* PARAMETERS:                                                                *
*   Color:      An RGB vector of integer values between 0 and 255.           *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void SetColorRGB(int Color[3])
{
    int i;

    if (IGGlblDrawSolid) {
	GLfloat MatAmbient[4], MatDiffuse[4], MatSpecular[4];
	static GLfloat
	    MatShininess[] = { 50.0 };

	for (i = 0; i < 3; i++) {
	    MatAmbient[i] = 0.2 * Color[0] / 255.0;
	    MatDiffuse[i] = 0.4 * Color[i] / 255.0;
	    MatSpecular[i] = Color[i] / 255.0;
	}
	MatAmbient[3] = MatDiffuse[3] = MatSpecular[3] = 1.0;

	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MatAmbient);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MatDiffuse);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, MatSpecular);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, MatShininess);
    }
    else
	glColor3f(Color[0] / 255.0, Color[1] / 255.0, Color[2] / 255.0);
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Call back function for handling mouse input.                             *
*                                                                            *
* PARAMETERS:                                                                *
*   w, ClientData, Call:  Parameters of call back function.                  *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void ViewInput(Widget w, XtPointer ClientData, XtPointer Call)
{
    static int
	LastButton = -1,
	LastX = -1,
	LastY = -1;
    GLwDrawingAreaCallbackStruct
	*CallData = (GLwDrawingAreaCallbackStruct *) Call;
    RealType ChangeFactor[2];

    switch (CallData -> event -> type) {
	case MotionNotify:
	    if (LastButton < 0)
	        break;

	    if (CallData -> event -> xbutton.x != LastX ||
		CallData -> event -> xbutton.y != LastY) {
		ChangeFactor[0] = (CallData -> event -> xbutton.x - LastX)
							* IGGlblChangeFactor;
		ChangeFactor[1] = (LastY - CallData -> event -> xbutton.y)
							* IGGlblChangeFactor;
		LastX = CallData -> event -> xbutton.x;
		LastY = CallData -> event -> xbutton.y;

		if (IGProcessEvent(LastButton == 1 ? IG_EVENT_ROTATE
						   : IG_EVENT_TRANSLATE,
				   ChangeFactor))
		    IGRedrawViewWindow();
	    }
	    break;
	case ButtonPress:
	    switch (CallData -> event -> xbutton.button) {
		case Button1:
		case Button3:
		    LastButton = CallData -> event -> xbutton.button;
		    LastX = CallData -> event -> xbutton.x;
		    LastY = CallData -> event -> xbutton.y;
		    break;
	    }
	    break;
	case ButtonRelease:
	    LastButton = -1;
	    break;
	default:
	    break;
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Call back function for handling expose events.                           *
*                                                                            *
* PARAMETERS:                                                                *
*   w, ClientData, Call:  Parameters of call back function.                  *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void ViewExpose(Widget w, XtPointer ClientData, XtPointer Call)
{
    GLwDrawingAreaCallbackStruct
	*CallData = (GLwDrawingAreaCallbackStruct *) Call;

    GLwDrawingAreaMakeCurrent(w, GlxContext);

    ViewWidth = CallData -> width;
    ViewHeight = CallData -> height;

    if (ViewWidth > ViewHeight) {
	int i = (ViewWidth - ViewHeight) / 2;

	glViewport(0, -i, ViewWidth, ViewWidth);
    }
    else {
	int i = (ViewHeight - ViewWidth) / 2;

	glViewport(-i, 0, ViewHeight, ViewHeight);
    }

    IGRedrawViewWindow();
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Call back function for handling initialization of view window.           *
*                                                                            *
* PARAMETERS:                                                                *
*   w, p1, p2:  Parameters of call back function                             *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void ViewInitWindow(Widget w, XtPointer p1, XtPointer p2)
{
    Arg args[1];
    XVisualInfo *Vi;

    XtSetArg(args[0], GLwNvisualInfo, &Vi);
    XtGetValues(w, args, 1);
    GlxContext = glXCreateContext(XtDisplay(w), Vi, 0, GL_FALSE);

    ViewWidget = w;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Sets up a view window.						     M
*                                                                            *
* PARAMETERS:                                                                M
*   argc, argv:   Command line,                                              M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   SetViewWindow                                                            M
*****************************************************************************/
void SetViewWindow(int argc, char **argv)
{
     Arg args[20];
     int n;
     Widget Form, Glw;

     n = 0;
     Form = XmCreateFormDialog(MainTransForm, "view", args, n);
     XtManageChild(Form);

     n = 0;
     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);    n++;
     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM);   n++;
     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
     Glw = GLwCreateMDrawingArea(Form, "glwidget", args, n);
     XtVaSetValues(Glw,
		   XmNdefaultPosition, TRUE,
		   XmNwidth,           ViewWidth,
		   XmNheight,          ViewHeight,
		   NULL); 

     XtAddCallback(Glw, GLwNexposeCallback, ViewExpose, (XtPointer) NULL);
     XtAddCallback(Glw, GLwNresizeCallback, ViewExpose, (XtPointer) NULL);
     XtAddCallback(Glw, GLwNginitCallback, ViewInitWindow, (XtPointer) NULL);
     XtAddCallback(Glw, GLwNinputCallback, ViewInput, (XtPointer) NULL);

     XtManageChild(Glw);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Redraw the view window.                                                  M
*                                                                            *
* PARAMETERS:                                                                M
*   None                                                                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*****************************************************************************/
void IGRedrawViewWindow(void)
{
    MatrixType IritView;
    static int
	FirstTimeSolid = TRUE;

    if (ViewWidget == INVALID_WIDGET)		     /* Not initialized yet. */
        return;

    IGPredefinedAnimation();

    GLwDrawingAreaMakeCurrent(ViewWidget, GlxContext);

    glClearColor(IGGlblBackGroundColor[0] / 255.0,
		 IGGlblBackGroundColor[1] / 255.0,
		 IGGlblBackGroundColor[2] / 255.0,
		 1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glDrawBuffer(IGGlblDoDoubleBuffer ? GL_BACK : GL_FRONT);

    /* Clear viewing area. */
    glClear(GL_COLOR_BUFFER_BIT |
	    (IGGlblDrawSolid ? GL_DEPTH_BUFFER_BIT : 0));

    /* activate zbuffer only if we are in solid drawing mode. */
    if (IGGlblDrawSolid) {
	if (FirstTimeSolid) {
	    static GLfloat
		TwoSides[1] = { 1.0 },
	        LightPositions[4][4] = { {   1.0,   2.0,  10.0, 0.0 },
					 { -15.0,  -1.0 , -3.0, 0.0 },
					 {  -5.0,  -1.0, -10.0, 0.0 },
					 {   5.0, -10.0,   1.0, 0.0 } },
	        LightAmbient[] = { 0.1, 0.1, 0.1, 1.0 },
	        LightDiffuse[] = { 0.5, 0.5, 0.5, 1.0 },
	        LightSpecular[] = { 3.0, 3.0, 3.0, 1.0 },
	        LModelAmbient[] = { 0.2, 0.2, 0.2, 1.0 };
	    int i;

	    for (i = 0; i < 4; i++)
	        LightPositions[0][i] = IGGlblLightSrcPos[i];

	    for (i = 0; i < 4; i++) {
		glLightfv(GL_LIGHT0 + i, GL_POSITION, LightPositions[i]);
		glLightfv(GL_LIGHT0 + i, GL_AMBIENT, LightAmbient);
		glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, LightDiffuse);
		glLightfv(GL_LIGHT0 + i, GL_SPECULAR, LightSpecular);
	    }
 
	    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LModelAmbient);
	    glDepthFunc(GL_GREATER);
	    glClearDepth(0.0);

	    FirstTimeSolid = FALSE;

	    for (i = 0; i < 4; i++)
		glEnable(GL_LIGHT0 + i);

	    glDisable(GL_FOG);
	}

	glEnable(GL_LIGHTING);
	glEnable(GL_DEPTH_TEST);
    }
    else {
	int i;
	GLfloat fogColor[4];
	
	FirstTimeSolid = TRUE;

	for (i = 0; i < 3; i++)
	    fogColor[i] = (float) IGGlblBackGroundColor[i] / 255.0;
	fogColor[3] = (float) 1.0;

	glFogi(GL_FOG_MODE, GL_LINEAR);
	glHint(GL_FOG_HINT, GL_NICEST);
	glFogf(GL_FOG_START, (float) IGGlblZMinClip);
	glFogf(GL_FOG_END, (float) IGGlblZMaxClip);
	glFogfv(GL_FOG_COLOR, fogColor);

	if (IGGlblDepthCue)
	    glEnable(GL_FOG);
	else
	    glDisable(GL_FOG);

	for (i = 0; i < 4; i++)
	    glDisable(GL_LIGHT0 + i);

	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
    }

    switch (IGGlblViewMode) {	 /* Update the current view. */
	case IG_VIEW_ORTHOGRAPHIC:
	    GEN_COPY(IritView, IritPrsrViewMat, sizeof(MatrixType));
	    break;
	case IG_VIEW_PERSPECTIVE:
	    MatMultTwo4by4(IritView, IritPrsrViewMat, IritPrsrPrspMat);
	    break;
    }

    IPTraverseObjListHierarchy(IGGlblDisplayList, IritView, ViewObject);

    glFlush();
    if (IGGlblDoDoubleBuffer)
	glXSwapBuffers(XtDisplay(ViewWidget), XtWindow(ViewWidget));
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Call back function of the IPTraverseObjListHierarchy above.              *
*                                                                            *
* PARAMETERS:                                                                *
*   PObj:      Object to display.                                            *
*   Mat:       Viewing matrix of object.                                     *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void ViewObject(IPObjectStruct *PObj, MatrixType Mat)
{
    int i, j;
    GLdouble CrntView[16];

    for (i = 0; i < 4; i++)
        for (j = 0; j < 4; j++)
	    CrntView[i * 4 + j] = Mat[i][j];

    if (IGGlblDrawSolid) {
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
    }
    else {
        glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
    }
    glLoadIdentity();
    glOrtho(-1.0, 1.0, -1.0, 1.0, IGGlblZMaxClip, IGGlblZMinClip);
    glMultMatrixd(CrntView);
    glMatrixMode(GL_MODELVIEW);
    
    IGDrawObject(PObj);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* To handle internal events. Should not block.                               M
*                                                                            *
* PARAMETERS:                                                                M
*   None                                                                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*****************************************************************************/
void IGHandleInternalEvents(void)
{
}
