#include <windows.h>
#include "fuse2.h"

/*****************

        Brian's incredible Fuse app.


        This program was compiled Win 3.0 SDK and MSC 6.0.



        Brian Farmer
        Computer Science Center
        University of Maryland
        College Park,  MD 20742

        brianf@umd5.umd.edu


******************/


#define max_fuses       40

HANDLE  hInst;

typedef struct FUSESTR
        {
                int     x1, y1, x2, y2;
                BOOL    drawn;
        } FUSE;

FUSE    fuses[max_fuses];

int     dx1, dy1, dx2, dy2, xextent, yextent;
HWND    hDesk;
HPEN    mypen;
FARPROC oldproc;

long FAR PASCAL MyProc (HWND hWnd, WORD message, WORD wParam, LONG lParam)

{
        if (message == WM_ERASEBKGND)
                ReDoLines ();

        CallWindowProc (oldproc, hWnd, message, wParam, lParam);
}

void SetBack (HWND hWnd)

{

        oldproc = (FARPROC)GetWindowLong (hWnd, GWL_WNDPROC);

        SetWindowLong (hWnd, GWL_WNDPROC, (LONG)MakeProcInstance ((FARPROC)MyProc, hInst));
}

void InitFuses(void)
{

        int     i;
        RECT    rect;

        hDesk = GetDesktopHwnd ();

        SetBack (hDesk);

        GetClientRect (hDesk, &rect);
        yextent = rect.bottom-rect.top;
        xextent = rect.right-rect.left;

        mypen = CreatePen (0, 1, RGB (255, 255, 255));

        for (i=0;i<max_fuses;i++)
                fuses[i].drawn = FALSE;

        fuses[max_fuses-1].x1 = xextent/2;
        fuses[max_fuses-1].x2 = xextent/2 - 50;

        fuses[max_fuses-1].y1 = yextent/2;
        fuses[max_fuses-1].y2 = yextent/2 - 50;

        dx1 = 10;
        dy1 = 10;
        dx2 = -10;
        dy2 = -10;
}

void DrawFuse (HDC hDC, FUSE *fuse)

{
        MoveTo (hDC, fuse->x1, fuse->y1);
        LineTo (hDC, fuse->x2, fuse->y2);
}


int MyRand ()

{
        return (rand ()/3277);
}

void MoveFuse (FUSE *previous, FUSE *tomove)

{
        tomove->x1 = previous->x1 + dx1; 
        tomove->x2 = previous->x2 + dx2; 
        tomove->y1 = previous->y1 + dy1; 
        tomove->y2 = previous->y2 + dy2; 

        if (tomove->x1 > xextent)
                dx1 = -MyRand ();

        if (tomove->x1 < 0)
                dx1 = MyRand ();

        if (tomove->x2 > xextent)
                dx2 = -MyRand ();

        if (tomove->x2 < 0)
                dx2 = MyRand ();

        if (tomove->y1 > yextent)
                dy1 = -MyRand ();

        if (tomove->y1 < 0)
                dy1 = MyRand ();

        if (tomove->y2 > yextent)
                dy2 = -MyRand ();

        if (tomove->y2 < 0)
                dy2 = MyRand ();

}

void ReDoLines ()

{
static  int     current=0;
        HDC     hDC;
        int     oldrop, i;
        HANDLE  oldpen;

        hDC = GetDC (hDesk);

        oldrop = SetROP2 (hDC, R2_XORPEN);
        oldpen = SelectObject (hDC, mypen);


        for (i=0; i<max_fuses;i++)
        {
                if (fuses[i].drawn)
                {
                        DrawFuse (hDC, &fuses[i]);
                        fuses[i].drawn = FALSE;
                }
        }


        SetROP2 (hDC, oldrop);
        SelectObject (hDC, oldpen);

        ReleaseDC (hDesk, hDC);
}

void DoFuses ()

{
static  int     current=0;
        HDC     hDC;
        int     oldrop;
        HANDLE  oldpen;

        hDC = GetDC (hDesk);

        oldrop = SetROP2 (hDC, R2_XORPEN);
        oldpen = SelectObject (hDC, mypen);

        if (fuses[current].drawn)
                DrawFuse (hDC, &fuses[current]);

        if (!current)
                MoveFuse (&fuses[max_fuses-1], &fuses[0]);
        else
                MoveFuse (&fuses[current-1], &fuses[current]);


        DrawFuse (hDC, &fuses[current]);

        fuses[current].drawn = TRUE;

        current = ++current % max_fuses;

        SetROP2 (hDC, oldrop);
        SelectObject (hDC, oldpen);

        ReleaseDC (hDesk, hDC);
}


long PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )

HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;


{
        MSG     msg;
        BOOL    ext = FALSE;


        hInst = hInstance;

        InitFuses ();

        while (TRUE)
        {
                PeekMessage( (LPMSG)&msg, 0, 0, 0, PM_REMOVE);
                DoFuses ();
        }
}

