/*
 * IP Address control
 *
 * Copyright 1998, 1999 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 "winbase.h"
#include "commctrl.h"
#include "ipaddress.h"
#include "heap.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(ipaddress)


#define IPADDRESS_GetInfoPtr(hwnd) ((IPADDRESS_INFO *)GetWindowLongA (hwnd, 0))


static BOOL 
IPADDRESS_SendNotify (HWND hwnd, UINT command);
static BOOL 
IPADDRESS_SendIPAddressNotify (HWND hwnd, UINT field, BYTE newValue);


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


static LRESULT CALLBACK
IPADDRESS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);




static VOID
IPADDRESS_Refresh (HWND hwnd, HDC hdc)
{
	RECT rcClient;
	HBRUSH hbr;
	COLORREF clr=GetSysColor (COLOR_3DDKSHADOW);
    int i,x,fieldsize;

    GetClientRect (hwnd, &rcClient);
	hbr =  CreateSolidBrush (RGB(255,255,255));
    DrawEdge (hdc, &rcClient, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
	FillRect (hdc, &rcClient, hbr);
    DeleteObject (hbr);

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

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

	}

}





static LRESULT
IPADDRESS_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    IPADDRESS_INFO *infoPtr;
	RECT rcClient, edit;
	int i,fieldsize;
	LPIP_SUBCLASS_INFO lpipsi;
	

    infoPtr = (IPADDRESS_INFO *)COMCTL32_Alloc (sizeof(IPADDRESS_INFO));
    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);

    GetClientRect (hwnd, &rcClient);

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

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

	lpipsi=(LPIP_SUBCLASS_INFO)
			GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP);
	if (lpipsi == NULL)  {
		lpipsi= (LPIP_SUBCLASS_INFO) COMCTL32_Alloc (sizeof(IP_SUBCLASS_INFO));
		lpipsi->hwnd = hwnd;
		lpipsi->uRefCount++;
		SetPropA ((HWND)hwnd, IP_SUBCLASS_PROP,
					(HANDLE)lpipsi);
/*		infoPtr->lpipsi= lpipsi; */
	} else 
		WARN("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]= CreateWindowA ("edit", NULL, 
				WS_CHILD | WS_VISIBLE | ES_LEFT,
				edit.left, edit.top, edit.right-edit.left, edit.bottom-edit.top,
				hwnd, (HMENU) 1, GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
		lpipsi->wpOrigProc[i]= (WNDPROC)
					SetWindowLongA (lpipsi->hwndIP[i],GWL_WNDPROC, (LONG)
					IPADDRESS_SubclassProc);
		SetPropA ((HWND)lpipsi->hwndIP[i], IP_SUBCLASS_PROP,
					(HANDLE)lpipsi);
	}

	lpipsi->infoPtr= infoPtr;

    return 0;
}


static LRESULT
IPADDRESS_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
	int i;
    IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd);
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP);

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

    COMCTL32_Free (infoPtr);
    return 0;
}


static LRESULT
IPADDRESS_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;

	TRACE("\n");
    hdc = GetDC (hwnd);
    IPADDRESS_Refresh (hwnd, hdc);
    ReleaseDC (hwnd, hdc);

    IPADDRESS_SendIPAddressNotify (hwnd, 0, 0);  /* FIXME: should use -1 */
    IPADDRESS_SendNotify (hwnd, EN_KILLFOCUS);       
    InvalidateRect (hwnd, NULL, TRUE);

    return 0;
}


static LRESULT
IPADDRESS_Paint (HWND hwnd, WPARAM wParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

    hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
    IPADDRESS_Refresh (hwnd, hdc);
    if(!wParam)
	EndPaint (hwnd, &ps);
    return 0;
}


static LRESULT
IPADDRESS_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;

	TRACE("\n");

    hdc = GetDC (hwnd);
    IPADDRESS_Refresh (hwnd, hdc);
    ReleaseDC (hwnd, hdc);

    return 0;
}


static LRESULT
IPADDRESS_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    /* IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); */
	TRACE("\n");
    return 0;
}


static BOOL
IPADDRESS_SendNotify (HWND hwnd, UINT command)

{
    TRACE("%x\n",command);
    return (BOOL)SendMessageA (GetParent (hwnd), WM_COMMAND,
              MAKEWPARAM (GetWindowLongA (hwnd, GWL_ID),command), (LPARAM)hwnd);
}


