/*****************************************************************************
*   Program to draw EE diagrams.					     *
*									     *
* This module redraw/draw all structs.					     *
*									     *
* Written by:  Gershon Elber			IBM PC Ver 1.0,	Oct. 1989    *
*****************************************************************************/

#include <stdio.h>
#include "\usr\include\intr_lib.h"
#include "Program.h"
#include "EERedraw.h"
#include "EEModify.h"
#include "EEString.h"
#include "EElayer.h"



static int CursorStartX, CursorStartY;
static DrawGenericStruct *HighLightStruct = NULL;
static DrawPolylineStruct *CrsrPolyline = NULL;
static DrawConnectionStruct *CrsrConnection = NULL;
static IntrCursorShapeStruct Cursor;

static void DrawPolylineCursor(int x, int y);
static void DrawConnectionCursor(int x, int y);

/*****************************************************************************
* Redraws only the active window which is assumed to be whole visible.	     *
*****************************************************************************/
void SetHighLightStruct(DrawGenericStruct *HighLight)
{
    HighLightStruct = HighLight;
}

/*****************************************************************************
* Redraws only the active window which is assumed to be whole visible.	     *
*****************************************************************************/
void RedrawActiveWindow(void)
{
    IntrWndwPop(EEActiveWindow -> IntrLibWindowID, TRUE, FALSE);
}

/*****************************************************************************
* Routine to redraw all windows defined.				     *
*****************************************************************************/
void RedrawAllWindows(void)
{
    IntrWndwRedrawAll();
}

/*****************************************************************************
* Routine to redraw list of structs.					     *
* If the list is of DrawPickStruct types then the picked item are drawn.     *
*****************************************************************************/
void RedrawStructList(DrawGenericStruct *Structs, int DrawMode, int Color)
{
    while (Structs) {
	if (Structs -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
	    RedrawOneStruct(((DrawPickedStruct *) Structs) -> PickedStruct,
							      DrawMode, Color);
	else
	    RedrawOneStruct(Structs, DrawMode, Color);

	Structs = Structs -> Pnext;
    }
}

/*****************************************************************************
* Routine to redraw list of structs.					     *
*****************************************************************************/
void RedrawOneStruct(DrawGenericStruct *Struct, int DrawMode, int Color)
{
    if (HighLightStruct == Struct)
	Color = EE_HIGHLIGHT_COLOR;
    

    switch (Struct -> StructType) {
	case DRAW_POLYLINE_STRUCT_TYPE:
	    RedrawPolylineStruct((DrawPolylineStruct *) Struct, DrawMode,
									Color);
	    break;
	case DRAW_CONNECTION_STRUCT_TYPE:
	    RedrawConnectionStruct((DrawConnectionStruct *) Struct,
							      DrawMode, Color);
	    break;
	case DRAW_TEXT_STRUCT_TYPE:
	    RedrawTextStruct((DrawTextStruct *) Struct, DrawMode, Color);
	    break;
	case DRAW_LIB_ITEM_STRUCT_TYPE:
	    DrawLibPart((DrawLibItemStruct *) Struct, DrawMode, Color);
	    break;
    }
}

/*****************************************************************************
* Routine to redraw polyline struct.					     *
*****************************************************************************/
void RedrawPolylineStruct(DrawPolylineStruct *Struct, int DrawMode, int Color)
{
    int i, CrntColor = GRGetColor();

    if(!(ReturnLayerMode(Struct->Layer)&0x03))
	return;
	else if(Color==EE_ERASE_COLOR)
		GRSetColor(EE_ERASE_COLOR);
    else
	GRSetColor(ReturnLayerColor(Struct->Layer)); 
	

    GRSetLineStyle(GR_SOLID_LINE, 0, Struct -> Width);

    GRSetWriteMode(DrawMode);

    GRMoveTo(Struct -> Points[0], Struct -> Points[1]);
    for (i = 1; i < Struct -> NumOfPoints; i++)
	GRLineTo(Struct -> Points[i * 2], Struct -> Points[i * 2 + 1]);

    GRSetColor(CrntColor);
}

/*****************************************************************************
* Routine to redraw connection struct.					     *
*****************************************************************************/
void RedrawConnectionStruct(DrawConnectionStruct *Struct, int DrawMode,
								int Color)
{
    int tmp_color;
    int CrntColor = GRGetColor(), Width = DEFAULT_SNAP_DISTANCE / 2;

    if(!(ReturnLayerMode(Struct->Layer)&0x03))
	return;
	else if(Color==EE_ERASE_COLOR)
	GRSetColor(EE_ERASE_COLOR);
    else
	tmp_color=ReturnLayerColor(Struct->Layer); 
	GRSetColor(tmp_color); 
    GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);

    GRSetWriteMode(DrawMode);

    GRSetFillStyle(GR_SOLID_FILL, tmp_color);

    GRBar(Struct -> PosX - Width, Struct -> PosY - Width,
	  Struct -> PosX + Width, Struct -> PosY + Width);

    GRSetColor(CrntColor);
}

/*****************************************************************************
* Routine to redraw text struct.					     *
*****************************************************************************/
void RedrawTextStruct(DrawTextStruct *Struct, int DrawMode, int Color)
{
    int CrntColor = GRGetColor();

    if(!(ReturnLayerMode(Struct->Layer)&0x03))
	return;
	else if(Color==EE_ERASE_COLOR)
	GRSetColor(EE_ERASE_COLOR);
    else
	GRSetColor(ReturnLayerColor(Struct->Layer)); 
    GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);

    GRSetWriteMode(DrawMode); 
    

    PutTextInfo(Struct -> Orient, Struct -> PosX, Struct -> PosY,
					    Struct -> Scale, Struct -> Text);

    GRSetColor(CrntColor);
}

