/* 
CCIDE
Copyright 2001-2011 David Lindauer.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

You may contact the author at:
	mailto::camille@bluegrass.net
 */
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <richedit.h>
#include <stdio.h>
#include "helpid.h"
#include "header.h"
#include "codecomp.h"
#include "regexp.h"
#include <ctype.h>
//#include "..\gnu_regex\regex.h"

#ifndef __CCDL__
    #ifndef LVS_EX_CHECKBOXES
        #define LVS_EX_CHECKBOXES 4
        #define LVM_FIRST 0x1000
        #define LVM_SETEXTENDEDLISTVIEWSTYLE (LVM_FIRST + 54)   
            // optional wParam == mask
        #define ListView_SetExtendedListViewStyle(hwndLV, dw)\
        (DWORD)SendMessage((hwndLV), LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dw)
        #define ListView_SetCheckState(hwndLV, i, fCheck) \
        ListView_SetItemState(hwndLV, i, INDEXTOSTATEIMAGEMASK((fCheck)?2:1),
            LVIS_STATEIMAGEMASK)
        #define ListView_GetCheckState(hwndLV, i) \
        ((((UINT)(SendMessage((hwndLV), LVM_GETITEMSTATE, (WPARAM)(i),
            LVIS_STATEIMAGEMASK))) >> 12) -1)
    #endif 
#endif 

#define EDITOR_OFFSET 35

extern POINT menupos;
extern DWORD maximizeClient;
extern HWND hwndSourceTab;
extern LOGFONT EditFont;
extern HINSTANCE hInstance;
extern HWND hwndClient, hwndStatus, hwndFrame, hwndASM;
extern HANDLE hMenuMain;
extern int iFindMessage;
extern char szSourceFilter[];
extern char szNewFileFilter[];
extern enum DebugState uState;
extern PROJLIST *projectList;
extern char highlightText[256] ;
extern int highlightCaseSensitive;
extern int highlightWholeWord;

extern int tabs;
HANDLE editHeap;
HWND hwndFind;
char szDrawClassName[] = "xccDrawClass";
char szUntitled[] = "Untitled";
int numberofdrawwindows;
int editFlags = BACKUP_FILES ;
int findflags = 12;
int replaceflags = 4;
int completionEnabled = TRUE;

DWINFO *newInfo;
HANDLE children[MAX_CHILDREN];
HWND lastActiveEditWindow;

char *findhist[MAX_COMBO_HISTORY];
char *replacehist[MAX_COMBO_HISTORY];

static HWND currentParsing;
static HBITMAP pcBitmap, stoppcBitmap;
static HBITMAP tagBmps[TAG_MAX];
static char finding, findbuffer[256], replacebuffer[256], findbuffer2[256];
static FINDREPLACE find;
static FINDREPLACE replace;
static int findpos, found, lastfound;
#define PARSE_LIST_SIZE 100
static HWND parselist[PARSE_LIST_SIZE];

void recolorize(DWINFO *ptr);

int xstricmpz(char *str1, char *str2)
{
    while (*str2)
        if (toupper(*str1++) != toupper(*str2++))
            return 1;
    return  *str1 !=  *str2;
} int xstricmp(char *str1, char *str2)
{
    while (*str2)
        if (toupper(*str1++) != toupper(*str2++))
            return 1;
    return 0;
}

//-------------------------------------------------------------------------

char *stristr(char *str1, char *str2)
{
    int l = strlen(str2);
    while (*str1)
    {
        if (!xstricmp(str1, str2))
            return str1;
        str1++;
    }
    return 0;
}
void ResetEditTitles(void )
{
	int i;
    for (i = 0; i < numberofdrawwindows; i++)
    {
        PostMessage(children[i], WM_COMMAND, ID_REDRAWSTATUS, 0);
	}
}

void rehighlight(char *text, int whole, int casesensitive)
{
	int i;
	strcpy(highlightText, text);
	highlightWholeWord = whole;
	highlightCaseSensitive = casesensitive;
    for (i = 0; i < numberofdrawwindows; i++)
    {
		DWINFO *data = (DWINFO *)GetWindowLong(children[i], 0);
		recolorize(data);
	}
}
//-------------------------------------------------------------------------

void ApplyFontSettings(LPLOGFONT lf)
{
    int i;
    memcpy(&EditFont, lf, sizeof(EditFont));
    for (i = 0; i < numberofdrawwindows; i++)
    {
        HFONT fnt = CreateFontIndirect(&EditFont);
        PostMessage(GetDlgItem(children[i], ID_EDITCHILD), WM_SETFONT, (WPARAM)
            fnt, 0);
    }
}

//-------------------------------------------------------------------------

void InvalidateByName(char *name)
{
    int i;
    DWINFO info;
    strcpy(info.dwName, name);
    for (i = 0; i < numberofdrawwindows; i++)
        if (SendMessage(children[i], WM_COMMAND, ID_QUERYHASFILE, (LPARAM)
            &info))
            InvalidateRect(children[i], 0, 0);
}

//-------------------------------------------------------------------------

void ApplyEditSettings(void)
{
    int i;
    for (i = 0; i < numberofdrawwindows; i++)
	{
        PostMessage(GetDlgItem(children[i], ID_EDITCHILD), WM_SETEDITORSETTINGS,
            0, 0);
		PostMessage(children[i], WM_SETLINENUMBERMODE, 0, 0);
	}

}

//-------------------------------------------------------------------------

int ApplyBreakAddress(char *module, int linenum)
{
    char nmodule[260];
    int i;
    nmodule[0] = 0;
    TagBreakpoint(module, linenum);
    if (linenum)
    {
        char *p;
        static DWINFO x;
        FindModuleName(nmodule, module);
		if (nmodule[0])
		{
	        strcpy(x.dwName, nmodule);
	        p = strrchr(nmodule, '\\');
	        if (p)
	            strcpy(x.dwTitle, p + 1);
	        else
	            strcpy(x.dwTitle, nmodule);
	        x.dwLineNo = BPLine(x.dwName);
	        x.logMRU = TRUE;
	        x.newFile = FALSE ;
	        CreateDrawWindow(&x, TRUE);
		}
    }

}

//-------------------------------------------------------------------------

static int FileAttributes(char *name)
{
    int rv = GetFileAttributes(name);
    if (rv ==  - 1)
    {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
            return 0;
        return  - 1; // any other error, it is read only file
    }
    else
        return rv;
}

//-------------------------------------------------------------------------

static int CreateFileSaveData(HWND hwnd, int changed)
{
    int items = 0;
    int i;
    LV_ITEM item;
    RECT r;
    HWND hwndLV = GetDlgItem(hwnd, IDC_FILELIST);
    LV_COLUMN lvC;
    ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_CHECKBOXES);

    GetWindowRect(hwndLV, &r);
    lvC.mask = LVCF_WIDTH | LVCF_SUBITEM;
    lvC.cx = 20;
    lvC.iSubItem = 0;
    ListView_InsertColumn(hwndLV, 0, &lvC);
    lvC.mask = LVCF_WIDTH | LVCF_SUBITEM;
    lvC.cx = 32;
    lvC.iSubItem = 1;
    ListView_InsertColumn(hwndLV, 1, &lvC);
    lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
    lvC.fmt = LVCFMT_LEFT;
    lvC.cx = r.right - r.left - 56;
    lvC.iSubItem = 2;
    ListView_InsertColumn(hwndLV, 2, &lvC);


    for (i = 0; i < numberofdrawwindows; i++)
    {
        DWINFO *ptr = (DWINFO*)GetWindowLong(children[i], 0);
        int rv;
        FILETIME time;
        if (changed)
        {
            int a = FileAttributes(ptr->dwName);
            rv = FALSE;
            if (a ==  - 1)
                a = 0;
            if (FileTime(&time, ptr->dwName))
            {
                rv = (time.dwHighDateTime != ptr->time.dwHighDateTime ||
                    time.dwLowDateTime != ptr->time.dwLowDateTime);
                ptr->time = time;
            }
            if (a &FILE_ATTRIBUTE_READONLY)
                SendMessage(ptr->dwHandle, EM_SETREADONLY, 1, 0);
            else
                SendMessage(ptr->dwHandle, EM_SETREADONLY, 0, 0);
        }
        else
            rv = SendMessage(ptr->dwHandle, EM_GETMODIFY, 0, 0);
        if (rv)
        {
            int v;
            item.iItem = items++;
            item.iSubItem = 0;
            item.mask = LVIF_PARAM;
            item.lParam = (LPARAM)i;
            item.pszText = ""; // LPSTR_TEXTCALLBACK ;
            v = ListView_InsertItem(hwndLV, &item);
            ListView_SetCheckState(hwndLV, v, TRUE);
        }
    }

    return items;
}

static void SetOKText(HWND hwnd, char *text)
{
    HWND hwndLV = GetDlgItem(hwnd, IDC_FILELIST);
	HWND okbut = GetDlgItem(hwnd, IDOK);
    int i;
    for (i = 0;; i++)
    {
	    LV_ITEM item;
        item.iItem = i;
        item.iSubItem = 0;
        item.mask = LVIF_PARAM;
        if (!ListView_GetItem(hwndLV, &item))
            break;
        if (ListView_GetCheckState(hwndLV, i))
		{
			SetWindowText(okbut, text);
			return;
		}
    }
	SetWindowText(okbut, "Ok");
}
//-------------------------------------------------------------------------

