//
//   Headers detail edit for compose
//
//   1/8/96  M.Shimomai
//           Kagoshima Univ., Japan
//
#include <windows.h>
#include <windowsx.h>
#include "wvglob.h"
#include "winvn.h"
#pragma hdrstop
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>

char *GetDlgEditText (HWND hDlg, unsigned int iMessage);
BOOL SearchLineTextBlock (TypTextBlock * textBlock, char *prefix);
unsigned long iSearchLineTextBlock (TypTextBlock * textBlock, char *prefix);

/*-- function WinVnHeadersDialog ---------------------------------------
 *
 */
void ResizeHeaderDialog(HWND hDlg)
{
#define XSPACING		5
#define YSPACING		2

	HWND hItem;
	RECT rect;
	int cx, cy, ySize;
	SIZE size;
	HDC hDC;
	HFONT hOldFont;

	GetClientRect (hDlg, &rect);
	cx = RectWidth (rect);
	cy = RectHeight (rect);
	ySize = (int) (2 * WinVnLineHeight);
	hItem = GetDlgItem(hDlg, IDC_HEADER_EDIT);
	
	hDC = GetDC(hItem);
	hOldFont = (HFONT)SelectObject (hDC, hWinVnFont);
	GetTextExtentPoint (hDC, " Cancel ", 11, &size);
	SelectObject (hDC, hOldFont);
	ReleaseDC (hItem, hDC);
	
	MoveWindow (hItem, 0, 0, cx, cy - ySize - YSPACING * 3, TRUE);
	cx = cx / 2;
	SendDlgItemMessage (hDlg, IDC_HEADER_EDIT, WM_SETFONT, (WPARAM) hCompositionFont, FALSE);
	MoveWindow (GetDlgItem(hDlg, IDOK),
	cx - XSPACING - size.cx, cy - ySize - YSPACING,
	size.cx, ySize, TRUE);
	SendDlgItemMessage (hDlg, IDOK, WM_SETFONT, (WPARAM) hWinVnFont, TRUE);
	MoveWindow (GetDlgItem(hDlg, IDCANCEL),
	cx + XSPACING, cy - ySize - YSPACING,
	size.cx, ySize, TRUE);
	SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM) hWinVnFont, TRUE);
}

char far *newheader;

INT_PTR CALLBACK WinVnHeadersDlg (HWND hDlg, unsigned int iMessage, WPARAM wParam, LPARAM lParam)
{
	HWND hWnd;
	RECT rect;
	int widthDlg;
	char *ptr;

	switch (iMessage) 
	{
		case WM_INITDIALOG:
			SendDlgItemMessage (hDlg, IDC_HEADER_EDIT, WM_SETFONT, (WPARAM) hCompositionFont, FALSE);
			ptr = (char *) lParam;
			if (ptr && *ptr) 
			{
				SetDlgItemText (hDlg, IDC_HEADER_EDIT, ptr);
			}
			hWnd = GetParent(hDlg);
			GetClientRect (hWnd, &rect);
			widthDlg = RectWidth (rect);
			GetWindowRect (hDlg, &rect);
			MoveWindow (hDlg, (int)rect.left, (int)rect.top, widthDlg, RectHeight(rect), TRUE);
			ResizeHeaderDialog(hDlg);
			return TRUE;
			break;

		case WM_SIZE:
			ResizeHeaderDialog(hDlg);
			break;

		case WM_COMMAND:
		switch (GET_WM_COMMAND_ID(wParam, lParam)) 
		{
			case IDOK:
				if (SendDlgItemMessage (hDlg, IDC_HEADER_EDIT, EM_GETMODIFY, 0, 0L)) 
				{
					if (!(newheader = GetDlgEditText (hDlg, IDC_HEADER_EDIT))) 
					{
						WVMessageBox (GetDlgItem(hDlg, IDC_HEADER_EDIT), "Can't retrieve new header part text",
							"Failed in Headers Detail Dialog", MB_OK | MB_ICONINFORMATION);
						EndDialog (hDlg, FALSE);
						break;
					}
					EndDialog (hDlg, TRUE);
				}
				else 
				{
					EndDialog (hDlg, FALSE);
				}
				break;

			case IDCANCEL:
				EndDialog (hDlg, FALSE);
				break;

			default:
				return FALSE;
		}
		break;

		case WM_CHAR:
			if (LOWORD (wParam) == VK_TAB) 
			{
				break;
			}
			return FALSE;

		default:
			return FALSE;
			break;
	}
	return TRUE;
}


#define TEXT_SIZE_INC		1024L

