/* IP Address control
 *
 * Copyright 1998 Eric Kohl
 * Copyright 1998 Alex Priem <alexp@sci.kun.nl>
 *
 * NOTES

 *
 * TODO:
 *    -Check ranges when changing field-focus.
 * 	  -Check all notifications/behavior.
 *    -Optimization: include lpipsi in IPADDRESS_INFO.
 *	  -CurrentFocus: field that has focus at moment of processing.
 *	  -connect Rect32 rcClient.
 *	  -handle right and left arrows correctly. Boring.
 *	  -split GotoNextField in CheckField and GotoNextField.
 *	  -check ipaddress.cpp for missing features.
 *    -refresh: draw '.' instead of setpixel.
 *	  -handle VK_ESCAPE.
 */

#include <ctype.h>
#include <stdlib.h>

#include "windows.h"
#include "win.h"
#include "commctrl.h"
#include "ipaddress.h"
#include "heap.h"
#include "debug.h"


#define IPADDRESS_GetInfoPtr(wndPtr) ((IPADDRESS_INFO *)wndPtr->wExtra[0])


static BOOL32 
IPADDRESS_SendNotify (WND *wndPtr, UINT32 command);
static BOOL32 
IPADDRESS_SendIPAddressNotify (WND *wndPtr, UINT32 field, BYTE newValue);


/* property name of tooltip window handle */
#define IP_SUBCLASS_PROP "CCIP32SubclassInfo"


static LRESULT CALLBACK
IPADDRESS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam);




static VOID
IPADDRESS_Refresh (WND *wndPtr, HDC32 hdc)
{
	RECT32 rcClient;
	HBRUSH32 hbr;
	COLORREF clr=GetSysColor32 (COLOR_3DDKSHADOW);
    int i,x,fieldsize;

    GetClientRect32 (wndPtr->hwndSelf, &rcClient);
	hbr =  CreateSolidBrush32 (RGB(255,255,255));
    DrawEdge32 (hdc, &rcClient, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
	FillRect32 (hdc, &rcClient, hbr);
    DeleteObject32 (hbr);

	x=rcClient.left;
	fieldsize=(rcClient.right-rcClient.left) /4;

	for (i=0; i<3; i++) {		/* Should draw text "." here */
		x+=fieldsize;
		SetPixel32 (hdc, x,   13, clr);
		SetPixel32 (hdc, x,   14, clr);
		SetPixel32 (hdc, x+1, 13, clr);
		SetPixel32 (hdc, x+1, 14, clr);

	}

}





static LRESULT
IPADDRESS_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    IPADDRESS_INFO *infoPtr;
	RECT32 rcClient, edit;
	int i,fieldsize;
	LPIP_SUBCLASS_INFO lpipsi;
	

    infoPtr = (IPADDRESS_INFO *)COMCTL32_Alloc (sizeof(IPADDRESS_INFO));
    wndPtr->wExtra[0] = (DWORD)infoPtr;

	if (infoPtr == NULL) {
    	ERR (ipaddress, "could not allocate info memory!\n");
    	return 0;
    }

    GetClientRect32 (wndPtr->hwndSelf, &rcClient);

	fieldsize=(rcClient.right-rcClient.left) /4;

	edit.top   =rcClient.top+2;
	edit.bottom=rcClient.bottom-2;

	lpipsi=(LPIP_SUBCLASS_INFO)
			GetProp32A ((HWND32)wndPtr->hwndSelf,IP_SUBCLASS_PROP);
	if (lpipsi == NULL)  {
		lpipsi= (LPIP_SUBCLASS_INFO) COMCTL32_Alloc (sizeof(IP_SUBCLASS_INFO));
		lpipsi->wndPtr=wndPtr;
		lpipsi->uRefCount++;
		SetProp32A ((HWND32)wndPtr->hwndSelf, IP_SUBCLASS_PROP,
					(HANDLE32)lpipsi);
/*		infoPtr->lpipsi= lpipsi; */
	} else 
		WARN (ipaddress,"IP-create called twice\n");
	
	for (i=0; i<=3; i++) {
		infoPtr->LowerLimit[i]=0;
		infoPtr->UpperLimit[i]=255;
		edit.left=rcClient.left+i*fieldsize+3;
		edit.right=rcClient.left+(i+1)*fieldsize-2;
		lpipsi->hwndIP[i]= CreateWindow32A ("edit", NULL, 
				WS_CHILD | WS_VISIBLE | ES_LEFT,
				edit.left, edit.top, edit.right-edit.left, edit.bottom-edit.top,
				wndPtr->hwndSelf, (HMENU32) 1, wndPtr->hInstance, NULL);
		lpipsi->wpOrigProc[i]= (WNDPROC32)
					SetWindowLong32A (lpipsi->hwndIP[i],GWL_WNDPROC, (LONG)
					IPADDRESS_SubclassProc);
		SetProp32A ((HWND32)lpipsi->hwndIP[i], IP_SUBCLASS_PROP,
					(HANDLE32)lpipsi);
	}

	lpipsi->infoPtr= infoPtr;

    return 0;
}