static void ParseFileSaveData(HWND hwnd, UINT wParam, int changed, char *text)
{
    LV_ITEM item;
    HWND hwndLV = GetDlgItem(hwnd, IDC_FILELIST);
    int i;
    for (i = 0;; i++)
    {
        DWINFO *ptr;
        item.iItem = i;
        item.iSubItem = 0;
        item.mask = LVIF_PARAM;
        if (!ListView_GetItem(hwndLV, &item))
            break;
        ptr = (DWINFO*)GetWindowLong(children[item.lParam], 0);
        switch (wParam)
        {
            case IDOK:
                if (changed)
                {
                    if (ListView_GetCheckState(hwndLV, i))
                        LoadFile(children[item.lParam], ptr);
                }
                else
                    if (ListView_GetCheckState(hwndLV, i))
                        SendMessage(children[item.lParam], WM_COMMAND, IDM_SAVE,
                            0);
                    else
                {
                    TagLinesAdjust(ptr->dwName, TAGM_DISCARDFILE);
                }
                break;
            case IDC_SELECTALL:
            case IDC_DESELECTALL:
                ListView_SetCheckState(hwndLV, i, wParam == IDC_SELECTALL ? 1 :
                    0);
                break;
        }

    }
    if (wParam == IDC_SELECTALL || wParam == IDC_DESELECTALL)
		SetOKText(hwnd, text);
}

//-------------------------------------------------------------------------

long APIENTRY FileSaveProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
    lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
            if (!CreateFileSaveData(hwnd, FALSE))
                EndDialog(hwnd, 1);
            else
                CenterWindow(hwnd);
            return 0;
        case WM_NOTIFY:
            if (wParam == IDC_FILELIST)
            {
                if (((LPNMHDR)lParam)->code == LVN_GETDISPINFO)
                {
                    LV_DISPINFO *plvdi = (LV_DISPINFO*)lParam;
                    DWINFO *ptr;
                    plvdi->item.mask |= LVIF_TEXT | LVIF_DI_SETITEM;
                    plvdi->item.mask &= ~LVIF_STATE;
                    switch (plvdi->item.iSubItem)
                    {
                    case 2:
                        ptr = (DWINFO*)GetWindowLong(children[plvdi
                            ->item.lParam], 0);
                        plvdi->item.pszText = ptr->dwTitle;
                        break;
                    default:
                        plvdi->item.pszText = "";
                        break;
                    }
                }
				else if (((LPNMHDR)lParam)->code == LVN_ITEMCHANGED)
                {
					SetOKText(hwnd, "Save");
				}
            }
            return 0;
        case WM_COMMAND:
            switch (wParam &0xffff)
            {
            case IDOK:
                ParseFileSaveData(hwnd, IDOK, FALSE,"");
                EndDialog(hwnd, IDOK);
                break;
            case IDCANCEL:
                EndDialog(hwnd, IDCANCEL);
                break;
            case IDC_SELECTALL:
                ParseFileSaveData(hwnd, IDC_SELECTALL, FALSE, "Save");
                break;
            case IDC_DESELECTALL:
                ParseFileSaveData(hwnd, IDC_DESELECTALL, FALSE, "Save");
                break;
            case IDHELP:
                ContextHelp(IDH_SAVE_FILE_DIALOG);
                break;
            }
            break;
        case WM_CLOSE:
            PostMessage(hwnd, WM_COMMAND, IDCANCEL, 0);
            break;
    }
    return 0;
}

//-------------------------------------------------------------------------

long APIENTRY FileChangeProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
    lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
            if (!CreateFileSaveData(hwnd, TRUE))
                EndDialog(hwnd, 1);
            else
                CenterWindow(hwnd);
            return 0;
        case WM_NOTIFY:
            if (wParam == IDC_FILELIST)
            {
                NMITEMACTIVATE *ia;
                LV_ITEM item;
                int state;
                if (((LPNMHDR)lParam)->code == LVN_GETDISPINFO)
                {
                    LV_DISPINFO *plvdi = (LV_DISPINFO*)lParam;
                    DWINFO *ptr;
                    plvdi->item.mask |= LVIF_TEXT | LVIF_DI_SETITEM;
                    plvdi->item.mask &= ~LVIF_IMAGE;
                    switch (plvdi->item.iSubItem)
                    {
                    case 2:
                        ptr = (DWINFO*)GetWindowLong(children[plvdi
                            ->item.lParam], 0);
                        plvdi->item.pszText = ptr->dwTitle;
                        break;
                    default:
                        plvdi->item.pszText = "";
                        break;
                    }
                }
				else if (((LPNMHDR)lParam)->code == LVN_ITEMCHANGED)
                {            
					SetOKText(hwnd, "Reload");
				}
			}
            break;
        case WM_COMMAND:
            switch (wParam &0xffff)
            {
            case IDOK:
                ParseFileSaveData(hwnd, IDOK, TRUE,"");
                EndDialog(hwnd, IDOK);
                break;
            case IDCANCEL:
                EndDialog(hwnd, IDCANCEL);
                break;
            case IDC_SELECTALL:
                ParseFileSaveData(hwnd, IDC_SELECTALL, TRUE, "Reload");
                break;
            case IDC_DESELECTALL:
                ParseFileSaveData(hwnd, IDC_DESELECTALL, TRUE, "Reload");
                break;
            case IDHELP:
                ContextHelp(IDH_RELOAD_FILE_DIALOG);
                break;
            }
            break;
        case WM_CLOSE:
            PostMessage(hwnd, WM_COMMAND, IDCANCEL, 0);
            break;
    }
    return 0;
}

//-------------------------------------------------------------------------

void PASCAL CheckEditWindowChangedThread(void *aa)
{
    static int sem;
    if (!sem)
    {
        sem++;
        DialogBoxParam(hInstance, "DLG_FILECHANGE", 0, (DLGPROC)FileChangeProc,
            0);
        sem--;
    }
}

//-------------------------------------------------------------------------

void CheckEditWindowChanged(void)
{
    DWORD threadhand;
    CloseHandle(CreateThread(0,0,(LPTHREAD_START_ROUTINE)CheckEditWindowChangedThread,
							 (LPVOID)NULL,0,&threadhand)) ;
}

//-------------------------------------------------------------------------

int QuerySaveAll(void)
{
    return DialogBoxParam(hInstance, "DLG_FILESAVE", 0, (DLGPROC)FileSaveProc,
        0);
}

//-------------------------------------------------------------------------

void SaveDrawAll(void)
{
    int i;
    for (i = 0; i < numberofdrawwindows; i++)
    {
        DWINFO *ptr = (DWINFO*)GetWindowLong(children[i], 0);
        if (SendMessage(ptr->dwHandle, EM_GETMODIFY, 0, 0))
            SendMessage(children[i], WM_COMMAND, IDM_SAVE, 0);
    }
}

//-------------------------------------------------------------------------

int AnyModified(void)
{
    int i, rv = 0;
    for (i = 0; i < numberofdrawwindows; i++)
    {
        DWINFO *ptr = (DWINFO*)GetWindowLong(children[i], 0);
        rv |= SendMessage(ptr->dwHandle, EM_GETMODIFY, 0, 0);
    }
    return rv;
}

//-------------------------------------------------------------------------

void CloseAll(void)
{
    int i;
    for (i = numberofdrawwindows - 1; i >= 0; i--)
        ShowWindow(children[i], SW_HIDE);
    for (i = numberofdrawwindows - 1; i >= 0; i--)
        PostMessage(children[i], WM_CLOSE, 0, 0);
}

//-------------------------------------------------------------------------

void RedrawAllBreakpoints(void)
{
    int i;
    for (i = numberofdrawwindows - 1; i >= 0; i--)
        InvalidateRect(children[i], 0, 0);
}

//-------------------------------------------------------------------------

char *GetEditData(HWND hwnd)
{
    int l;
    char *buf;
    l = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
//	buf = HeapAlloc(editHeap, HEAP_ZERO_MEMORY, l + 1);
	buf = calloc(l+1, 1);
    if (!buf)
    {
        return 0;
    }
    SendMessage(hwnd, WM_GETTEXT, l + 1, (LPARAM)buf);
    return buf;
}

void FreeEditData(char *buf)
{
	free(buf);
//	HeapFree(editHeap, 0, buf);
//	HeapCompact(editHeap, 0);
}
//-------------------------------------------------------------------------

int SetEditData(HWND hwnd, char *buf)
{
    SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), WM_SETTEXT, 0, (LPARAM)buf);
    FreeEditData(buf);
    return TRUE;
}

//-------------------------------------------------------------------------