void EditHeaders (WndEdit * editWnd)
{
	TypTextBlock * headers;
	char *line, *buf;
	unsigned long i;
	long left, num;
	char *ptr, *endPtr, *p, *q = '\0';
	int result, n;
	char title[MAXDIALOGSTRING];

	if ((headers = InitTextBlock (editWnd->hWnd)) == NULL)
		return;

	/* Ray Dunn:99/11: Avoid crossposting Warning - add arg*/
	if (GenerateHeadersForSend (editWnd, headers, NULL, FALSE) == FAIL)
		return;

	left = TEXT_SIZE_INC;
	num = 1;
	if ((buf = (char *) GlobalAllocPtr (GMEM_MOVEABLE,  left * sizeof (char))) == NULL) 
	{
		WVMessageBox (editWnd->hWnd, "Failed to Generate Article", "Memory Allocation Failure", MB_OK | MB_ICONSTOP);
		return;
	}
	*buf = '\0';

	for (i = 0; i < headers->numLines; i++) 
	{
		line = TextBlockLine (headers, i);
		if ((left -= strlen(line)) < 0) 
		{
			if ((buf = (char *) GlobalReAllocPtr (buf,TEXT_SIZE_INC * (++num) * sizeof (char), GMEM_MOVEABLE)) == NULL) 
			{
				WVMessageBox (editWnd->hWnd, "Failed to Generate Article", "Memory Allocation Failure", MB_OK | MB_ICONSTOP);
				return;
			}
			left += TEXT_SIZE_INC;
		}
		strcat(buf, line);
	}

	FreeTextBlock (headers);

	ContinueEdit:
	if (DialogBoxParam (hInst, MAKEINTRESOURCE(IDD_WINVNHEADERS), editWnd->hWnd, lpfnWinVnHeadersDlg, (LPARAM) buf) == TRUE) 
	{
		/* now scan text up to a blank line for additional 
		* x- and rfc822 and rfc1036 headers 
		*/
		ptr = p = newheader;
		result = SUCCESS;
		while (*p) 
		{
			if ((endPtr = strchr (p, '\r')) == NULL) 
			{
				endPtr = ptr + strlen(ptr);	/* handle no crlf on last line */
			} 
			else 
			{
				endPtr++;				/* move past \r */
				/* handle soft line break \r\r\n (see EM_FMTLINES) */
				if (*endPtr == '\r') 
				{
					endPtr++;			/* move past \n */
				}
				if (*endPtr == '\n') 
				{
					endPtr++;			/* move past extra \n (in case of soft line break extra \n */
				}
			}
			if (*ptr == '\0') 
				break;	/* blank line */
			if (isspace((unsigned char)*endPtr)) 
			{
				p = endPtr;
				continue;
			}	
			if (!IsAdditionalHeader(ptr)) 
			{		/* not recognized */
				*buf = '\"';
				for(p=ptr, q=buf + 1; *p != ':'; q++, p++) 
					*q = *p;
				*q++ = '\"'; 
				*q = '\0';
				strcat(buf, " : non RFC822/RFC1036 header.\nBack to header part edit window.");
				
				if(WVMessageBox (editWnd->hWnd, buf, "Warning: Header not recognized ", MB_YESNO | MB_ICONQUESTION) == IDYES) 
				{
					GlobalFreePtr (buf);
					buf = newheader;
					goto ContinueEdit;
				}
			}
			ptr = p = endPtr;
		}

		ResetTextBlock(editWnd->extraHeaders);
		ptr = p = newheader;
		while (*p && result == SUCCESS) 
		{
			if ((endPtr = strchr (p, '\r')) == NULL) 
			{
				endPtr = ptr + strlen(ptr);	/* handle no crlf on last line */
			} 
			else 
			{
				q = endPtr;
				//		*endPtr = '\0';
				endPtr++;				/* move past \r */
				/* handle soft line break \r\r\n (see EM_FMTLINES) */
				
				if (*endPtr == '\r') 
				{
					endPtr++;			/* move past \n */
				}
				
				if (*endPtr == '\n') 
				{
					endPtr++;			/* move past extra \n (in case of soft line break extra \n */
				}
			}
			if (*ptr == '\0') 
				break;	/* blank line */
			
			if (isspace((unsigned char)*endPtr)) 
			{	/* continuous line */
				p = endPtr;
				continue;
			}	
			else
				*q = '\0';

			for (n = 0; n < HDR_NUM_CONTROLS; n++) 
			{
				if (n == HDR_ATTACH)
					continue;

				if (editWnd->headerControls->UI[n]) 
				{
					SendMessage (editWnd->headerControls->title[n], WM_GETTEXT, (WPARAM) MAXDIALOGSTRING, (LPARAM) (LPCSTR) title);
					if (_strnicmp(title, ptr, strlen(title)) == 0) 
					{
						SendMessage (editWnd->headerControls->UI[n], WM_SETTEXT, (WPARAM) MAXHEADERLINE, (LPARAM) (LPCSTR) (strchr (ptr, ':') + 2));
						break;
					}
				}
			}
			if (n >= HDR_NUM_CONTROLS) 
			{
				unsigned long i;
				char prefix[32];
				
				strncpy(prefix, ptr, 31);
				prefix[31] = '\0';
				
				if (p = strchr(prefix, ':'))
					*(++p) = '\0';
				
				_snprintf(buf, MAXHEADERLINE, "%s\r\n", ptr);
			
				if ((i = iSearchLineTextBlock(editWnd->extraHeaders, prefix)) < editWnd->extraHeaders->numLines) 
				{
					result = ReplaceLineInTextBlock (editWnd->extraHeaders, i, buf);
				}
				else 
				{
					result = AddLineToTextBlock (editWnd->extraHeaders, buf);
				}
			}
			ptr = p = endPtr;
		}

		GlobalFreePtr (newheader);
		GlobalFreePtr (buf);

		if ((buf = GetEditText(editWnd->hWndEdit)) && editWnd->bodyOffset > 0L) 
		{
			SetWindowText (editWnd->hWndEdit, &(buf[editWnd->bodyOffset]));
			editWnd->bodyOffset = 0L;
		}
	}
	GlobalFreePtr (buf);
}