static LRESULT
IPADDRESS_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
	int i;
    IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr(wndPtr);
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetProp32A ((HWND32)wndPtr->hwndSelf,IP_SUBCLASS_PROP);

	for (i=0; i<=3; i++) {
		SetWindowLong32A ((HWND32)lpipsi->hwndIP[i], GWL_WNDPROC,
                  (LONG)lpipsi->wpOrigProc[i]);
	}

    COMCTL32_Free (infoPtr);
    return 0;
}


static LRESULT
IPADDRESS_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    HDC32 hdc;

	TRACE (ipaddress,"\n");
    hdc = GetDC32 (wndPtr->hwndSelf);
    IPADDRESS_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

	IPADDRESS_SendIPAddressNotify (wndPtr, 0, 0);  /* FIXME: should use -1 */
	IPADDRESS_SendNotify (wndPtr, EN_KILLFOCUS);       
    InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);

    return 0;
}


static LRESULT
IPADDRESS_Paint (WND *wndPtr, WPARAM32 wParam)
{
    HDC32 hdc;
    PAINTSTRUCT32 ps;

    hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
    IPADDRESS_Refresh (wndPtr, hdc);
    if(!wParam)
	EndPaint32 (wndPtr->hwndSelf, &ps);
    return 0;
}


static LRESULT
IPADDRESS_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    HDC32 hdc;

	TRACE (ipaddress,"\n");

    hdc = GetDC32 (wndPtr->hwndSelf);
    IPADDRESS_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return 0;
}


static LRESULT
IPADDRESS_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    /* IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr(wndPtr); */
	TRACE (ipaddress,"\n");
    return 0;
}


static BOOL32
IPADDRESS_SendNotify (WND *wndPtr, UINT32 command)

{
    TRACE (ipaddress, "%x\n",command);
    return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_COMMAND,
              MAKEWPARAM (wndPtr->wIDmenu,command), (LPARAM) wndPtr->hwndSelf);
}


static BOOL32
IPADDRESS_SendIPAddressNotify (WND *wndPtr, UINT32 field, BYTE newValue)

{
	NMIPADDRESS nmip;

    TRACE (ipaddress, "%x %x\n",field,newValue);
    nmip.hdr.hwndFrom = wndPtr->hwndSelf;
    nmip.hdr.idFrom   = wndPtr->wIDmenu;
    nmip.hdr.code     = IPN_FIELDCHANGED;

	nmip.iField=field;
	nmip.iValue=newValue;

    return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
                                   (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmip);
}




static LRESULT
IPADDRESS_ClearAddress (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
	int i;
	HDC32 hdc;
	char buf[1];
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetProp32A ((HWND32)wndPtr->hwndSelf,IP_SUBCLASS_PROP);

	TRACE (ipaddress,"\n");

	buf[0]=0;
	for (i=0; i<=3; i++) 
		SetWindowText32A (lpipsi->hwndIP[i],buf);
	
  	hdc = GetDC32 (wndPtr->hwndSelf);
    IPADDRESS_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);
	return 0;
}

static LRESULT
IPADDRESS_IsBlank (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
 int i;
 char buf[20];
 LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetProp32A ((HWND32)wndPtr->hwndSelf,IP_SUBCLASS_PROP);

 TRACE (ipaddress,"\n");

 for (i=0; i<=3; i++) {
		GetWindowText32A (lpipsi->hwndIP[i],buf,5);
		if (buf[0]) return 0;
	}

 return 1;
}