void backup(char *name)
{
    char newname[256], buffer[512];
    char *s;
    HANDLE in, out;
    int size;
    BY_HANDLE_FILE_INFORMATION info;
    strcpy(newname, name);
    s = strrchr(newname, '.');
    if (s)
        if (!xstricmp(s, ".cws"))
            strcpy(s, ".cwb");
        else if (!xstricmp(s, ".ctg"))
            strcpy(s, ".ctb");
        else
            strcpy(s, ".bak");
    else
        strcat(newname, ".bak");

    in = CreateFile(name, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
    if (in == INVALID_HANDLE_VALUE)
        return ;
    if (!GetFileInformationByHandle(in, &info))
    {
        CloseHandle(in);
        return ;
    }
    out = CreateFile(newname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    if (out == INVALID_HANDLE_VALUE)
    {
        ExtendedMessageBox("File Error", MB_SETFOREGROUND | MB_SYSTEMMODAL, 
            "Backup file is not writeable");
        CloseHandle(in);
        return ;
    }
    while (1)
    {
        DWORD read, written;
        if (!ReadFile(in, buffer, 512, &read, 0) || !read)
            break;
        WriteFile(out, buffer, read, &written, 0);
    }
    SetFileTime(out, &info.ftCreationTime, &info.ftLastAccessTime,
        &info.ftLastWriteTime);
    CloseHandle(out);
    CloseHandle(in);
}

//-------------------------------------------------------------------------

int SaveFile(HWND hwnd, DWINFO *info)
{
    char *buf = GetEditData(GetDlgItem(hwnd, ID_EDITCHILD));
    FILE *out;
    int l, i;

    if (editFlags &BACKUP_FILES)
        backup(info->dwName);
    if (!buf)
        return FALSE;
    #ifdef OLD_EDIT_FORMAT
        out = fopen(info->dwName, "wb");
    #else 
        out = fopen(info->dwName, "w");
    #endif 
    if (!out)
    {
        ExtendedMessageBox("File Error", MB_SETFOREGROUND | MB_SYSTEMMODAL, 
            "Output file is not writeable");
        free(buf);
        return FALSE;
    }
    fputs(buf, out);
    fclose(out);
    FreeEditData(buf);
    FileTime(&info->time, info->dwName);
    return TRUE;
}

//-------------------------------------------------------------------------

int LoadFile(HWND hwnd, DWINFO *info)
{
    long size;
    char *buf;
    #ifdef OLD_EDIT_FORMAT
        FILE *in = fopen(info->dwName, "rb");
    #else 
        FILE *in = fopen(info->dwName, "r");
    #endif 
    if (!in)
    {
        ShowWindow(info->dwHandle, SW_SHOW);
        return FALSE;
    }
    fseek(in, 0L, SEEK_END);
    size = ftell(in);
//	buf = HeapAlloc(editHeap, HEAP_ZERO_MEMORY, size + 1);
	buf = calloc(size+1, 1);
    if (!buf)
    {
        fclose(in);
        ShowWindow(info->dwHandle, SW_SHOW);
        return FALSE;
    }
    fseek(in, 0L, SEEK_SET);
    size = fread(buf, 1, size, in);
    if (size < 0)
        size = 0;
    buf[size] = 0;
    fclose(in);
    SetEditData(hwnd, buf);
    SendMessage(info->dwHandle, EM_SETMODIFY, 0, 0);
    if (FileAttributes(info->dwName) &FILE_ATTRIBUTE_READONLY)
        SendMessage(info->dwHandle, EM_SETREADONLY, 1, 0);
    FileTime(&info->time, info->dwName);
    return TRUE;

}

//-------------------------------------------------------------------------

#ifdef TEST
    BOOL CALLBACK enumfunc(HWND wnd, int param)
    {
        FILE *fil = fopen("q", "a");
        char buf[256], buf2[256];
        int id = GetWindowLong(wnd, GWL_ID);
        GetClassName(wnd, buf, 256);
        GetWindowText(wnd, buf2, 256);
        fprintf(fil, "%s(%s): %d\n", buf2, buf, id);
        fclose(fil);
        return TRUE;
    }
#endif 
/* hook function translates CBN style messaging to EN style messaging */
BOOL CALLBACK findHook(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    if (iMessage == WM_COMMAND)
    {
        int l = wParam >> 16;
        if (l == CBN_SELENDOK)
        {
            SendMessage((HWND)lParam, WM_SETMODIFY, 1, 0); 
                // we do this so the edit box will have something in it when the dialog proc checks it
        }
        if (l == CBN_EDITUPDATE || l == CBN_SELENDOK)
        {
            SendMessage(hwnd, WM_COMMAND, (EN_UPDATE << 16) + (wParam &0xffff),
                lParam);
        }
        if (l == CBN_EDITCHANGE || l == CBN_SELENDOK)
        {
            SendMessage(hwnd, WM_COMMAND, (EN_CHANGE << 16) + (wParam &0xffff),
                lParam);
        }
        if ((wParam &0xffff) == IDCANCEL)
            goto join;
        if ((wParam &0xffff) == IDOK && finding)
		{
			char buf[256];
			buf[0] = buf[255] = 0;
			PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
			SendDlgItemMessage(hwnd, 1152, WM_GETTEXT, 255, (LPARAM)buf);
			rehighlight(buf , IsDlgButtonChecked(hwnd, 1040), IsDlgButtonChecked(hwnd, 1041));
		}
    }
    if (iMessage == WM_SYSCOMMAND)
    if (wParam == SC_CLOSE)
    {
        join: if (finding)
        {
            findflags = 0;
            if (IsDlgButtonChecked(hwnd, 1040))
                findflags++;
            if (IsDlgButtonChecked(hwnd, 1041))
                findflags += 2;
            if (IsDlgButtonChecked(hwnd, 990))
                findflags += 4;
            if (IsWindow(GetDlgItem(hwnd, 1057)) && IsDlgButtonChecked(hwnd,
                1057))
                findflags += 8;
//            IntToProfile("FindFlags", findflags);
        }
        else
        {
            replaceflags = 0;
            if (IsDlgButtonChecked(hwnd, 1040))
                replaceflags++;
            if (IsDlgButtonChecked(hwnd, 1041))
                replaceflags += 2;
            if (IsDlgButtonChecked(hwnd, 990))
                replaceflags += 4;
            if (IsWindow(GetDlgItem(hwnd, 1057)) && IsDlgButtonChecked(hwnd,
                1057))
                replaceflags += 8;
//            IntToProfile("ReplaceFlags", replaceflags);
        }
        hwndFind = 0;
    }
    if (iMessage == WM_INITDIALOG)
    {
        if (finding)
        {
            if (findflags &4)
                CheckDlgButton(hwnd, 990, 1);
        }
        else
        {
            if (replaceflags &4)
                CheckDlgButton(hwnd, 990, 1);
        }
        return 1;
    }
    else
        return 0;
}

//-------------------------------------------------------------------------

void PopFindString(HWND hwnd)
{
    char buf[256];
    HWND hwndedit;
    charinfo a;
    if (IsWindow(hwndFind))
    {
        SetFocus(hwndFind);
        return ;
    }
    if (GetWordFromPos(GetDlgItem(hwnd, ID_EDITCHILD), buf,  - 1, 0, 0, 0) &&
        buf[0])
        strcpy(findbuffer, buf);
    find.lStructSize = sizeof(find);
    find.hwndOwner = hwndFrame;
    find.hInstance = hInstance;
    find.Flags = FR_ENABLETEMPLATE | FR_ENABLEHOOK;
    if (findflags &1)
        find.Flags |= FR_WHOLEWORD;
    if (findflags &2)
        find.Flags |= FR_MATCHCASE;
//    if (findflags &8)
    find.Flags |= FR_DOWN;
    find.lpstrFindWhat = findbuffer;
    find.lpstrReplaceWith = 0;
    find .wFindWhatLen = 256;
    find .wReplaceWithLen = 0;
    find.lpTemplateName = "FINDDLG";
    find.lpfnHook = findHook;
    finding = TRUE;
    hwndFind = FindText(&find);
    hwndedit = GetDlgItem(hwndFind, 1152);
    SubClassHistoryCombo(hwndedit);
    SendMessage(hwndedit, WM_SETHISTORY, 0, (LPARAM)findhist);
    //   EnumChildWindows(hwndFind, (WNDENUMPROC)enumfunc,0) ;
    lastfound =  - 1;
    //   SendMessage(GetDlgItem(hwnd,ID_EDITCHILD),EM_GETSEL, (WPARAM)&findpos,0) ;
    SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXGETSEL, 0, (LPARAM) &a);
    findpos = a.min;
}

//-------------------------------------------------------------------------

void PopReplaceString(HWND hwnd)
{
    DWINFO *p = (DWINFO*)GetWindowLong(hwnd, 0);
    char buf[256];
    HWND hwndedit;
    charinfo a;
    if (IsWindow(hwndFind))
    {
        SetFocus(hwndFind);
        return ;
    }
    //   if (GetWordFromPos(GetDlgItem(hwnd,ID_EDITCHILD),buf,-1,0,0,0) && buf[0])
    //      strcpy(findbuffer2,buf) ;
    replace.lStructSize = sizeof(replace);
    replace.hwndOwner = hwndFrame;
    replace.hInstance = hInstance;
    replace.Flags = FR_ENABLETEMPLATE | FR_ENABLEHOOK | FR_DOWN;
    if (replaceflags &1)
        replace.Flags |= FR_WHOLEWORD;
    if (replaceflags &2)
        replace.Flags |= FR_MATCHCASE;
    replace.lpstrFindWhat = findbuffer2;
    replace.lpstrReplaceWith = replacebuffer;
    replace .wFindWhatLen = 256;
    replace .wReplaceWithLen = 256;
    replace.lpTemplateName = "REPLACEDLG";
    replace.lpfnHook = findHook;
    finding = FALSE;
    hwndFind = ReplaceText(&replace);
    hwndedit = GetDlgItem(hwndFind, 1152);
    SubClassHistoryCombo(hwndedit);
    SendMessage(hwndedit, WM_SETHISTORY, 0, (LPARAM)findhist);
    hwndedit = GetDlgItem(hwndFind, 1153);
    SubClassHistoryCombo(hwndedit);
    SendMessage(hwndedit, WM_SETHISTORY, 0, (LPARAM)replacehist);

    lastfound =  - 1;
    SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXGETSEL, 0, (LPARAM) &a);
    findpos = a.min;
    if (a.min != a.max)
        CheckRadioButton(hwndFind, IDC_RADIO_ALL_TEXT, IDC_RADIO_SELECTED_TEXT,
            IDC_RADIO_SELECTED_TEXT);
    else
        CheckRadioButton(hwndFind, IDC_RADIO_ALL_TEXT, IDC_RADIO_SELECTED_TEXT,
            IDC_RADIO_ALL_TEXT);
}

