/*****************************************************************************
*   A Windows NT driver - regular NT graphics calls.			     *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Gershon Elber				Ver 0.1, June 1993.  *
*****************************************************************************/

#include <stdio.h>
#include <windows.h>
#include "irit_sm.h"
#include "genmat.h"
#include "iritprsr.h"
#include "allocate.h"
#include "attribut.h"
#include "ip_cnvrt.h"
#include "cagd_lib.h"
#include "symb_lib.h"
#include "iritgrap.h"
#include "wntdrvs.h"

/*****************************************************************************
* DESCRIPTION:                                                               M
* Redraw the viewing window.						     M
*                                                                            *
* PARAMETERS:                                                                M
*   none	                                                             M
*                                                                            *
* RETURN VALUE:                                                              M
*   void	                                                             M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGRedrawViewWindow                                                       M
*****************************************************************************/
void IGRedrawViewWindow(void)
{
    InvalidateRect(IGhWndView, NULL, FALSE);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Redraw the viewing window.						     M
*                                                                            *
* PARAMETERS:                                                                M
*   hWnd:     Handle on window to draw to.                                   M
*   wMsg:     Event to handle.                                               M
*   wParam:   Some parameters of event.                                      M
*                                                                            *
* RETURN VALUE:                                                              M
*   int:      Window's condition.                                            M
*                                                                            *
* KEYWORDS:                                                                  M
*   RedrawViewWindow                                                         M
*****************************************************************************/
int RedrawViewWindow(HWND hWnd, UINT wMsg, WPARAM wParam)
{
    PAINTSTRUCT ps;

    if (wMsg != WM_PAINT)
	return 0;

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

    if (IGCurrenthDC = BeginPaint(hWnd, &ps)) {
	RECT rect;
	IPObjectStruct *PObj, *MatObj;
	MatrixType CrntViewMat;

	GetClientRect(hWnd, &rect);
	FillRect(IGCurrenthDC, &rect, IGBackGroundBrush);

	/* Slim chance that a race will oocur if the following test and set */
	/* is done simultanuously. Should use semaphors probably.	    */
	while (IGGlblDisplayListIsUsed)
	    IritSleep(10);
	IGGlblDisplayListIsUsed = TRUE;

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

	for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext) {
	    int Visible = TRUE;

	    if ((MatObj = AttrGetObjectObjAttrib(PObj,
						 "_animation_mat")) != NULL &&
		IP_IS_MAT_OBJ(MatObj)) {
		if (Visible = AttrGetObjectIntAttrib(PObj, "_isvisible")) {
		    MatMultTwo4by4(IGGlblCrntViewMat,
				   *MatObj -> U.Mat, IritPrsrViewMat);
		    if (IGGlblViewMode == IG_VIEW_PERSPECTIVE) 
			MatMultTwo4by4(IGGlblCrntViewMat,
				       IGGlblCrntViewMat, IritPrsrPrspMat);
		}
	    }
	    else
		GEN_COPY(IGGlblCrntViewMat, CrntViewMat, sizeof(MatrixType));

	    if (Visible)
		IGDrawObject(PObj);
	}

	IGGlblDisplayListIsUsed = FALSE;

	if (IGCurrenthPen)
            DeleteObject(SelectObject(IGCurrenthDC, IGCurrenthPen));
	EndPaint(hWnd, &ps);
	IGCurrenthDC = 0;
	IGCurrenthPen = 0;
    }

    return 0;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Low level 2D drawing routine. Coordinates are normalized to -1 to 1 by     M
* this time.                                                                 M
*                                                                            *
* PARAMETERS:                                                                M
*   X, Y:    Coordinates of 2D location to move to.                          M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGMoveTo2D                                                               M
*****************************************************************************/
void IGMoveTo2D(RealType X, RealType Y)
{
    int x, y;

    MoveToEx(IGCurrenthDC, x = WNT_MAP_X_COORD(X), y = WNT_MAP_Y_COORD(Y), NULL);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Low level 2D drawing routine. Coordinates are normalized to -1 to 1 by     M
* this time.                                                                 M
*                                                                            *
* PARAMETERS:                                                                M
*   X, Y:    Coordinates of 2D location to draw to.                          M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGLineTo2D                                                               M
*****************************************************************************/
void IGLineTo2D(RealType X, RealType Y)
{
    int x, y;

    LineTo(IGCurrenthDC, x = WNT_MAP_X_COORD(X), y = WNT_MAP_Y_COORD(Y));
}

/*****************************************************************************
* DESCRIPTION:                                                               M
* Sets the intensity of a color (high or low).				     M
*                                                                            *
* PARAMETERS:                                                                M
*   High:     TRUE for high, FALSE for low.                                  M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGSetColorIntensity                                                      M
*****************************************************************************/
void IGSetColorIntensity(int High)
{
    if (!IGCurrenthDC)
	return;
    if (IGCurrenthPen)
        DeleteObject(SelectObject(IGCurrenthDC, IGCurrenthPen));
    IGCurrenthPen = 
	SelectObject(IGCurrenthDC, CreatePen(PS_SOLID, IGGlblLineWidth,
					     High ? IGCrntColorHighIntensity
					          : IGCrntColorLowIntensity));

    IGGlblIntensityHighState = High;
}

/*****************************************************************************
* 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])) {
	IGSetColorRGB(Color);
    }
    else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
	IGSetColorIndex(c);
    }
    else {
	/* Use white as default color: */
	IGSetColorIndex(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)
{
}

/*****************************************************************************
* 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                                                                     *
*****************************************************************************/
void IGSetColorIndex(int color)
{
    IGSetColorIndex2(color, IGGlblLineWidth);
}

/*****************************************************************************
* DESCRIPTION:                                                               *
* Sets the color/width according to the given color index/width.   	     *
*                                                                            *
* PARAMETERS:                                                                *
*   color:     Index of color to use. Must be between 0 and IG_MAX_COLOR.    *
*   width:     In pixel, for line draw.                                      *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
void IGSetColorIndex2(int color, int width)
{
    if (color > IG_MAX_COLOR)
	color = IG_IRIT_WHITE;

    IGCrntColorHighIntensity = IGColorsHighIntensity[color];
    IGCrntColorLowIntensity = IGColorsLowIntensity[color];

    if (!IGCurrenthDC)
	return;
    if (IGCurrenthPen)
        DeleteObject(SelectObject(IGCurrenthDC, IGCurrenthPen));
    IGCurrenthPen = SelectObject(IGCurrenthDC, CreatePen(PS_SOLID, width,
						    IGCrntColorHighIntensity));

    IGGlblIntensityHighState = TRUE;
}


/*****************************************************************************
* 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                                                                     *
*****************************************************************************/
void IGSetColorRGB(int Color[3])
{
    IGCrntColorHighIntensity = GetNearestColor(IGCurrenthDC,
					       RGB(Color[0],
						   Color[1],
						   Color[2]));
    IGCrntColorLowIntensity = GetNearestColor(IGCurrenthDC,
					      RGB(Color[0] / 2,
						  Color[1] / 2,
						  Color[2] / 2));


    if (!IGCurrenthDC)
	return;
    if (IGCurrenthPen)
        DeleteObject(SelectObject(IGCurrenthDC, IGCurrenthPen));

    IGCurrenthPen = SelectObject(IGCurrenthDC, CreatePen(PS_SOLID, 1,
						    IGCrntColorHighIntensity));

    IGGlblIntensityHighState = TRUE;
}