static LRESULT
IPADDRESS_GetAddress (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
 char field[20];
 int i,valid,fieldvalue;
 DWORD ip_addr;
 IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr(wndPtr);
 LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetProp32A ((HWND32)wndPtr->hwndSelf,IP_SUBCLASS_PROP);

 TRACE (ipaddress,"\n");

 valid=0;
 ip_addr=0;
 for (i=0; i<=3; i++) {
		GetWindowText32A (lpipsi->hwndIP[i],field,4);
		ip_addr*=256;
		if (field[0]) {
			field[3]=0;
			fieldvalue=atoi(field);
			if (fieldvalue<infoPtr->LowerLimit[i]) 
				fieldvalue=infoPtr->LowerLimit[i];
			if (fieldvalue>infoPtr->UpperLimit[i]) 
				fieldvalue=infoPtr->UpperLimit[i];
			ip_addr+=fieldvalue;
			valid++;
		}
 }

 *(LPDWORD) lParam=ip_addr;

 return valid;
}

static LRESULT
IPADDRESS_SetRange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)

{
    IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr(wndPtr);
	INT32 index;
	
 	TRACE (ipaddress,"\n");

	index=(INT32) wParam;
	if ((index<0) || (index>3)) return 0;

	infoPtr->LowerLimit[index]=lParam & 0xff;
	infoPtr->UpperLimit[index]=(lParam >>8)  & 0xff;
	return 1;
}

static LRESULT
IPADDRESS_SetAddress (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
	HDC32 hdc;
    IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr(wndPtr);
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetProp32A ((HWND32)wndPtr->hwndSelf,IP_SUBCLASS_PROP);
	int i,ip_address,value;
    char buf[20];

 	TRACE (ipaddress,"\n");
	ip_address=(DWORD) lParam;

	for (i=3; i>=0; i--) {
		value=ip_address & 0xff;
		if ((value>=infoPtr->LowerLimit[i]) && (value<=infoPtr->UpperLimit[i])) 
			{
			 sprintf (buf,"%d",value);
			 SetWindowText32A (lpipsi->hwndIP[i],buf);
			 IPADDRESS_SendNotify (wndPtr, EN_CHANGE);
		}
		ip_address/=256;
	}

	hdc = GetDC32 (wndPtr->hwndSelf);		/* & send notifications */
    IPADDRESS_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

 return TRUE;
}




static LRESULT
IPADDRESS_SetFocusToField (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    /* IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr(wndPtr); */
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetProp32A ((HWND32)wndPtr->hwndSelf,IP_SUBCLASS_PROP);
	INT32 index;

	index=(INT32) wParam;
 	TRACE (ipaddress," %d\n", index);
	if ((index<0) || (index>3)) return 0;
	
	SetFocus32 (lpipsi->hwndIP[index]);
	
    return 1;
}


static LRESULT
IPADDRESS_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TRACE (ipaddress, "\n");

	SetFocus32 (wndPtr->hwndSelf);
	IPADDRESS_SendNotify (wndPtr, EN_SETFOCUS);
	IPADDRESS_SetFocusToField (wndPtr, 0, 0);

 	return TRUE;
}



/* tab/shift-tab: IPN_FIELDCHANGED, lose focus.
   dot, space,right arrow:	set focus to next child edit.
   numerics (0..9), control characters: forward to default edit control 
   other characters: dropped
*/
   



static int
IPADDRESS_GotoNextField (LPIP_SUBCLASS_INFO lpipsi, int currentfield)
{
 int newField,fieldvalue;
 char field[20];
 IPADDRESS_INFO *infoPtr=lpipsi->infoPtr;

 TRACE (ipaddress,"\n");
 GetWindowText32A (lpipsi->hwndIP[currentfield],field,4);
 if (field[0]) {
	field[3]=0;	
	newField=-1;
	fieldvalue=atoi(field);
	if (fieldvalue<infoPtr->LowerLimit[currentfield]) 
		newField=infoPtr->LowerLimit[currentfield];
	if (fieldvalue>infoPtr->UpperLimit[currentfield])
		newField=infoPtr->UpperLimit[currentfield];
	if (newField>=0) {
		sprintf (field,"%d",newField);
		SetWindowText32A (lpipsi->hwndIP[currentfield], field);
		return 1;
	}
 }

 if (currentfield<3) 
		SetFocus32 (lpipsi->hwndIP[currentfield+1]);
 return 0;
}