//-------------------------------------------------------------------------

static int xfind(FINDREPLACE *find, char *buf, int pos, int *len,
    RE_CONTEXT **r, int regular)
{
    int flags = find->Flags;
    int i;
    if (!find->lpstrFindWhat)
        return  - 1;

    if (pos < 0)
        pos = 0;

    *len = strlen(find->lpstrFindWhat);
    while (TRUE)
    {
		if (regular)
		{
				RE_CONTEXT *context;
				context = re_init(find->lpstrFindWhat, RE_F_REGULAR | 
								  ((flags & FR_MATCHCASE) ? 0 : RE_F_INSENSITIVE) |
								  ((flags & FR_WHOLEWORD) ? RE_F_WORD : 0), NULL);
				if (!context)
				{
                    ExtendedMessageBox("Error",
                        MB_SETFOREGROUND | MB_SYSTEMMODAL, "There is a problem with the regular expression");
                    return  - 1;
				}
                if (flags &FR_DOWN)
					i = re_matches(context, buf, pos, strlen(buf));
				else
					i = re_matches(context, buf, pos, 0);
				if (!i)
					return -1;
				*len = context->m_eo - context->m_so;
				pos += context->m_so + (int)buf;
				if (!r)
					re_free(context);
				else
					*r = context;
        }
        else if (flags &FR_DOWN)
        {
            if (flags &FR_MATCHCASE)
                pos = (int)strstr(buf + pos, find->lpstrFindWhat);
            else
                pos = (int)stristr(buf + pos, find->lpstrFindWhat);
        }
        else
        {
            do
            {
                int l = strlen(find->lpstrFindWhat);
                if (flags &FR_MATCHCASE)
                {
                    if (!strncmp(buf + pos, find->lpstrFindWhat, l))
                        break;
                }
                else
                    if (!strnicmp(buf + pos, find->lpstrFindWhat, l))
                        break;
                pos--;
            }
            while (pos >= 0);
            if (pos < 0)
                pos = 0;
            else
                pos = pos + buf;
        }
        if (pos)
        {
            pos = (char*)pos - buf;
            if (flags &FR_WHOLEWORD)
            {
                if (pos && isalnum(buf[pos - 1]))
                    pos +=  *len;
                else if (!buf[pos +  *len] || !isalnum(buf[pos +  *len]))
                    return pos;
                else
                    pos +=  *len;
            }
            else
                return pos;
        }
        else
            return  - 1;

    }

}

//-------------------------------------------------------------------------

static void MoveFindWindow(HWND editwnd, int left, int right)
{
    POINTL ptl, ptr;
    RECT w1, f, s, cw;
    int th = SendMessage(editwnd, EM_GETTEXTHEIGHT, 0, 0);

    SendMessage(editwnd, EM_POSFROMCHAR, (WPARAM) &ptl, left);
    SendMessage(editwnd, EM_POSFROMCHAR, (WPARAM) &ptr, right);
	ClientToScreen(editwnd, &ptl);
	ClientToScreen(editwnd, &ptr);

    GetWindowRect(hwndFind, &f);
	GetWindowRect(hwndClient, &cw);
	w1.left = ptl.x;
	w1.right = ptr.x;
	w1.top = ptl.y;
	w1.bottom = ptl.y + th;
    if (IntersectRect(&s, &w1, &f))
    {
        if (ptl.y >= (cw.bottom - cw.top) / 2)
        {
            MoveWindow(hwndFind, f.left, cw.top, f.right - f.left, f.bottom -
                f.top, TRUE);
        }
        else
        {
            MoveWindow(hwndFind, f.left, cw.bottom - (f.bottom - f.top), f.right
                - f.left, f.bottom - f.top, TRUE);
        }
    }
}

//-------------------------------------------------------------------------

static int FindNextString(HWND hwnd, FINDREPLACE *find, RE_CONTEXT **r)
{
    char *buf;
    int len;
	static int regular;
	if (!find->lpstrFindWhat)
		return TRUE;
	SetStatusMessage("", FALSE);
    buf = GetEditData(GetDlgItem(hwnd, ID_EDITCHILD));
    if (IsWindow(GetDlgItem(hwndFind, 990)) )
		regular = IsDlgButtonChecked(hwndFind, 990);
    if (buf)
    {
        int pos;
        charinfo a;
        //      SendMessage(GetDlgItem(hwnd,ID_EDITCHILD),EM_GETSEL, (WPARAM)&pos,0) ;
        SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXGETSEL, 0, (LPARAM) &a)
            ;
        pos = a.min;
        if (pos != lastfound && findpos !=  - 1)
            findpos = pos;
        if (findpos ==  - 1)
            if (find->Flags &FR_DOWN)
                findpos = 0;
            else
                findpos = strlen(buf);
        findpos = xfind(find, buf, findpos, &len, r, regular);
        lastfound = findpos;
        FreeEditData(buf);
        if (findpos >= 0)
        {
            charinfo r;
            r.min = findpos;
            r.max = findpos + len;
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 1, 0);
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXSETSEL, 0, (LPARAM)
                &r);
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_SCROLLCARET, 0, 1);
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 0, 0);
            UpdateWindow(GetDlgItem(hwnd, ID_EDITCHILD));
            SendMessage(hwnd, WM_COMMAND, ID_REDRAWSTATUS, 0);
            if (find->Flags &FR_DOWN)
                findpos += len;
            else
            {
                findpos -= len;
                if (findpos < 0)
                {
                    findpos = 0;
                    goto done;
                } 
            }
            MoveFindWindow(GetDlgItem(hwnd, ID_EDITCHILD), findpos, findpos +
                len);
        }
        else
        {
            done: SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_SETSEL,  - 1,
                0);
            SendMessage(hwnd, WM_COMMAND, ID_REDRAWSTATUS, 0);
            if (!(find->Flags &FR_REPLACEALL))
            {
				SetStatusMessage("Search reached end of file", TRUE);
            }
            findpos =  - 1;
            return TRUE;
        }
        return FALSE;
    }
    return TRUE;

}
void FindStringFromToolbar(char *buf)
{
	HWND wnd;
	strcpy(findbuffer, buf);
	
    find.lStructSize = sizeof(find);
    find.hwndOwner = hwndFrame;
    find.hInstance = hInstance;
    find.Flags = FR_ENABLETEMPLATE | FR_ENABLEHOOK;
    find.Flags |= FR_DOWN | FR_FINDNEXT;
    find.lpstrFindWhat = findbuffer;
    find.lpstrReplaceWith = 0;
    find .wFindWhatLen = 256;
    find .wReplaceWithLen = 0;
    find.lpTemplateName = "FINDDLG";
    find.lpfnHook = findHook;
	wnd = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0);
	if (wnd != NULL)
		FindNextString(wnd, &find, 0);
	
}

//-------------------------------------------------------------------------