static BOOL
IPADDRESS_SendIPAddressNotify (HWND hwnd, UINT field, BYTE newValue)
{
	NMIPADDRESS nmip;

    TRACE("%x %x\n",field,newValue);
    nmip.hdr.hwndFrom = hwnd;
    nmip.hdr.idFrom   = GetWindowLongA (hwnd, GWL_ID);
    nmip.hdr.code     = IPN_FIELDCHANGED;

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

    return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
                               (WPARAM)nmip.hdr.idFrom, (LPARAM)&nmip);
}




static LRESULT
IPADDRESS_ClearAddress (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
	int i;
	HDC hdc;
	char buf[1];
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetPropA ((HWND)hwnd,IP_SUBCLASS_PROP);

	TRACE("\n");

	buf[0]=0;
	for (i=0; i<=3; i++) 
		SetWindowTextA (lpipsi->hwndIP[i],buf);
	
    hdc = GetDC (hwnd);
    IPADDRESS_Refresh (hwnd, hdc);
    ReleaseDC (hwnd, hdc);
	
	return 0;
}

static LRESULT
IPADDRESS_IsBlank (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 int i;
 char buf[20];
 LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP);

 TRACE("\n");

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

 return 1;
}

static LRESULT
IPADDRESS_GetAddress (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 char field[20];
 int i,valid,fieldvalue;
 DWORD ip_addr;
 IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd);
 LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP);

 TRACE("\n");

 valid=0;
 ip_addr=0;
 for (i=0; i<=3; i++) {
		GetWindowTextA (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 (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd);
	INT index;
	
 	TRACE("\n");

	index=(INT) 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 (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd);
	HDC hdc;
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP);
	int i,ip_address,value;
    char buf[20];

 	TRACE("\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);
			 SetWindowTextA (lpipsi->hwndIP[i],buf);
			 IPADDRESS_SendNotify (hwnd, EN_CHANGE);
		}
		ip_address/=256;
	}

    hdc = GetDC (hwnd);		/* & send notifications */
    IPADDRESS_Refresh (hwnd, hdc);
    ReleaseDC (hwnd, hdc);

 return TRUE;
}




static LRESULT
IPADDRESS_SetFocusToField (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    /* IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); */
	LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP);
	INT index;

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


static LRESULT
IPADDRESS_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TRACE("\n");

	SetFocus (hwnd);
	IPADDRESS_SendNotify (hwnd, EN_SETFOCUS);
	IPADDRESS_SetFocusToField (hwnd, 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("\n");
 GetWindowTextA (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);
		SetWindowTextA (lpipsi->hwndIP[currentfield], field);
		return 1;
	}
 }

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


LRESULT CALLBACK
IPADDRESS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 int i,l,index;
 IPADDRESS_INFO *infoPtr;
 LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO)
            GetPropA ((HWND)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) {
 				HWND pwnd;
				int shift;
				shift = GetKeyState(VK_SHIFT) & 0x8000;
				if (shift)
					pwnd=GetNextDlgTabItem (GetParent (hwnd), 0, TRUE);
				else
					pwnd=GetNextDlgTabItem (GetParent (hwnd), 0, FALSE);
				if (pwnd) SetFocus (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=GetWindowTextLengthA (lpipsi->hwndIP[index]);
				if (l==3) 
					if (IPADDRESS_GotoNextField (lpipsi,index)) {
						wParam=0;
						lParam=0;
					}
				break;
			}
	
			wParam=0;
			lParam=0;
			break;
		}
 }

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

LRESULT WINAPI
IPADDRESS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
	case IPM_CLEARADDRESS:
		return IPADDRESS_ClearAddress (hwnd, wParam, lParam);

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

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

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

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

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

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

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

	case WM_GETDLGCODE:
	    return DLGC_WANTARROWS | DLGC_WANTCHARS;

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

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

	case WM_PAINT:
	    return IPADDRESS_Paint (hwnd, wParam);

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

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

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


void
IPADDRESS_Register (void)
{
    WNDCLASSA wndClass;

    if (GlobalFindAtomA (WC_IPADDRESSA)) return;

    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
    wndClass.style         = CS_GLOBALCLASS;
    wndClass.lpfnWndProc   = (WNDPROC)IPADDRESS_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(IPADDRESS_INFO *);
    wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
    wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
    wndClass.lpszClassName = WC_IPADDRESSA;
 
    RegisterClassA (&wndClass);
}

VOID
IPADDRESS_Unregister (void)
{
    if (GlobalFindAtomA (WC_IPADDRESSA))
    UnregisterClassA (WC_IPADDRESSA, (HINSTANCE)NULL);
}

