/* edit.c */

#include <windows.h>
#include <commdlg.h>
#include <ctype.h>
#include <assert.h>
#include "screen.h"

char *cInvertedArray;
int bMouseDown = FALSE;
int bSelection;

static int iLocStart;
static int iLocEnd;

void Edit_LbuttonDown(
	HWND hWnd,
	LPARAM lParam)
{
	SCREEN *pScr;
	HMENU hMenu;
	int iTmp;
	int iXlocStart;
	int iYlocStart;
	HDC hDC;
	
	pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE);
	assert(pScr != NULL);
	
	hDC = GetDC(hWnd);
	for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) {        
		if (cInvertedArray[iTmp]) {
			PatBlt(hDC, iTmp % pScr->width * pScr->cxChar,
				(int) (iTmp / pScr->width) * pScr->cyChar,
				pScr->cxChar, pScr->cyChar, DSTINVERT);                
			cInvertedArray[iTmp] = 0;
			}
	}
	bSelection = FALSE;
	hMenu = GetMenu(hWnd);
	EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED);
	ReleaseDC(hWnd, hDC);
	iXlocStart = (int) LOWORD(lParam) / pScr->cxChar;
	if (iXlocStart >= pScr->width)
		iXlocStart = pScr->width - 1;
	iYlocStart = (int) HIWORD(lParam) / pScr->cyChar;
	if (iYlocStart >= pScr->height)
		iYlocStart = pScr->height - 1;
	iLocStart = iXlocStart + iYlocStart * pScr->width;
	bMouseDown = TRUE;

} /* Edit_LbuttonDown */


void Edit_LbuttonUp(
	HWND hWnd,
	LPARAM lParam)
{
	SCREEN *pScr;
	int iTmp;
	int iTmp2;
	HMENU hMenu;
	
	bMouseDown = FALSE;
	if (bSelection)
		return;
	bSelection = TRUE;

	pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE);
	assert(pScr != NULL);

	iTmp = (int) LOWORD(lParam) / pScr->cxChar;
	if (iTmp >= pScr->width)
		iTmp = pScr->width - 1;
	iTmp2 = (int) HIWORD(lParam) / pScr->cyChar;
	if (iTmp2 >= pScr->height)
		iTmp2 = pScr->height - 1;
	iLocEnd = iTmp + iTmp2 * pScr->width;
	if (iLocEnd == iLocStart) {
		bSelection = FALSE;
	}
	else {
		hMenu = GetMenu(hWnd);
		EnableMenuItem(hMenu, IDM_COPY, MF_ENABLED);
	}    

} /* Edit_LbuttonUp */