static void ReplaceNextString(HWND hwnd, FINDREPLACE *replace)
{
    char buf[256];
    int flags;
    static RE_CONTEXT *context;
    int regnum;
	int replaces = 0;
    charinfo a;
    static int selected;
	static int regular;
	if (!replace->lpstrFindWhat || !replace->lpstrReplaceWith)
		return;
	if (IsWindow(hwndFind))
	    selected = IsDlgButtonChecked(hwndFind, IDC_RADIO_SELECTED_TEXT);
    if (IsWindow(GetDlgItem(hwndFind, 990)) )
		regular = IsDlgButtonChecked(hwndFind, 990);
	replace->Flags |= FR_DOWN;
    flags = replace->Flags;
    if (selected)
    {
        SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXGETSEL, 0, (LPARAM) &a)
            ;
		findpos = a.min;
    } else if (flags & FR_REPLACEALL)
	{
		a.min = a.max = 0;
		findpos = -1 ;
		found = FALSE;
	    SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXSETSEL, 0, 
                    (LPARAM) &a);
	}
        //      SendMessage(GetDlgItem(hwnd,ID_EDITCHILD),EM_GETSEL, (WPARAM)&pos,0) ;
    SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 1, 0);
    while (TRUE)
    {
        int notthere = FALSE;
		int len = strlen(replace->lpstrFindWhat);
        if (!found || (flags &FR_FINDNEXT))
        {
			if (context)
				re_free(context);
			context = NULL;
            notthere = FindNextString(hwnd, replace, &context);
			if (context)
				len = context->m_eo - context->m_so;
            if (!found && !(flags &FR_REPLACEALL))
            {
                found = !notthere;
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 0,
                    0);
                SendMessage(hwnd, WM_COMMAND, ID_REDRAWSTATUS, 0);
                return ;
            }
            found = !notthere;
        }
        if (notthere || selected && findpos >= a.max)
        {
            findpos =  - 1;
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 0, 0);
            SendMessage(hwnd, WM_COMMAND, ID_REDRAWSTATUS, 0);
            if (selected && (flags &FR_REPLACEALL))
            {
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXSETSEL, 0, 
                    (LPARAM) &a);
            }
			sprintf(buf,"%d items replaced", replaces);
			SetStatusMessage(buf, FALSE);
            return ;
        }
        if (flags &(FR_REPLACE | FR_REPLACEALL))
        {
            int readonly = SendMessage(GetDlgItem(hwnd, ID_EDITCHILD),
                EM_GETREADONLY, 0, 0);
            if (!readonly)
            {
				if (regular)
                {
                    int i, dest = 0;
                    char *dta = GetEditData(GetDlgItem(hwnd, ID_EDITCHILD));
                    for (i = 0; i < strlen(replace->lpstrReplaceWith) && dest <
                        255; i++)
                    {
                        if (replace->lpstrReplaceWith[i] == '\\')
                        {
                            if (replace->lpstrReplaceWith[++i])
                            {
                                int index = replace->lpstrReplaceWith[i];
                                if (isdigit(index))
                                {
                                    index -= '0';
                                    if (dta && index <= 10)
                                    {
										if (context->matchOffsets[index][1] > 0)
										{
	                                        int j;
	                                        for (j = context->matchOffsets[index][0]; j <
	                                            context->matchOffsets[index][1] && dest <
	                                            255; j++)
	                                            buf[dest++] = dta[j];
										}
                                    }
                                }
                                else
                                    buf[dest++] = replace->lpstrReplaceWith[i];
                            }
                        }
                        else
                            buf[dest++] = replace->lpstrReplaceWith[i];
                    }
                    FreeEditData(dta);
                    buf[dest] = 0;
                }
                else
                {
                    strcpy(buf, replace->lpstrReplaceWith);
                }
                if (selected)
                {
                    a.max += strlen(replace->lpstrReplaceWith) - len;
                }
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_REPLACESEL, 1, 
                    (LPARAM)buf);
                UpdateWindow(GetDlgItem(hwnd, ID_EDITCHILD));
				replaces++;
            }
            findpos += strlen(replace->lpstrReplaceWith) - len ;
            found = FALSE;
        }
        if (!(flags &FR_REPLACEALL))
        if (flags &FR_REPLACE)
        {
            flags &= ~FR_REPLACE;
            flags |= FR_FINDNEXT;
        }
        else
        {
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 0, 0);
            SendMessage(hwnd, WM_COMMAND, ID_REDRAWSTATUS, 0);
            return ;
        }
    }
}

//-------------------------------------------------------------------------

void drawParams(DWINFO *info, HWND hwnd)
{
    char buf[512];
    int start, ins, col, sel;
    int readonly = SendMessage(info->dwHandle, EM_GETREADONLY, 0, 0);
    int mod = SendMessage(info->dwHandle, EM_GETMODIFY, 0, 0);
	EDITDATA *dt ;
    charinfo a;
    SendMessage(info->dwHandle, EM_GETSEL, (WPARAM) &sel, 0);
    SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_EXGETSEL, 0, (LPARAM) &a);
    sel = a.min;
    start = SendMessage(info->dwHandle, EM_EXLINEFROMCHAR, 0, sel);
    ins = SendMessage(info->dwHandle, EM_GETINSERTSTATUS, 0, 0);
    col = SendMessage(info->dwHandle, EM_GETCOLUMN, 0, 0);
    sprintf(buf, "Line: %d", start + 1);
    SendMessage(hwndStatus, SB_SETTEXT, 1, (LPARAM)buf);
    sprintf(buf, "Col: %d", col + 1);
    SendMessage(hwndStatus, SB_SETTEXT, 2, (LPARAM)buf);
    SendMessage(hwndStatus, SB_SETTEXT, 3, (LPARAM)(ins ? "INS" : "OVR"));
    if (readonly)
        SendMessage(hwndStatus, SB_SETTEXT, 4, (LPARAM)("READ-ONLY"));
    else
        SendMessage(hwndStatus, SB_SETTEXT, 4, (LPARAM)(mod ? "MODIFIED" : 
            "    "));

    strcpy(buf, info->dwTitle);
	dt = (EDITDATA *)SendMessage(info->dwHandle, EM_GETEDITDATA, 0, 0);
	if (dt->id)
		sprintf(buf + strlen(buf), " (%d)", dt->id + 1);
    if (mod)
        strcat(buf, " *");
    SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)buf);

}

//-------------------------------------------------------------------------

void eraseParams(HWND hwnd)
{
    SendMessage(hwndStatus, SB_SETTEXT, 1, (LPARAM)"    ");
    SendMessage(hwndStatus, SB_SETTEXT, 2, (LPARAM)"    ");
    SendMessage(hwndStatus, SB_SETTEXT, 3, (LPARAM)"    ");
    SendMessage(hwndStatus, SB_SETTEXT, 4, (LPARAM)"    ");

}

//-------------------------------------------------------------------------
static int GetLog10(int val)
{
    int count = 1;
    if (val > 9999999)
        count = 8;
    else if (val > 999999)
        count = 7;
    else if (val > 99999)
        count = 6;
    else if (val > 9999)
        count = 5;
    else if (val > 999)
        count = 4;
    else if (val > 99)
        count = 3;
    else if (val > 9)
        count = 2;
    return count;
}

int PaintBreakpoints(HWND hwnd, HDC dc, PAINTSTRUCT *paint, RECT *rcl)
{
    HBRUSH graybrush, graybrush1;
    RECT r, r1;
    int i;
	int oldbk = SetBkColor(dc, GetSysColor(COLOR_3DFACE));
    HDC hMemDC = CreateCompatibleDC(dc);
    DWINFO *ptr = (DWINFO*)GetWindowLong(hwnd, 0);
    int linenum = SendMessage(ptr->dwHandle, EM_GETFIRSTVISIBLELINE, 0, 0) + 1;
    int chpos1 = SendMessage(ptr->dwHandle, EM_LINEINDEX, linenum, 0);
    int maxLines = SendMessage(ptr->dwHandle, EM_GETLINECOUNT, 0, 0); 
    int ypos;
    int lines, offset = 0;
    int height;
    short *lt;
    int lc;
	int count;
    POINTL pt;
	HFONT xfont;
    int bpline = BPLine(ptr->dwName);
	
    SendMessage(ptr->dwHandle, EM_POSFROMCHAR, (WPARAM) &pt, chpos1);
    ypos = pt.y;

    SendMessage(ptr->dwHandle, EM_GETRECT, 0, (LPARAM) &r1);
    lines = r1.bottom / (height = SendMessage(ptr->dwHandle, EM_GETTEXTHEIGHT,
        0, 0));

    count = GetLog10(linenum + lines);
    if (count > ptr->lineNumberDigits)
    {
        PostMessage(hwnd, WM_SETLINENUMBERMODE, count, 0);
        // will invalidate the rect and force it to repaint
        return 0;
    }
    if (ypos < height)
        offset = ypos - height;

    graybrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
    FillRect(dc, rcl, graybrush);
    DeleteObject(graybrush);
    if (uState != notDebugging)
    {
        lt = GetLineTable(ptr->dwName, &lc);
        if (lt)
        {
            int j = 0;
            graybrush1 = GetStockObject(BLACK_BRUSH);
            r.left = 28;
            r.right = 32;
            for (i = linenum; i <= linenum + lines; i++)
            {
                int oldline = TagOldLine(ptr->dwName, i);
                while (lt[j] < oldline)
                    j++;
                if (lt[j] == oldline)
                {
                    r.top = offset + (i - linenum) *height;
                    r.bottom = r.top + height;
                    FillRect(dc, &r, graybrush1);
                }
            }
        }
    }
    xfont = (HFONT)SendMessage(ptr->dwHandle, WM_GETFONT, 0, 0);
    xfont = SelectObject(dc, xfont);
    for (i = linenum; i <= linenum + lines; i++)
    {
        int type = IsTagged(ptr->dwName, i);
        switch (type)
        {
            case TAG_BP:
                if (bpline == i)
                {
                    SelectObject(hMemDC, stoppcBitmap);
                    BitBlt(dc, 12, (i - linenum) *height + offset, 16, 16,
                        hMemDC, 0, 0, SRCCOPY);
                    break;
                }
                // fallthrough 
            default:
                SelectObject(hMemDC, tagBmps[type]);
                BitBlt(dc, 12, (i - linenum) *height + offset, 16, 16, hMemDC,
                    0, 0, SRCCOPY);
                break;
                case  - 1: if (bpline == i)
                {
                    SelectObject(hMemDC, pcBitmap);
                    BitBlt(dc, 12, (i - linenum) *height + offset, 16, 16,
                        hMemDC, 0, 0, SRCCOPY);
                }
                break;
        }
        if (ptr->editorOffset != EDITOR_OFFSET && i <= maxLines + 1)
        {
            char buf[256];
            sprintf(buf, "%d", i);
            TextOut(dc, EDITOR_OFFSET + (ptr->lineNumberDigits - GetLog10(i)) * 
                    ((EDITDATA *)SendMessage(ptr->dwHandle, EM_GETEDITDATA, 0, 0))->cd->txtFontWidth , 
                    (i - linenum) *height + offset, buf, strlen(buf));
        }
    }
    xfont = SelectObject(dc, xfont);
    SetBkColor(dc, oldbk);
    DeleteDC(hMemDC);
}

