/*
copyright 1989, Sarmad Adnan, adnan@rice.edu
*/

#include <windows.h>
#include <math.h>
#include "wineyes.h"



HANDLE hInst;
BOOL   FirstTimeToggle = TRUE;
POINT  mouseloc;
POINT  iamat;
POINT  eyecenter1, eyecenter2;
POINT  eyesize;
POINT  eyeballsize;
RECT   prevloc1={0,0,0,0};
RECT   prevloc2={0,0,0,0};

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
MSG msg;


if(hPrevInstance)
    {
    MessageBox(NULL, "I only have two eyes", "Error", MB_OK);
    return(NULL);
    }

if(!WinEyesInit(hInstance))
    {
    MessageBox(NULL, "Class registration failed", "Error", MB_OK);
    return(NULL);
    }

hInst = hInstance;

hWnd = CreateWindow(
		WINEYES_APPNAME,
		WINEYES_TITLE,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		161,
		195,
		NULL,
		NULL,
		hInstance,
		NULL
		);

if(!hWnd)
    {
    MessageBox(NULL, "Could not create window", "Error", MB_OK);
    return (NULL);
    }


if(!SetTimer(hWnd, NULL, 300, NULL) )
    {
    MessageBox(hWnd, "No Timers Available", "Error", MB_OK);
    return(NULL);
    }

ShowWindow(hWnd, SW_MINIMIZE);
UpdateWindow(hWnd);

while( GetMessage( &msg, NULL, NULL, NULL) )
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
return(msg.wParam);
}


BOOL WinEyesInit(HANDLE hInstance)
{
HANDLE hMemory;
PWNDCLASS pWndClass;
BOOL bSuccess;

hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
pWndClass = (PWNDCLASS) LocalLock(hMemory);

pWndClass->style = NULL;
pWndClass->lpfnWndProc = WinEyesWndProc;
pWndClass->hInstance = hInstance;
pWndClass->hIcon = NULL;
pWndClass->hCursor = LoadCursor(NULL, IDC_CROSS);
pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
pWndClass->lpszMenuName = (LPSTR) NULL;
pWndClass->lpszClassName = (LPSTR) WINEYES_APPNAME;
bSuccess = RegisterClass(pWndClass);
LocalUnlock(hMemory);
LocalFree(hMemory);

return(bSuccess);
}






long FAR PASCAL WinEyesWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
{
FARPROC lpProcAbout;
HMENU hMenu;

switch(message) 
    {
    case WM_PAINT:
        WinEyesPaint(hWnd);
        break;
    case WM_TIMER:
        WinEyesUpdate(hWnd);
        break;
    case WM_SIZE:
        InvalidateRect(hWnd, NULL, TRUE);
        FirstTimeToggle=TRUE;
        break;
    case WM_SYSCOMMAND:
        if(wParam == ID_ABOUT)
            {
            lpProcAbout = MakeProcInstance(About, hInst);
            DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
            FreeProcInstance(lpProcAbout);
            break;
	    }
        else
            return(DefWindowProc(hWnd, message, wParam, lParam));
    case WM_CREATE:
        hMenu = GetSystemMenu(hWnd, FALSE);
        ChangeMenu(hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR);
        ChangeMenu(hMenu, NULL, "A&bout WinEyes...", ID_ABOUT, MF_APPEND | MF_STRING);
        break;
    case WM_DESTROY:
        KillTimer(hWnd, NULL);
        PostQuitMessage(0);
        break;
    default:
        return (DefWindowProc(hWnd, message, wParam, lParam));
    }
return(NULL);
}


BOOL FAR PASCAL About(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
switch(message)
    {
    case WM_INITDIALOG:
        return (TRUE);
    case WM_COMMAND:
        if (wParam == IDOK) 
            {
            EndDialog(hDlg, NULL);
            return (TRUE);
	    }
        break;
    }
return(FALSE);
}


void WinEyesPaint(HWND hWnd)
{
PAINTSTRUCT ps;
POINT size, round;
RECT  forEllipse1, forEllipse2, rect;

BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH) );
GetClientRect( hWnd, &rect );
size.x=rect.right-rect.left;
size.y=rect.bottom-rect.top;
round.x=size.x/10;
round.y=size.y/10;
RoundRect(ps.hdc, rect.left, rect.top, rect.right, rect.bottom, round.x, round.y);