unsigned long iSearchLineTextBlock (TypTextBlock * textBlock, char *prefix)
{
	unsigned long i;

	for (i=0; i < textBlock->numLines; i++)
		if (_strnicmp(prefix, TextBlockLine(textBlock, i), strlen(prefix))==0) 
		{
			break;
		}
	return (i);
}

BOOL SearchLineTextBlock (TypTextBlock * textBlock, char *prefix)
{
	if (textBlock == NULL) 
		return (FALSE);
	return (iSearchLineTextBlock(textBlock, prefix) < textBlock->numLines);
}

BOOL GetHeaderLineTextBlock (char *content, TypTextBlock * textBlock, char *prefix, BOOL bZot /*= TRUE*/)
{
	unsigned long i;
	char *p;
	if (textBlock && (i=iSearchLineTextBlock(textBlock, prefix)) < textBlock->numLines) 
	{
		strcpy(content, TextBlockLine(textBlock, i) + strlen(prefix) + 1);
		for (p = content + strlen(content) - 1; p > content && (*p == '\r' || *p == '\n') ; p--)
			 *p = '\0';
		if (bZot)
			*(TextBlockLine(textBlock, i)) = '\0';
		return (TRUE);
	}
	return (FALSE);
}


BOOL ReconstructTextBlock (HWND hParentWnd, TypTextBlock **textBlock)
{
	TypTextBlock * headers;
	char *p;
	unsigned long i;
	int result = SUCCESS;

	if (*textBlock) 
	{
		headers = InitTextBlock (hParentWnd);
		for (i=0; i < (*textBlock)->numLines && result == SUCCESS; i++) 
		{
			if( (p = TextBlockLine((*textBlock), i)) )
				result = AddLineToTextBlock (headers, p);
		}
		if (result == SUCCESS) 
		{
			FreeTextBlock (*textBlock);
			*textBlock = headers;
		}
	}
	return (result);
}

char * GetDlgEditText (HWND hDlg, unsigned int iMessage)
{
	unsigned int size;
	char *newText;

#define EDIT_PAD 2

	size = (unsigned int) SendDlgItemMessage (hDlg, iMessage, WM_GETTEXTLENGTH, 0, 0L)
				 + EDIT_PAD;

	if ((newText = (char *) GlobalAllocPtr (GMEM_MOVEABLE, size * sizeof (char))) == NULL) 
	{
		WVMessageBox (hDlg, "Memory allocation failure", "Edit Text", MB_OK |MB_ICONHAND);
		return (NULL);
	}
	*newText = '\0';

	if (GetDlgItemText (hDlg, iMessage, (LPSTR) newText, size) == 0) 
	{
		WVMessageBox (hDlg, "Can't get text", "Edit Text", MB_OK | MB_ICONHAND);
		return (NULL);
	}

	return (newText);
}