//-------------------------------------------------------------------------

LRESULT CALLBACK _export gotoProc(HWND hwnd, UINT iMessage, WPARAM wParam,
    LPARAM lParam)
{
    char buf[3];
    switch (iMessage)
    {
        case WM_COMMAND:
            if (wParam == IDOK)
            {
                int i = GetEditFieldValue(hwnd, IDC_GOTO);
                EndDialog(hwnd, i);
                break;
            }
            if (HIWORD(wParam) == EN_CHANGE)
            {
                DisableControl(hwnd, IDOK, !GetWindowText((HWND)lParam, buf, 2))
                    ;
                break;
            }
            if (wParam != IDCANCEL)
                break;
        case WM_CLOSE:
            EndDialog(hwnd, 0);
            break;
        case WM_INITDIALOG:
            CenterWindow(hwnd);
            SetEditField(hwnd, IDC_GOTO, "");
            DisableControl(hwnd, IDOK, 1);
            break;
    }
    return 0;
}

//-------------------------------------------------------------------------

void recolorize(DWINFO *ptr)
{
    int colorizing = COLORIZE_NONE;
    if (stristr(ptr->dwName, ".c") == ptr->dwName + strlen(ptr->dwName) - 2 ||
        stristr(ptr->dwName, ".cpp") == ptr->dwName + strlen(ptr->dwName) - 4 
        || stristr(ptr->dwName, ".h") == ptr->dwName + strlen(ptr->dwName) - 2)
        colorizing = COLORIZE_C;
    else if (stristr(ptr->dwName, ".asm") == ptr->dwName + strlen(ptr->dwName) 
        - 4 || stristr(ptr->dwName, ".asi") == ptr->dwName + strlen(ptr->dwName)
        - 4 || stristr(ptr->dwName, ".inc") == ptr->dwName + strlen(ptr->dwName)
        - 4 || stristr(ptr->dwName, ".nas") == ptr->dwName + strlen(ptr->dwName)
        - 4)
        colorizing = COLORIZE_ASM;
	else if (stristr(ptr->dwName, ".rc") == ptr->dwName + strlen(ptr->dwName) - 3)
		colorizing = COLORIZE_RC;
    SendMessage(ptr->dwHandle, EM_COLORIZE, 0, colorizing);
}

//-------------------------------------------------------------------------

void asyncLoadFile(DWINFO *ptr)
{
    recolorize(ptr);
    if (ptr->dwName[0])
        LoadFile(ptr->self, ptr);
    else
        ShowWindow(ptr->dwHandle, SW_SHOW);
    if (ptr->dwLineNo !=  - 1)
    {
        PostMessage(ptr->self, WM_COMMAND, IDM_SETLINE, ptr->dwLineNo);
    }
    PostMessage(hwndSourceTab, WM_RESETTABS, 0, 0);
}
static void installparse(HWND hwnd)
{
	int i;
	for (i=0; i < PARSE_LIST_SIZE; i++)
		if (!parselist[i])
		{
			parselist[i] = hwnd;
			break;
		}	
}
void InstallForParse(HWND hwnd)
{
	if (completionEnabled)
	{
		int i;
		DWINFO *info = (DWINFO *)GetWindowLong(hwnd, 0);
		char *name = info->dwName;
		int len = strlen(name);
		if (name[len-2] == '.')
		{
			if (tolower(name[len - 1]) == 'c')
				installparse(hwnd);
			else if (tolower(name[len-1]) == 'h')
				for (i=0; i < numberofdrawwindows; i++)
				{
					if (IsWindow(children[i]))
					{
						info = (DWINFO *)GetWindowLong(children[i], 0);
						name = info->dwName;
						len = strlen(name);
						if (name[len -2] == '.' && tolower(name[len-1]) == 'c')
							installparse(children[i]);
					}
				}
		}
	}
}
static void deleteParseData(char *name)
{
		int len = strlen(name);
		if (name[len-2] == '.')
		{
			if (tolower(name[len - 1]) == 'c')
				deleteFileData(name);
		}
}
static void ScanParse(void)
{
	while (1)
	{
		int i;
		for (i=0; i < PARSE_LIST_SIZE; i++)
			if (parselist[i])
			{
				if (IsWindow(parselist[i]))
				{
					DWINFO *info = (DWINFO *)GetWindowLong(parselist[i], 0);
					currentParsing = parselist[i];
					if (info)
						doparse(info->dwName);
					currentParsing = NULL;
				}
				parselist[i] = 0;
			}
		Sleep(100);
	}
}
//-------------------------------------------------------------------------