/*****************************************************************************
* Routine to place polyline struct. Return TRUE if not aborted.		     *
*****************************************************************************/
BooleanType PlacePolylineStruct(DrawPolylineStruct *Struct)
{
    int i, Event, CursorEndX, CursorEndY, Dx, Dy, *Points;
    DrawGenericStruct *Next;

    IntrPushCursorType();
    Cursor.CursorType = INTR_CURSOR_CUSTOM;
    Cursor.CursorRoutine = DrawPolylineCursor;
    IntrSetCursorType(&Cursor);
    IntrDrawMessage("Place polyline", EEPopUpForeColor, EEPopUpBackColor);

    CrsrPolyline = Struct;
    CursorStartX = GRInvMapX(GRCurrentCursorX);
    CursorStartY = GRInvMapY(GRCurrentCursorY);

    /*   Snap the CursorStartX/Y to the real polyline point. As we need to   */
    /* snap to this structure only, make sure its next is NULL.		     */
    Next = Struct -> Pnext;
    Struct -> Pnext = NULL;
    SnapPoint2(&CursorStartX, &CursorStartY, FALSE,
					(DrawGenericStruct *) Struct, NULL);
    Struct -> Pnext = Next;

    if ((Event = IntrGetEventWaitSA(&CursorEndX, &CursorEndY)) ==
							INTR_EVNT_SELECT) {
	CursorEndX = GRInvMapX(CursorEndX);
	CursorEndY = GRInvMapY(CursorEndY);
	Points = Struct -> Points;
	Dx = EE_SNAP(CursorEndX) - EE_SNAP(CursorStartX);
	Dy = EE_SNAP(CursorEndY) - EE_SNAP(CursorStartY);
	for (i = 0; i < Struct -> NumOfPoints; i++) {
	    Points[i * 2] += Dx;
	    Points[i * 2 + 1] += Dy;
	}
    }

    IntrEraseMessage();
    IntrPopCursorType();

    return Event != INTR_EVNT_ABORT;
}

/*****************************************************************************
* Routine to place connection struct. Return TRUE if not aborted.	     *
*****************************************************************************/
BooleanType PlaceConnectionStruct(DrawConnectionStruct *Struct)
{
    int Event, NewX = Struct -> PosX, NewY = Struct -> PosY;

    IntrPushCursorType();
    Cursor.CursorType = INTR_CURSOR_CUSTOM;
    Cursor.CursorRoutine = DrawConnectionCursor;
    IntrSetCursorType(&Cursor);
    IntrDrawMessage("Place connection", EEPopUpForeColor, EEPopUpBackColor);

    CrsrConnection = Struct;
    if ((Event = IntrGetEventWaitSA(&NewX, &NewY)) == INTR_EVNT_SELECT) {
	Struct -> PosX = EE_SNAP(GRInvMapX(NewX));
	Struct -> PosY = EE_SNAP(GRInvMapY(NewY));
    }

    IntrEraseMessage();
    IntrPopCursorType();

    return Event != INTR_EVNT_ABORT;
}

/*****************************************************************************
* Routine to place text struct. Return TRUE if not aborted.		     *
*****************************************************************************/
BooleanType PlaceTextStruct(DrawTextStruct *Struct)
{
    return PlaceString(Struct -> Text, &Struct -> Orient, Struct -> Scale,
		       &Struct -> PosX, &Struct -> PosY,
                       INTR_WNDW_PLACE_CENTER);
}

/*****************************************************************************
* Routine called by the cursor routine to display current polyline.	     *
*****************************************************************************/
static void DrawPolylineCursor(int x, int y)
{
    int i,
    	LastColor = GRGetColor();

    GRSetColor(EE_HIGHLIGHT_COLOR);

    GRSMoveTo(0, y);
    GRSLineTo(GRScreenMaxX, y);

    GRSMoveTo(x, 0);
    GRSLineTo(x, GRScreenMaxY);

    x = GRInvMapX(x) - CursorStartX;
    y = GRInvMapY(y) - CursorStartY;

    GRMoveTo(CrsrPolyline -> Points[0] + x, CrsrPolyline -> Points[1] + y);
    for (i = 1; i < CrsrPolyline -> NumOfPoints; i++)
	GRLineTo(CrsrPolyline -> Points[i * 2] + x,
		 CrsrPolyline -> Points[i * 2 + 1] + y);

    GRSetColor(LastColor);
}

/*****************************************************************************
* Routine called by the cursor routine to display current connection.        *
*****************************************************************************/
static void DrawConnectionCursor(int x, int y)
{
    int Width = DEFAULT_SNAP_DISTANCE / 2,
    	LastColor = GRGetColor();

    GRSetColor(EE_HIGHLIGHT_COLOR);

    GRSMoveTo(0, y);
    GRSLineTo(GRScreenMaxX, y);

    GRSMoveTo(x, 0);
    GRSLineTo(x, GRScreenMaxY);

    x = GRInvMapX(x);
    y = GRInvMapY(y);

    GRMoveTo(x - Width, y - Width);
    GRLineTo(x + Width, y - Width);
    GRLineTo(x + Width, y + Width);
    GRLineTo(x - Width, y + Width);
    GRLineTo(x - Width, y - Width);

    GRSetColor(LastColor);
}