forEllipse1.left=rect.left+1, forEllipse1.right=(size.x)/2-1;
forEllipse1.top=rect.top+1, forEllipse1.bottom=(size.y)*2/3;
forEllipse2.right=rect.right-1, forEllipse2.left=(size.x)/2+1;
forEllipse2.top=rect.top+1, forEllipse2.bottom=(size.y)*2/3;

SelectObject(ps.hdc, GetStockObject(WHITE_BRUSH) );
SelectObject(ps.hdc, GetStockObject(WHITE_PEN) );
Ellipse(ps.hdc, forEllipse1.left, forEllipse1.top, forEllipse1.right, forEllipse1.bottom);
Ellipse(ps.hdc, forEllipse2.left, forEllipse2.top, forEllipse2.right, forEllipse2.bottom);
EndPaint(hWnd, (LPPAINTSTRUCT)&ps);

eyecenter1.x=(forEllipse1.right+forEllipse1.left)/2+1;
eyecenter1.y=(forEllipse1.top+forEllipse1.bottom)/2+1;

eyecenter2.x=(forEllipse2.right+forEllipse2.left)/2+1;
eyecenter2.y=eyecenter1.y;

eyesize.x=size.x/10;
eyesize.y=size.y/6;
eyeballsize.x=size.x/8;
eyeballsize.y=size.y/6;
}


void WinEyesUpdate(HWND hWnd)
{
PAINTSTRUCT ps;
RECT  rect, forEllipse1, forEllipse2;
POINT current1, current2;
HDC   hDc;
DWORD orgis;
double angle1, angle2;

GetCursorPos((LPPOINT)&current1);
if( (mouseloc.x==current1.x) && (mouseloc.y==current1.y) )
    return;

mouseloc.x=current1.x, mouseloc.y=current1.y;

hDc=GetDC(hWnd);

orgis=GetDCOrg(hDc);
iamat.x=LOWORD(orgis);
iamat.y=HIWORD(orgis);

current1.x=mouseloc.x-iamat.x-eyecenter1.x, current1.y=mouseloc.y-iamat.y-eyecenter1.y;
current2.x=mouseloc.x-iamat.x-eyecenter2.x, current2.y=mouseloc.y-iamat.y-eyecenter2.y;

angle1=atan2((double)current1.x, (double)current1.y);
angle1= 1.571-angle1;
angle2=atan2((double)current2.x, (double)current2.y);
angle2= 1.571-angle2;
current1.x=(int)( cos(angle1)*eyesize.x+eyecenter1.x), current1.y=(int)(sin(angle1)*eyesize.y+eyecenter1.y);
current2.x=(int)( cos(angle2)*eyesize.x+eyecenter2.x), current2.y=(int)(sin(angle2)*eyesize.y+eyecenter2.y);

forEllipse1.left=current1.x-eyeballsize.x, forEllipse1.top=current1.y-eyeballsize.y;
forEllipse1.right=current1.x+eyeballsize.x, forEllipse1.bottom=current1.y+eyeballsize.y;

forEllipse2.left=current2.x-eyeballsize.x, forEllipse2.top=current2.y-eyeballsize.y;
forEllipse2.right=current2.x+eyeballsize.x, forEllipse2.bottom=current2.y+eyeballsize.y;

if(!FirstTimeToggle)
    {
    SelectObject(hDc, GetStockObject(WHITE_PEN) );
    SelectObject(hDc, GetStockObject(WHITE_BRUSH) );
    Ellipse(hDc, prevloc1.left, prevloc1.top, prevloc1.right, prevloc1.bottom);
    Ellipse(hDc, prevloc2.left, prevloc2.top, prevloc2.right, prevloc2.bottom);
    }
else
    {
    FirstTimeToggle=FALSE;
    }

SelectObject(hDc, GetStockObject(BLACK_BRUSH) );
SelectObject(hDc, GetStockObject(BLACK_PEN) );
Ellipse(hDc, forEllipse1.left, forEllipse1.top, forEllipse1.right, forEllipse1.bottom);
Ellipse(hDc, forEllipse2.left, forEllipse2.top, forEllipse2.right, forEllipse2.bottom);

prevloc1.left=forEllipse1.left, prevloc1.top=forEllipse1.top;
prevloc1.right=forEllipse1.right, prevloc1.bottom=forEllipse1.bottom;
prevloc2.left=forEllipse2.left, prevloc2.top=forEllipse2.top;
prevloc2.right=forEllipse2.right, prevloc2.bottom=forEllipse2.bottom;

ReleaseDC(hWnd, hDc);
}