LRESULT CALLBACK _export DrawProc(HWND hwnd, UINT iMessage, WPARAM wParam,
    LPARAM lParam)
{
    DWORD threadhand;
    DWINFO *ptr,  *ptr1;
	EDITDATA *ed;
    OPENFILENAME ofn;
    HDC dc;
    HPEN hpen, oldpen;
    RECT r;
    HBRUSH graybrush;
    LOGBRUSH lbrush;
    PAINTSTRUCT paint;
	LPCREATESTRUCT createStruct;
    int childheight;
    int startpos, endpos, flag, i;
    HWND win;
    FILETIME time;
    NMHDR *nm;
    int rv;
    charinfo s;
    switch (iMessage)
    {
		case WM_LBUTTONDOWN:
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
			{
				POINT pt;
                int linenum;
				RECT r;
				GetCursorPos(&pt);
				GetWindowRect(ptr->dwHandle, &r);
				pt.x = 0;
				pt.y -= r.top;
				GetClientRect(ptr->dwHandle, &r);
				if (pt.y < r.bottom - r.top)
				{
	                linenum = SendMessage(ptr->dwHandle, EM_CHARFROMPOS, 0, (LPARAM)&pt);
/*
					if (uState == notDebugging)
						ToggleBookMark(linenum);
					else
*/
					{
	    	            linenum = SendMessage(ptr->dwHandle, EM_EXLINEFROMCHAR, 0,
    	    	            linenum) + 1;
	            	    Tag(TAG_BP, ptr->dwName, linenum, 0, 0, 0, 0);
					}
				}
			}
			break;
        case EN_LINECHANGE:
            found = FALSE;
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
            TagLineChange(ptr->dwName, wParam + 1, lParam);
            GetClientRect(hwnd, &r);
			r.right = ptr->editorOffset;
            InvalidateRect(hwnd, &r, 0);
            break;
        case WM_NOTIFY:
            nm = (NMHDR*)lParam;
            if (nm->code == NM_RCLICK)
            {
                HMENU menu = LoadMenu(hInstance, "EDITMENU");
                HMENU popup = GetSubMenu(menu, 0);
                POINT pos, pos1;
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                SendMessage(hwnd, EN_SETCURSOR, 0, 0);
                if (!SendMessage(ptr->dwHandle, EM_GETMODIFY, 0, 0))
                    EnableMenuItem(menu, IDM_SAVE, MF_GRAYED);
                if (uState != atBreakpoint && uState != atException)
                {
                    EnableMenuItem(menu, IDM_RUNTO, MF_GRAYED);
                    EnableMenuItem(menu, IDM_ADDWATCHINDIRECT, MF_GRAYED);
                }
                GetCursorPos(&pos);
				menupos = pos;
                pos1.x = pos.x;
                pos1.y = pos.y;
//                ScreenToClient(ptr->dwHandle, &pos1);
//                i = SendMessage(ptr->dwHandle, EM_CHARFROMPOS, 0, (LPARAM)
//                    &pos1);
//                s.min = i;
//                s.max = i;
//                SendMessage(ptr->dwHandle, EM_EXSETSEL, 0, (LPARAM) &s);
				InsertBitmapsInMenu(popup);
                TrackPopupMenuEx(popup, TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pos.x,
                    pos.y, hwndFrame, NULL);
                DestroyMenu(menu);
            }
            return 0;
        case WM_SYSCOMMAND:
            if (wParam == SC_CLOSE)
                return SendMessage(hwnd, WM_COMMAND, IDM_CLOSE, 0);
            break;
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
			case IDM_NEWWINDOW:
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
				newInfo = ptr ;
				openfile(ptr, TRUE, TRUE);
				break ;
            case IDM_SPECIFIEDHELP:
			case IDM_RTLHELP:
			case IDM_LANGUAGEHELP:
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                i = SendMessage(ptr->dwHandle, WM_COMMAND, wParam, lParam);
                break;
            case IDM_GOTO:
                lParam = DialogBox(hInstance, "GOTODIALOG", hwnd, (DLGPROC)
                    gotoProc);
                if (lParam == 0)
                    break;
                // fall through
            case IDM_SETLINE:
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                SendMessage(ptr->dwHandle, EM_GETLINECOUNT, 0, 0); 
                    // force update of vertical scroll range
                i = SendMessage(ptr->dwHandle, EM_LINEINDEX, lParam - 1, 0);
                s.min = i;
                s.max = i;
	            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 1, 0);
                SendMessage(ptr->dwHandle, EM_EXSETSEL, 0, (LPARAM) &s);
                SendMessage(ptr->dwHandle, EM_SCROLLCARET, 0, 1);
    	        SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_HIDESELECTION, 0, 0);
                drawParams(ptr, hwnd);
                found = FALSE;
                InvalidateRect(hwnd, 0, 0);
                break;
            case ID_REDRAWSTATUS:
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                drawParams(ptr, hwnd);
                InvalidateRect(hwnd, 0, 0);
                break;
            case ID_QUERYHASFILE:
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                ptr1 = (DWINFO*)lParam;
                if (!xstricmpz(ptr->dwName, ptr1->dwName))
				{
					return SendMessage(ptr->dwHandle, EM_GETEDITDATA, 0, 0);
				}
				return 0 ;
            case ID_QUERYSAVE:
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                rv = SendMessage(ptr->dwHandle, EM_GETMODIFY, 0, 0);
                if (rv)
                {
                    return ExtendedMessageBox("File Changed",
                        MB_YESNOCANCEL, 
                        "File %s has changed.  Do you wish to save it?", ptr
                        ->dwTitle);
                }
                else
                    return IDNO;
            case IDM_SAVEAS:
                dialog: ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                if (!SaveFileDialog(&ofn, ptr->dwName, hwnd, TRUE, szSourceFilter, 0))
                    break;
                if (projectList && ptr->dwName[0] == 0)
                {
                    if (ExtendedMessageBox("Target Query", MB_TASKMODAL |
                        MB_YESNO, "Add file to Target?") == IDYES)
                    {
                        PROJLIST *p = ProjectFindSelectedEXE(0);
                        if (!p)
                            ExtendedMessageBox("Target Query", MB_TASKMODAL,
                                "No target selected");
                        else
                            AddFileInternal(p->sourceTreeHandle, p, 0, ofn.lpstrFile,
                                ofn.lpstrFileTitle);
                    }
                }
                strcpy(ptr->dwTitle, ofn.lpstrFileTitle);
                strcpy(ptr->dwName, ofn.lpstrFile);
                recolorize(ptr);
            case IDM_SAVE:
                ptr = (DWINFO*)GetWindowLong(hwnd, 0);
				if (LOWORD(wParam) == IDM_SAVE)
				{
	                rv = SendMessage(ptr->dwHandle, EM_GETMODIFY, 0, 0);
    	            if (!rv)
        	            break;
				}
                if (ptr->dwName[0] == 0)
                    goto dialog;
                rv = SaveFile(hwnd, (char*)GetWindowLong(hwnd, 0));
                TagLinesAdjust(ptr->dwName, TAGM_SAVEFILE);
                SendMessage(ptr->dwHandle, EM_SETMODIFY, 0, 0);
                drawParams(ptr, hwnd);
	            PostMessage(hwndSourceTab, WM_RESETTABS, 0, 0);
                return rv;
            case IDM_CLOSE:
                {
                    rv = SendMessage(hwnd, WM_COMMAND, ID_QUERYSAVE, 0);
                    switch (rv)
                    {
                    case IDYES:
                        if (SendMessage(hwnd, WM_COMMAND, IDM_SAVE, 0))
                            SendMessage(hwnd, WM_CLOSE, 0, 0);
                        break;
                    case IDNO:
                        ptr = (DWINFO*)GetWindowLong(hwnd, 0);
                        TagLinesAdjust(ptr->dwName, TAGM_DISCARDFILE);
                        SendMessage(hwnd, WM_CLOSE, 0, 0);
                        break;
                    case IDCANCEL:
                        break;
                    }
                    return rv;
                }
                break;
            case IDM_UNDO:
                found = FALSE;
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), WM_UNDO, 0, 0);
                break;
            case IDM_REDO:
                found = FALSE;
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), WM_REDO, 0, 0);
                break;
            case IDM_CUT:
                found = FALSE;
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), WM_CUT, 0, 0);
                break;
            case IDM_COPY:
                found = FALSE;
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), WM_COPY, 0, 0);
                break;
            case IDM_PASTE:
                found = FALSE;
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), WM_PASTE, 0, 0);
                break;
            case IDM_SELECTALL:
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_SETSEL, 0,  - 1);
                break;
            case IDM_FIND:
                PopFindString(hwnd);
                break;
            case IDM_REPLACE:
                PopReplaceString(hwnd);
                break;
            case IDM_FINDNEXT:
                if (finding)
                    FindNextString(hwnd, &find, 0);
                else
                    ReplaceNextString(hwnd, &replace);
                break;
            case IDM_TOUPPER:
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_TOUPPER, 0, 0);
                break;
            case IDM_TOLOWER:
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_TOLOWER, 0, 0);
                break;
            case IDM_INDENT:
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_SELECTINDENT, 0,
                    1);
                break;
            case IDM_UNINDENT:
                SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_SELECTINDENT, 0,
                    0);
                break;
            case EN_SETFOCUS:
                lastActiveEditWindow = hwnd ;
                break;
            default:
                return DefMDIChildProc(hwnd, iMessage, wParam, lParam);
            }
            break;
		case EM_CANREDO:
            return SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_CANREDO, 0, 0)
                ;
        case EM_CANUNDO:
            return SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_CANUNDO, 0, 0)
                ;
        case EN_SETCURSOR:
            found = FALSE;
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
            drawParams(ptr, hwnd);
            GetClientRect(hwnd, &r);
            r.right = ptr->editorOffset - 3;
            InvalidateRect(hwnd, &r, 0);
            break;
        case WM_PAINT:
            GetClientRect(hwnd, &r);
            dc = BeginPaint(hwnd, &paint);
            PaintBreakpoints(hwnd, dc, &paint, &r);
            EndPaint(hwnd, &paint);
            return 0;
        case WM_CREATE:
            //         maximized = TRUE ;
			createStruct = (LPCREATESTRUCT)lParam;
			ed = (EDITDATA *)((LPMDICREATESTRUCT)(createStruct->lpCreateParams))->lParam;
            ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DWINFO));
            SetWindowLong(hwnd, 0, (int)ptr);
            SetWindowLong(hwnd, 4, (int)EDITSIG);
            memset(ptr, 0, sizeof(*ptr));
            strcpy(ptr->dwTitle, newInfo->dwTitle);
            SetWindowText(hwnd, newInfo->dwTitle);
            strcpy(ptr->dwName, newInfo->dwName);
            if (!ptr->newFile)
                FileTime(&ptr->time, ptr->dwName);
            ptr->dwHandle = CreateWindowEx(0, "xedit", 0, WS_CHILD +
                WS_CLIPSIBLINGS + WS_HSCROLL + WS_VSCROLL + ES_LEFT + WS_VISIBLE +
                ES_MULTILINE + ES_NOHIDESEL + ES_AUTOVSCROLL + ES_AUTOHSCROLL,
                EDITOR_OFFSET, 0, 0, 0, hwnd, (HMENU)ID_EDITCHILD, hInstance, 
				(void *)ed)
                ;
            ptr->self = hwnd;
            ptr->dwLineNo =  - 1;
            if (newInfo && !newInfo->newFile && newInfo->dwLineNo !=  -
                1)
            {
                ptr->dwLineNo = newInfo->dwLineNo;
                newInfo->dwLineNo =  - 1;
            }
            if (!ed && newInfo->logMRU)
            {
                InsertMRU(ptr, 0);
                MRUToMenu(0);
            }
            //         CloseHandle(CreateThread(0,0,(LPTHREAD_START_ROUTINE)asyncLoadFile,(LPVOID)ptr,0,&threadhand)) ;
			if (!ed)
			{
    	        if (ptr->dwName[0] && (!newInfo || !newInfo->newFile))
        	        LoadFile(ptr->self, ptr);
	            if (ptr->dwLineNo !=  - 1)
    	        {
        	        PostMessage(ptr->self, WM_COMMAND, IDM_SETLINE, ptr->dwLineNo);
            	}
	            recolorize(ptr);
			}
            children[numberofdrawwindows++] = hwnd;
            SendMessage(hwnd, WM_SETLINENUMBERMODE, 2, 0);
			ShowWindow(hwnd, SW_SHOW);
            PostMessage(hwndSourceTab, WM_RESETTABS, 0, 0);
			InstallForParse(hwnd);
            return 0;

        case WM_CLOSE:
            if (hwnd == lastActiveEditWindow)
                lastActiveEditWindow = hwnd;
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
            eraseParams(ptr->dwHandle);
			if (hwnd != currentParsing)
				deleteParseData(ptr->dwName);
            break;
        case WM_DESTROY:
            for (i = 0; i < numberofdrawwindows; i++)
                if (children[i] == hwnd)
                    break;
            if (i < numberofdrawwindows - 1)
                memcpy(children + i, children + i + 1, (numberofdrawwindows - i
                    - 1) *sizeof(HWND));
            if (--numberofdrawwindows == 0 && IsWindow(hwndFind))
            {
                DestroyWindow(hwndFind);
                hwndFind = 0;
            }
            SendMessage(hwndSourceTab, WM_RESETTABS, 0, 0);
            HeapFree(GetProcessHeap(), 0, (void*)GetWindowLong(hwnd, 0));
            PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0);
            break;
        case WM_SIZE:
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
			if (wParam == SIZE_MAXIMIZED)
				maximizeClient = TRUE;
			if (wParam == SIZE_RESTORED)
				maximizeClient = FALSE;
            MoveWindow(GetDlgItem(hwnd, ID_EDITCHILD), ptr->editorOffset, 0, 
                (lParam &65535) - ptr->editorOffset, lParam >> 16, 1);
            break;
        case WM_MDIACTIVATE:
            found = FALSE;
            break;
        case WM_SETFOCUS:
            SetFocus(GetDlgItem(hwnd, ID_EDITCHILD));
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
            drawParams(ptr, hwnd);
            InvalidateRect(hwnd, 0, 0);
            PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0);
            PostMessage(hwndSourceTab, WM_SETACTIVETAB, 0, (LPARAM)hwnd);
            return 0;
        case WM_KILLFOCUS:
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), iMessage, wParam,
                lParam);
            return 0;
        case WM_SETLINENUMBERMODE:
        {
            BOOL lineNumbers = !!(editFlags & LINE_NUMBERS);
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
            if (wParam)
            {
                    ptr->lineNumberDigits = wParam; // never goes down while the window is open...
            }
            ptr->editorOffset = EDITOR_OFFSET +  
                lineNumbers * (ptr->lineNumberDigits * ((EDITDATA *)SendMessage(ptr->dwHandle, EM_GETEDITDATA, 0, 0))->cd->txtFontWidth + 4);
            GetClientRect(hwnd, &r);
            MoveWindow(GetDlgItem(hwnd, ID_EDITCHILD), ptr->editorOffset, r.top, 
                r.right - ptr->editorOffset, r.bottom - r.top, 1);
            InvalidateRect(hwnd, 0, 1);
            break;
        }
        case WM_INITMENUPOPUP:
            SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), EM_GETSEL, (WPARAM)
                &startpos, (LPARAM) &endpos);
            flag = startpos < endpos;
            EnableMenuItem(hMenuMain, IDM_CUT, flag);
            EnableMenuItem(hMenuMain, IDM_COPY, flag);
            EnableMenuItem(hMenuMain, IDM_PASTE, 1);
            EnableMenuItem(hMenuMain, IDM_UNDO, SendMessage(GetDlgItem(hwnd,
                ID_EDITCHILD), EM_CANUNDO, 0, 0));
            EnableMenuItem(hMenuMain, IDM_BROWSE, flag);
            //EnableMenuItem(hMenuMain,IDM_BROWSEBACK,flag) ;
            EnableMenuItem(hMenuMain, IDM_BOOKMARK, flag);
            //EnableMenuItem(hMenuMain,IDM_NEXTBOOKMARK,flag) ;
            //EnableMenuItem(hMenuMain,IDM_PREVBOOKMARK,flag) ;
            return 0;
        case WM_WORDUNDERCURSOR:
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
			{
            	int rv = SendMessage(ptr->dwHandle, iMessage, wParam, lParam);
				return rv;
			}
        case WM_FILETITLE:
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
            return ptr->dwTitle;
        case WM_FILENAME:
            ptr = (DWINFO*)GetWindowLong(hwnd, 0);
            return ptr->dwName;
        default:
            if (iMessage == iFindMessage)
            {
                HWND edit;
                if (finding)
                {
                    edit = GetDlgItem(hwndFind, 1152);
                    SendMessage(edit, WM_SAVEHISTORY, 0, 0);
                    if (find.Flags &FR_FINDNEXT)
                        FindNextString(hwnd, &find, 0);
                    //               if (find.Flags & FR_DIALOGTERM)
                    //                  hwndFind = 0 ;
                }
                else
                {
                    edit = GetDlgItem(hwndFind, 1152);
                    SendMessage(edit, WM_SAVEHISTORY, 0, 0);
                    edit = GetDlgItem(hwndFind, 1153);
                    SendMessage(edit, WM_SAVEHISTORY, 0, 0);
                    if (replace.Flags &(FR_FINDNEXT | FR_REPLACE |
                        FR_REPLACEALL))
                        ReplaceNextString(hwnd, &replace);
                    //               if (replace.Flags & FR_DIALOGTERM)
                    //                  hwndFind = 0 ;
                }
            }
			else
				if (iMessage >= WM_USER)
					return SendMessage(GetDlgItem(hwnd, ID_EDITCHILD), iMessage, wParam, lParam);
            break;
    }
    return DefMDIChildProc(hwnd, iMessage, wParam, lParam);
}