void Edit_MouseMove(HWND hWnd, LPARAM lParam){
	SCREEN *pScr;
	int iTmp;
	int iTmp2;
	int iXlocCurr;
	int iYlocCurr;
	int iLocCurr;
	int iX;
	int iX2;
	int iY;
	int iY2;
	SCREENLINE *pScrLine;
	HDC hDC;

	pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE);
	assert(pScr != NULL);

	hDC = GetDC(hWnd);
	iXlocCurr = (int) LOWORD(lParam) / pScr->cxChar;
	if (iXlocCurr >= pScr->width)
		iXlocCurr = pScr->width - 1;
	iYlocCurr = (int) HIWORD(lParam) / pScr->cyChar;
	if (iYlocCurr >= pScr->height)
		iYlocCurr = pScr->height - 1;
	iLocCurr = iXlocCurr + (iYlocCurr * pScr->width);
	if (iLocCurr > iLocStart) {
		for (iTmp=0; iTmp < iLocStart; iTmp++) {        
			if (cInvertedArray[iTmp]) {
				PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar,
					(int) (iTmp / pScr->width) * pScr->cyChar,
					pScr->cxChar, pScr->cyChar, DSTINVERT);
				cInvertedArray[iTmp] = 0;
			}
		}
		iX = iLocStart % pScr->width;
		iY = (int) (iLocStart / pScr->width);
		iX2 = iLocCurr % pScr->width;
		iY2 = (int) (iLocCurr / pScr->width);
		if (iY == iY2) {
			pScrLine = GetScreenLineFromY(pScr, iY);
			for (iTmp2 = iX; iTmp2 < iX2; iTmp2++) {
				if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) {
					PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar,
						pScr->cxChar, pScr->cyChar, DSTINVERT);
					cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2];
				}
			}
		}            
		else {
			pScrLine = GetScreenLineFromY(pScr, iY);

			for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) {
				if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) {
					PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar,
						pScr->cxChar, pScr->cyChar, DSTINVERT);
					cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2];
				}
			}

			for (iTmp = iY + 1; iTmp < iY2; iTmp++) {
				pScrLine = GetScreenLineFromY(pScr, iTmp);
				for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) {
					if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) {
						PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar,
							pScr->cxChar, pScr->cyChar, DSTINVERT);
						cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2];
					}
				}
			}

			if (iY2 != iY) {
				pScrLine = GetScreenLineFromY(pScr, iY2);
				for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) {
					if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) {
						PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar,
							pScr->cxChar, pScr->cyChar, DSTINVERT);
						cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2];
					}    
				}    
			}                
		}

		for (iTmp = iLocCurr; iTmp < pScr->width * pScr->height; iTmp++) {        
			if (cInvertedArray[iTmp]) {
				PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar,
					pScr->cxChar, pScr->cyChar, DSTINVERT);                
				cInvertedArray[iTmp] = 0;
			}
		}
	}
	else { /* going backwards */
		for (iTmp = 0; iTmp < iLocCurr; iTmp++) {        
			if (cInvertedArray[iTmp]) {
				PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar,
					pScr->cxChar, pScr->cyChar, DSTINVERT);                
				cInvertedArray[iTmp] = 0;
			}
		}
		iX = iLocCurr % pScr->width;
		iY = (int) (iLocCurr / pScr->width);
		iX2 = (iLocStart % pScr->width);
		iY2 = (int) (iLocStart / pScr->width);
		if (iY == iY2) {
			pScrLine = GetScreenLineFromY(pScr, iY);
			for (iTmp2= iX; iTmp2 < iX2; iTmp2++) {
				if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) {
					PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar,
						pScr->cxChar, pScr->cyChar, DSTINVERT);
					cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2];
				}
			}
		}            
		else {
			pScrLine = GetScreenLineFromY(pScr, iY);
			for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) {
				if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) {
					PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar,
						pScr->cxChar, pScr->cyChar, DSTINVERT);
					cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2];
				}    
			}                
			for (iTmp = iY + 1; iTmp < iY2; iTmp++) {
				pScrLine = GetScreenLineFromY(pScr, iTmp);
				for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) {
					if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) {
						PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar,
							pScr->cxChar, pScr->cyChar, DSTINVERT);
						cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2];
					}
				}
			}
			if (iY2 != iY) {
				pScrLine = GetScreenLineFromY(pScr, iY2);
				for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) {
					if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) {
						PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar,
							pScr->cxChar, pScr->cyChar, DSTINVERT);
						cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2];
					}    
				}    
			}                
		}    
		for (iTmp = iLocStart; iTmp < pScr->width * pScr->height; iTmp++) {        
			if (cInvertedArray[iTmp]) {
				PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar,
					pScr->cxChar, pScr->cyChar, DSTINVERT);
				cInvertedArray[iTmp] = 0;
			}    
		}
	}            
	ReleaseDC(hWnd, hDC);
} /* Edit_MouseMove */


void Edit_ClearSelection(
	SCREEN *pScr)
{
	int iTmp;
	HDC hDC;
	HMENU hMenu;

	hDC = GetDC(pScr->hWnd);
	for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) {
		if (cInvertedArray[iTmp]) {
			PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar,
				(int) (iTmp / pScr->width) * pScr->cyChar,
				pScr->cxChar, pScr->cyChar, DSTINVERT);
			cInvertedArray[iTmp] = 0;
		}
	}
	bSelection = FALSE;
	hMenu=GetMenu(pScr->hWnd);
	EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED);    
	ReleaseDC(pScr->hWnd, hDC);
} /* Edit_ClearSelection */


void Edit_Copy(
	HWND hWnd)
{
	int iTmp,iIdx;
	HGLOBAL hCutBuffer;
	LPSTR lpCutBuffer;
	SCREEN *pScr;
	
	pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE);
	assert(pScr != NULL);

	hCutBuffer= GlobalAlloc(GHND, (DWORD) (pScr->width * pScr->height + 1));
	lpCutBuffer= GlobalLock(hCutBuffer);

	if (iLocStart > iLocEnd) { /* swap variables */
		iTmp = iLocStart;
		iLocStart = iLocEnd;
		iLocEnd = iLocStart;
	}
	iTmp = iLocStart;
	iIdx = 0;
	while (iTmp < iLocEnd) {
		if (!cInvertedArray[iTmp]) {
			lpCutBuffer[iIdx++] = '\r';
			lpCutBuffer[iIdx++] = '\n';
			iTmp = (((int) (iTmp / pScr->width)) + 1) * pScr->width;
			continue;
		}
		lpCutBuffer[iIdx++] = cInvertedArray[iTmp++];
	}
	lpCutBuffer[iIdx] = 0;
	GlobalUnlock(hCutBuffer);
	OpenClipboard(hWnd);
	EmptyClipboard();
	SetClipboardData(CF_TEXT, hCutBuffer);
	CloseClipboard();

} /* Edit_Copy */