LRESULT CALLBACK
IPADDRESS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
 int i,l,index;
 IPADDRESS_INFO *infoPtr;
 LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetProp32A ((HWND32)hwnd,IP_SUBCLASS_PROP); 

 infoPtr = lpipsi->infoPtr;
 index=0;             /* FIXME */
 for (i=0; i<=3; i++) 
		if (lpipsi->hwndIP[i]==hwnd) index=i;

 switch (uMsg) {
	case WM_CHAR: break;
	case WM_KEYDOWN: {
			char c=(char) wParam;
			if (c==VK_TAB) {
 				HWND32 pwnd;
				int shift;
				shift = GetKeyState32(VK_SHIFT) & 0x8000;
				if (shift)
					pwnd=GetNextDlgTabItem32 (GetParent32 (hwnd), 0, TRUE);
				else
					pwnd=GetNextDlgTabItem32 (GetParent32 (hwnd), 0, FALSE);
				if (pwnd) SetFocus32 (pwnd);
				break;
			}
			
			if ((c==' ') || (c=='.') || (c==VK_RIGHT)) {
				IPADDRESS_GotoNextField (lpipsi,index);
				wParam=0;
				lParam=0;
				break;
			}
			if (c==VK_LEFT) {
				
			}
			if (c==VK_RETURN) {
			}
			if (((c>='0') && (c<='9')) || (iscntrl(c))) {
				l=GetWindowTextLength32A (lpipsi->hwndIP[index]);
				if (l==3) 
					if (IPADDRESS_GotoNextField (lpipsi,index)) {
						wParam=0;
						lParam=0;
					}
				break;
			}
	
			wParam=0;
			lParam=0;
			break;
		}
 }

 return CallWindowProc32A (lpipsi->wpOrigProc[index], hwnd, uMsg, wParam, lParam);
}

LRESULT WINAPI
IPADDRESS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
    WND *wndPtr = WIN_FindWndPtr(hwnd);

    switch (uMsg)
    {
	case IPM_CLEARADDRESS:
		return IPADDRESS_ClearAddress (wndPtr, wParam, lParam);

	case IPM_SETADDRESS:
	    return IPADDRESS_SetAddress (wndPtr, wParam, lParam);

	case IPM_GETADDRESS:
	    return IPADDRESS_GetAddress (wndPtr, wParam, lParam);

	case IPM_SETRANGE:
	    return IPADDRESS_SetRange (wndPtr, wParam, lParam);

	case IPM_SETFOCUS:
	    return IPADDRESS_SetFocusToField (wndPtr, wParam, lParam);

	case IPM_ISBLANK:
		return IPADDRESS_IsBlank (wndPtr, wParam, lParam);

	case WM_CREATE:
	    return IPADDRESS_Create (wndPtr, wParam, lParam);

	case WM_DESTROY:
	    return IPADDRESS_Destroy (wndPtr, wParam, lParam);

	case WM_GETDLGCODE:
	    return DLGC_WANTARROWS | DLGC_WANTCHARS;

	case WM_KILLFOCUS:
	    return IPADDRESS_KillFocus (wndPtr, wParam, lParam);

	case WM_LBUTTONDOWN:
        return IPADDRESS_LButtonDown (wndPtr, wParam, lParam);

	case WM_PAINT:
	    return IPADDRESS_Paint (wndPtr, wParam);

	case WM_SETFOCUS:
	    return IPADDRESS_SetFocus (wndPtr, wParam, lParam);

	case WM_SIZE:
	    return IPADDRESS_Size (wndPtr, wParam, lParam);

	default:
	    if (uMsg >= WM_USER)
		ERR (ipaddress, "unknown msg %04x wp=%08x lp=%08lx\n",
		     uMsg, wParam, lParam);
	    return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
    }
    return 0;
}


void
IPADDRESS_Register (void)
{
    WNDCLASS32A wndClass;

    if (GlobalFindAtom32A (WC_IPADDRESS32A)) return;

    ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
    wndClass.style         = CS_GLOBALCLASS;
    wndClass.lpfnWndProc   = (WNDPROC32)IPADDRESS_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(IPADDRESS_INFO *);
    wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
    wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
    wndClass.lpszClassName = WC_IPADDRESS32A;
 
    RegisterClass32A (&wndClass);
}

VOID
IPADDRESS_Unregister (VOID)
{
    if (GlobalFindAtom32A (WC_IPADDRESS32A))
    UnregisterClass32A (WC_IPADDRESS32A, (HINSTANCE32)NULL);
}