//-------------------------------------------------------------------------

void RegisterDrawWindow(void)
{
	DWORD threadid;
    WNDCLASS wc;
//	editHeap = HeapCreate(0, 2 * 1024 * 1024, 128  * 1024 * 1024);
    memset(&wc, 0, sizeof(wc));
    wc.style = CS_DBLCLKS;
    wc.lpfnWndProc = &DrawProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof(void*) * 2;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    wc.hCursor = LoadCursor(0, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = 0;
    wc.lpszClassName = szDrawClassName;
    pcBitmap = LoadImage(hInstance, "ID_PCBMP", IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    stoppcBitmap = LoadImage(hInstance, "ID_STOPPCBMP", IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    tagBmps[TAG_BP] = LoadImage(hInstance, "ID_STOPBMP", IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    tagBmps[TAG_FIF1] = LoadImage(hInstance, "ID_FIF1BMP", IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    tagBmps[TAG_FIF2] = LoadImage(hInstance, "ID_FIF2BMP", IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    tagBmps[TAG_BOOKMARK] = LoadImage(hInstance, "ID_BOOKMARKBMP", IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    tagBmps[TAG_BPGRAYED] = LoadImage(hInstance, "ID_STOPDISBMP", IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
    RegisterClass(&wc);
//    findflags = ProfileToInt("FindFlags", 12);
//    replaceflags = ProfileToInt("ReplaceFlags", 4);
//    editFlags = ProfileToInt("EditFlags",editFlags) ;
	CloseHandle(CreateThread(0,0, (LPTHREAD_START_ROUTINE)ScanParse, 0, 0, &threadid));
}

//-------------------------------------------------------------------------

HWND openfile(DWINFO *newInfo, int newwindow, int visible)
{
    BOOL maximized;
	HWND rv ;
	int i;
	void *extra = NULL ;
    if (newInfo && newInfo != (DWINFO*) - 1)
        for (i = 0; i < MAX_CHILDREN; i++)
    if (children[i] && SendMessage(children[i], WM_COMMAND, ID_QUERYHASFILE, 
        (LPARAM)newInfo))
    {
		if (newwindow)
		{
			extra = (EDITDATA *)SendMessage(children[i], EM_GETEDITDATA, 0, 0);
		}
		else
		{
	        BringWindowToTop(children[i]);
    	    SetFocus(children[i]);
        	if (newInfo->dwLineNo !=  - 1)
            	    PostMessage(children[i], WM_COMMAND, IDM_SETLINE, newInfo
                	    ->dwLineNo);
	        return children[i];
		}
    }
    SendMessage(hwndClient, WM_MDIGETACTIVE, 0, (LPARAM) &maximized);
	rv = CreateMDIWindow(szDrawClassName, szUntitled, (visible ? WS_VISIBLE : 0) |
    	WS_CHILD | WS_OVERLAPPEDWINDOW | WS_SYSMENU | MDIS_ALLCHILDSTYLES |
        WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | (maximized ? WS_MAXIMIZE : 0),
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndClient, hInstance, 
		(LPARAM)extra); 
    return rv;
}

//-------------------------------------------------------------------------

HWND CreateDrawWindow(DWINFO *baseinfo, int visible)
{
    int i;
    DWINFO temp;
    OPENFILENAME ofn;
    if (numberofdrawwindows >= MAX_CHILDREN)
    {
        ExtendedMessageBox("Error", MB_SETFOREGROUND | MB_SYSTEMMODAL, 
            "Too many edit windows open");
        return 0;
    }

    newInfo = baseinfo;
    if (!newInfo)
    {
        newInfo = &temp;
        newInfo->dwLineNo =  - 1;
        newInfo->logMRU = TRUE;
        newInfo->newFile = FALSE;
        if (OpenFileDialog(&ofn, 0, 0, FALSE, TRUE, szSourceFilter, 0))
        {
            char *q = ofn.lpstrFile, path[256];
            strcpy(path, ofn.lpstrFile);
            q += strlen(q) + 1;
            if (! *q)
            {
                strcpy(newInfo->dwTitle, ofn.lpstrFileTitle);
                strcpy(newInfo->dwName, ofn.lpstrFile);
            }
            else
            {
                while (*q)
                {
                    strcpy(newInfo->dwTitle, q);
                    sprintf(newInfo->dwName, "%s\\%s", path, q);
                    openfile(newInfo, FALSE, visible);
                    q += strlen(q) + 1;
                }
                return 0;
            }
        }
        else
        {

            //               ExtendedMessageBox("File Open",MB_SETFOREGROUND | MB_SYSTEMMODAL,"Could not open file %s %d",newInfo->dwName,GetLastError()) ;
            return 0;
        }
    } else if (newInfo == (DWINFO *)-1)
    {
        newInfo = &temp;
        newInfo->dwLineNo =  - 1;
        newInfo->logMRU = TRUE;
        newInfo->newFile = TRUE;
        if (SaveFileDialog(&ofn, 0, 0, TRUE, szNewFileFilter, "Open New File"))
        {
            char *q = ofn.lpstrFile, path[256];
            strcpy(path, ofn.lpstrFile);
            q += strlen(q) + 1;
            if (! *q)
            {
                strcpy(newInfo->dwTitle, ofn.lpstrFileTitle);
                strcpy(newInfo->dwName, ofn.lpstrFile);
            }
            else
            {
                while (*q)
                {
                    strcpy(newInfo->dwTitle, q);
                    sprintf(newInfo->dwName, "%s\\%s", path, q);
                    openfile(newInfo, FALSE, visible);
                    q += strlen(q) + 1;
                }
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
    return openfile(newInfo, FALSE, visible);
}