void Edit_Paste(
	HWND hWnd)
{
	HGLOBAL hClipMemory;
	static HGLOBAL hMyClipBuffer;
	LPSTR lpClipMemory;
	LPSTR lpMyClipBuffer;
	SCREEN *pScr;                              
	
	if (hMyClipBuffer)
		GlobalFree(hMyClipBuffer);
	OpenClipboard(hWnd);
	hClipMemory = GetClipboardData(CF_TEXT);
	hMyClipBuffer = GlobalAlloc(GHND, GlobalSize(hClipMemory));
	lpMyClipBuffer = GlobalLock(hMyClipBuffer);
	lpClipMemory= GlobalLock(hClipMemory);
	
	pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE);
	assert(pScr != NULL);

	lstrcpy(lpMyClipBuffer, lpClipMemory);
//    OutputDebugString(lpMyClipBuffer);
	PostMessage(pScr->hwndTel, WM_MYSCREENBLOCK, (WPARAM) hMyClipBuffer, (LPARAM) pScr);
	CloseClipboard();                    
	GlobalUnlock(hClipMemory);
	GlobalUnlock(hMyClipBuffer);    

} /* Edit_Paste */


void Edit_LbuttonDblclk(
	HWND hWnd,
	LPARAM lParam)
{
	HDC hDC;
	SCREEN *pScr;
	int iTmp;
	int iTmp2;
	int iXlocStart;
	int iYloc;
	SCREENLINE *pScrLine;
		
	pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE);
	assert(pScr != NULL);
	
	hDC = GetDC(hWnd);
	for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) {        
		if (cInvertedArray[iTmp]) {
			PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar,
				(int) (iTmp / pScr->width) * pScr->cyChar,
				pScr->cxChar, pScr->cyChar, DSTINVERT);
			cInvertedArray[iTmp] = 0;
		}
	}
	bSelection = FALSE;
	iXlocStart = (int) LOWORD(lParam) / pScr->cxChar;
	if (iXlocStart >= pScr->width)
		iXlocStart = pScr->width - 1;
	iYloc = (int) HIWORD(lParam) / pScr->cyChar;
	if (iYloc >= pScr->height)
		iYloc = pScr->height - 1;
	iLocStart = iXlocStart + (iYloc * pScr->width);

	pScrLine = GetScreenLineFromY(pScr, iYloc);

	iTmp = iXlocStart;
	while (isalnum((int) pScrLine->text[iTmp])) {
		PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar,
			 pScr->cxChar, pScr->cyChar, DSTINVERT);
		cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp];
		iTmp++;
	}
	iTmp2 = iXlocStart - 1;
	while (isalnum((int) pScrLine->text[iTmp2])) {
		PatBlt(hDC, iTmp2 * pScr->cxChar, iYloc * pScr->cyChar,
			 pScr->cxChar, pScr->cyChar, DSTINVERT);
		cInvertedArray[iTmp2 + (iYloc * pScr->width)] = pScrLine->text[iTmp2];
		iTmp2--;
	}
	iLocStart = (iTmp2 + 1) + (iYloc * pScr->width);
	iLocEnd = iTmp + (iYloc * pScr->width);

	bSelection = TRUE;
	ReleaseDC(hWnd, hDC);

} /* Edit_LbuttonDblclk */


void Edit_TripleClick(
	HWND hWnd,
	LPARAM lParam)
{
	HDC hDC;
	SCREEN *pScr;
	int iTmp;
	int iYloc;
	SCREENLINE *pScrLine;
		
//    OutputDebugString("Triple Click \r\n");
	pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE);
	assert(pScr != NULL);
	
	hDC = GetDC(hWnd);
	for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) {        
		if (cInvertedArray[iTmp]) {
			PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar,
				(int) (iTmp / pScr->width) * pScr->cyChar,
				pScr->cxChar, pScr->cyChar, DSTINVERT);
			cInvertedArray[iTmp] = 0;
		}    
	}
	bSelection = FALSE;
	iYloc = (int) HIWORD(lParam) / pScr->cyChar;
	if (iYloc >= pScr->height)
		iYloc = pScr->height - 1;
	iLocStart = iYloc * pScr->width;
	
	pScrLine = GetScreenLineFromY(pScr, iYloc);
	
	for (iTmp = 0; iTmp < pScr->width; iTmp++) {
		if (pScrLine->text[iTmp]) {
			PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar,
				 pScr->cxChar, pScr->cyChar, DSTINVERT);
			cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp];
		}
		else
			break;
	}
	iLocEnd = iTmp + (iYloc * pScr->width);

	bSelection = TRUE;
	ReleaseDC(hWnd, hDC);

} /* Edit_TripleClick */
