/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 1999-2017  The R Core Team
 *
 *  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, a copy is available at
 *  https://www.R-project.org/Licenses/
 */


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "win-nls.h"

#ifdef Win32
#define USE_MDI 1
#endif

#include <Defn.h>
#include <Fileio.h>
#include <stdio.h>
#include <Startup.h>
#include "graphapp/ga.h"
#include "graphapp/graphapp.h"
#include "graphapp/stdimg.h"
#include "console.h"
#include "consolestructs.h"
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include "rui.h"
#include "editor.h"

/* from sysutils.c */
void reEnc2(const char *x, char *y, int ny,
	    cetype_t ce_in, cetype_t ce_out, int subst);

#define gettext GA_gettext

#define MCHECK(a) if (!(a)) {del(c); return NULL;}
RECT *RgetMDIsize(void);

/* Pointers to currently open editors */
static editor REditors[MAXNEDITORS];
static int neditors  = 0;
static Rboolean fix_editor_up = FALSE;

static EditorData neweditordata (int file, const char *filename)
{
    EditorData p;
    p = (EditorData) malloc(sizeof(struct structEditorData));
    p->file = file;
    /* need space for terminator, and to copy it */
    p->filename = (char *) malloc((MAX_PATH+1)*sizeof(char));
    if (filename)
	strncpy(p->filename, filename, MAX_PATH+1);
    p->title = (char *) malloc((EDITORMAXTITLE + 1)*sizeof(char));
    p->title[EDITORMAXTITLE] = p->title[0] = '\0';
    return p;
}

void deleditordata(EditorData p)
{
    if (p->stealconsole)
	fix_editor_up = FALSE;
    free(p->filename);
    free(p->title);
    free(p->hmenu);
    free(p->pmenu);
    free(p);
}

static void editor_set_title(editor c, const char *title)
{
    char wtitle[EDITORMAXTITLE+1];
    textbox t = getdata(c);
    EditorData p = getdata(t);
    strncpy(wtitle, title, EDITORMAXTITLE);
    wtitle[EDITORMAXTITLE] = '\0';
    strcpy(p->title, wtitle);
    if (strlen(wtitle) + strlen(G_("R Editor")) + 3 < EDITORMAXTITLE) {
	strcat(wtitle, " - ");
	strcat(wtitle, G_("R Editor"));
    }
    settext(c, wtitle);
}

/*** FILE MANAGEMENT FUNCTIONS ***/

FILE *R_wfopen(const wchar_t *filename, const wchar_t *mode);

static void editor_load_file(editor c, const char *name, int enc)
{
    textbox t = getdata(c);
    EditorData p = getdata(t);
    FILE *f;
    char *buffer = NULL, tmp[MAX_PATH+50], tname[MAX_PATH+1];
    const char *sname;
    long num = 1, bufsize;

    if(enc == CE_UTF8) {
	wchar_t wname[MAX_PATH+1];
	Rf_utf8towcs(wname, name, MAX_PATH+1);
	f = R_wfopen(wname, L"r");
	reEnc2(name, tname, MAX_PATH+1, CE_UTF8, CE_NATIVE, 3);
	sname = tname;
    } else {
	f = R_fopen(name, "r");
	sname = name;
    }
    if (f == NULL) {
	snprintf(tmp, MAX_PATH+50, 
		 G_("unable to open file %s for reading"), sname);
	R_ShowMessage(tmp);
	return;
    }
    p->file = 1;
    strncpy(p->filename, name, MAX_PATH+1);
    bufsize = 0;
    while (num > 0) {
	buffer = realloc(buffer, bufsize + 3000 + 1);
	num = fread(buffer + bufsize, 1, 3000 - 1, f);
	if (num >= 0) {
	    bufsize += num;
	    buffer[bufsize] = '\0';
	}
	else {
	    snprintf(tmp, MAX_PATH+50, 
		     G_("Could not read from file '%s'"), sname);
	    askok(tmp);
	}
    }
    setlimittext(t, 2 * strlen(buffer));
    settext(t, buffer);
    gsetmodified(t, 0);
    free(buffer);
    fclose(f);
}

static void editor_save_file(editor c, const char *name, int enc)
{
    textbox t = getdata(c);
    FILE *f;
    char buf[MAX_PATH+30], tname[MAX_PATH+1];
    const char *sname;

    if (name == NULL)
	return;
    else {
	if(enc == CE_UTF8) {
	    wchar_t wname[MAX_PATH+1];
	    Rf_utf8towcs(wname, name, MAX_PATH+1);
	    reEnc2(name, tname, MAX_PATH+1, CE_UTF8, CE_NATIVE, 3);
	    sname = tname;
	    f = R_wfopen(wname, L"w");
	} else {
	    sname = name;
	    f = R_fopen(sname, "w");
	}
	if (f == NULL) {
	    snprintf(buf, MAX_PATH+30, G_("Could not save file '%s'"), sname);
	    askok(buf);
	    return;
	}
	fprintf(f, "%s", gettext(t));
	fclose(f);
    }
}

static void editorsaveas(editor c)
{
    textbox t = getdata(c);
    EditorData p = getdata(t);
    wchar_t *wname;

    setuserfilterW(L"R files (*.R)\0*.R\0S files (*.q, *.ssc, *.S)\0*.q;*.ssc;*.S\0All files (*.*)\0*.*\0\0");
    wname = askfilesaveW(G_("Save script as"), "");
    if (wname) {
	char name[4*MAX_PATH+1];
	wcstoutf8(name, wname, sizeof(name));
	/* now check if it has an extension */
	char *q = strchr(name, '.');
	if(!q) strncat(name, ".R", 4*MAX_PATH);
	editor_save_file(c, name, CE_UTF8);
	p->file = 1;
	reEnc2(name, p->filename, MAX_PATH+1, CE_UTF8, CE_NATIVE, 3);
	gsetmodified(t, 0);
	editor_set_title(c, p->filename);
    }
    show(c);
}

static void menueditorsaveas(control m)
{
    editor c = getdata(m);
    editorsaveas(c);
}

static void editorsave(editor c)
{
    textbox t = getdata(c);
    EditorData p = getdata(t);
    if (p->file) {  /* save existing file without prompt */
	editor_save_file(c, p->filename, CE_UTF8);
	gsetmodified(t, 0);
    }
    /* if new file then prompt for name to save as */
    else editorsaveas(c);
}

static void menueditorsave(control m)
{
    editor c = getdata(m);
    editorsave(c);
    show(c); /* steal focus back from tool button */
}

/* global console configuration variables */
char fontname[LF_FACESIZE+1];
int fontsty, pointsize;

static void editorprint(control m)
{
    printer lpr;
    font f;
    textbox t = getdata(m);
    const char *contents = gettext(t);
    char msg[LF_FACESIZE + 128];
    char *linebuf = NULL;
    int cc, rr, fh, page, linep, i, j, istartline;
    int top, left;

    if (!(lpr = newprinter(0.0, 0.0, ""))) return;
    f = gnewfont(lpr, strcmp(fontname, "FixedFont") ? fontname : "Courier New",
		 fontsty, pointsize, 0.0, 1);
    top = devicepixelsy(lpr) / 5;
    left = devicepixelsx(lpr) / 5;
    fh = fontheight(f);
    rr = getheight(lpr) - top;
    cc = getwidth(lpr) - 2*left;

    linep = rr; /* line in printer page */
    page = 1;
    i = 0;
    while (i < strlen(contents)) {
	if ( linep + fh >= rr ) { /* new page */
	    if (page > 1) nextpage(lpr);
	    snprintf(msg, LF_FACESIZE + 128, "Page %d", page++);
	    gdrawstr(lpr, f, Black, pt(cc - gstrwidth(lpr, f, msg) - 1, top),
		     msg);
	    linep = top + 2*fh;
	}
	j = 0;
	istartline = i;
	while (contents[i] != '\n' && contents[i] != '\0') {
	    ++i; ++j;
	}
	linebuf = realloc(linebuf, (j+1)*sizeof(char));
	strncpy(linebuf, &contents[istartline], j);
	linebuf[j] = '\0';
	gdrawstr(lpr, f, Black, pt(left, linep), linebuf);
	linep += fh;
	++i;
    }
    free(linebuf);
    if (f != FixedFont) del(f);
    del(lpr);
}

static void editorconsole(editor c)
{
    show(RConsole);
}

/* Remove global pointer to editor when closing an editor. Fill the
 * gap in the array with the last editor in the list */

static void editorupdateglobals(editor c)
{
    int i = 0;
    if (neditors > 1) {
	while (REditors[i] != c) ++i;
	if (i < neditors - 1)
	    REditors[i] = REditors[neditors-1];
    }
    --neditors;
}

/* Hooks called when editor window is destroyed */

static void editordel(editor c)
{
    editorupdateglobals(c);
}

static void textboxdel(textbox t)
{
    EditorData p = getdata(t);
    deleditordata(p);
}

int editorchecksave(editor c)
{
    textbox t = getdata(c);
    EditorData p = getdata(t);
    int save;
    char buf[EDITORMAXTITLE + 100];
    if (ggetmodified(t)) {
	snprintf(buf, EDITORMAXTITLE + 100,
		 "\"%s\" has been modified.  Do you want to save the changes?",
		 (p->title ? p->title : "Untitled"));
	save = askyesnocancel(buf);
	switch (save) {
	case YES:
	    editorsave(c);
	    break;
	case NO:
	    break;
	case CANCEL:
	    return 1;
	}
    }
    return 0;
}

static void editorclose(editor c)
{
    if (!editorchecksave(c))
	del(c);
}

static void menueditorclose(control m)
{
    editor c = getdata(m);
    editorclose(c);
}

/* Called when exiting Rgui, check if any open editors need saving */

void editorcleanall(void)
{
    int i;
    for (i = neditors-1;  i >= 0; --i) {
	if (editorchecksave(REditors[i])) {
	    R_ProcessEvents();  // see R_CleanUp
	    jump_to_toplevel();
	}
	del(REditors[i]);
    }
}

static void editornew(void)
{
    Rgui_Edit("", CE_NATIVE, "", 0);
}

void menueditornew(control m)
{
    editornew();
}

static void editoropen(const char *default_name)
{
    wchar_t *wname;
    char name[4*MAX_PATH + 1], title[4*MAX_PATH];

    int i; textbox t; EditorData p;
    setuserfilterW(L"R files (*.R)\0*.R\0S files (*.q, *.ssc, *.S)\0*.q;*.ssc;*.S\0All files (*.*)\0*.*\0\0");
    wname = askfilenameW(G_("Open script"), default_name); /* returns NULL if open dialog cancelled */
    if (wname) {
	wcstoutf8(name, wname, sizeof(name));
	/* check if file is already open in an editor. If so, close and open again */
	for (i = 0; i < neditors; ++i) {
	    t = getdata(REditors[i]);
	    p = getdata(t);
	    if (!strcmp (name, p->filename)) {
		editorclose(REditors[i]);
		break;
	    }
	}
	reEnc2(name, title, MAX_PATH+1, CE_UTF8, CE_NATIVE, 3);
	Rgui_Edit(name, CE_UTF8, title, 0);
    } else show(RConsole);
}

void menueditoropen(control m)
{
    editor c = getdata(m);
    char *default_name = "";
    /* It really is not clear what is meant here: seems to assume an
       editor window but is called from elsewhere, hopefully with NULL
       (since 2.1.1 patched). */
    if (c) {
	textbox t = getdata(c);
	EditorData p = getdata(t);
	if (p->file) default_name = p->filename;  /* name of currently-open file, if there is one */
    }
    editoropen(default_name);
}


/*** EDITING FUNCTIONS ***/

static void editorundo(control m)
{
    textbox t = getdata(m);
    undotext(t);
}

static void editorcut(control m)
{
    textbox t = getdata(m);
    cuttext(t);
}

static void editorcopy(control m)
{
    textbox t = getdata(m);
    copytext(t);
}

static void editorpaste(control m)
{
    textbox t = getdata(m);
    /* check whether the widget text limit needs to be increased
     * before doing the paste */
    int pastelen = getpastelength();
    checklimittext(t, pastelen + 1);
    pastetext(t);
}

static void editordelete(control m)
{
    textbox t = getdata(m);
    cleartext(t);
}

static void editorselectall(control m)
{
    textbox t = getdata(m);
    selecttextex(t, 0, -1);
}

static void editorfind(control m)
{
    textbox t = getdata(m);
    finddialog(t);  /* actual find/replace work is in graphapp/dialogs.c */
}

static void editorreplace(control m)
{
    textbox t = getdata(m);
    replacedialog(t);
}


/*** FUNCTIONS FOR RUNNING R CODE FROM THE EDITOR ***/

static void editorrunline(textbox t)
{
    int length = getlinelength(t); /* return character num */
    char *line = malloc(length * sizeof(WCHAR) + 2); /* Extra space for null and word length in getcurrentline */
    memset(line, 0, length * sizeof(WCHAR) + 2);
    getcurrentline(t, line, length);
    consolecmd(RConsole, line);
    free(line);
    scrollcaret(t, 1);
    show(t);
}

/* For the moment, send the selected text to the console via the
   clipboard. Wasteful, but currently consolecmd only allows a maximum
   of 8K of text */

static void editorrunselection(textbox t, long start, long end)
{
    copytext(t);
    if (consolecanpaste(RConsole)) {
	consolepaste(RConsole);
	if (gettext(t)[end-1] != '\n')
	    consolenewline(RConsole);
    }
}

static Rboolean busy_running = FALSE;

static void editorrun(textbox t)
{
    if (!busy_running) {
	long start=0, end=0;
	if (CharacterMode != RGui) {
	    R_ShowMessage(G_("No RGui console to paste to"));
	    return;
	}
	busy_running = TRUE;
	textselectionex(t, &start, &end);
	if (start >= end)
	    editorrunline(t);
	else {
	    editorrunselection(t, start, end);
	    selecttextex(t, end, end); /* move insertion point to end of selection after running */
	}
	busy_running = FALSE;
    }
}

static void menueditorrun(control m)
{
    textbox t = getdata(m);
    editorrun(t);
}

static void editorrunall(control m)
{
    textbox t = getdata(m);
    long start=0, end=0;
    textselectionex(t, &start, &end); /* save current selection state */
    selecttextex(t, 0, -1);
    editorrun(t);
    selecttextex(t, start, end);  /* return to original selection state */
}

/* Grey out menu buttons as appropriate */

static void editormenuact(control m)
{
    long start, end;
    textbox t = getdata(m);
    EditorData p = getdata(t);
    textselectionex(t, &start, &end);
    if (start < end) {
	enable(p->mcut);
	enable(p->mcopy);
	enable(p->mdelete);
	enable(p->mpopcut);
	enable(p->mpopcopy);
	enable(p->mpopdelete);
    }
    else {
	disable(p->mcut);
	disable(p->mcopy);
	disable(p->mdelete);
	disable(p->mpopcut);
	disable(p->mpopcopy);
	disable(p->mpopdelete);
    }
    if (modeless_active()){
	disable(p->mfind);
	disable(p->mreplace);
    }
    else {
	enable(p->mfind);
	enable(p->mreplace);
    }
    helpmenuact(p->hmenu);
    pkgmenuact(p->pmenu);
}

static void editorresize(editor c, rect r)
{
    resize(getdata(c), r);
    resize(c, r);
}

static void editorcontrolkeydown(textbox t, int key)
{
    switch (key) {
    case F5:
	editorrun(t);
	break;
    }
}

static void editorasciikeydown(textbox t, int key)
{
    /* check whether the text limit is about to be exceeded and
       increase it if necessary.  Ugh - this callback is called after
       the text is inserted, so we make space for two characters */
    checklimittext(t, 2);
}

/* Set keyboard focus to the text editing area when the editor window receives focus */

static void editorfocus(editor c)
{
    textbox t = getdata(c);
    show(t);
}

static void editorhelp(void)
{
    char s[4096];

    strcpy(s, G_("R EDITOR\n"));
    strcat(s, "\n");
    strcat(s, G_("A standard text editor for editing and running R code.\n"));
    strcat(s, "\n");
    strcat(s, G_("RUNNING COMMANDS\n"));
    strcat(s, G_("To run a line or section of R code, select the code and either\n"));
    strcat(s, G_("     Press Ctrl-R\n"));
    strcat(s, G_("     Select \"Run line or selection\" from the \"Edit\" menu\n"));
    strcat(s, G_("     Press the \"Run line or selection\" icon on the toolbar\n"));
    strcat(s, G_("This will copy the selected commands to the console and evaluate them.\n"));
    strcat(s, G_("If there is no selection, this will just run the current line and advance\n"));
    strcat(s, G_("the cursor by one line.\n"));

    askok(s);
}


static void menueditorhelp(control m)
{
    editorhelp();
}

static MenuItem EditorPopup[] = {                /* Numbers used below */
    {GN_("Run line or selection"), menueditorrun, 'R', 0}, /* 0 */
    {"-", 0, 0, 0},
    {GN_("Undo"), editorundo, 'Z', 0},                     /* 2 */
    {"-", 0, 0, 0},
    {GN_("Cut"), editorcut, 'X', 0},                       /* 4 */
    {GN_("Copy"), editorcopy, 'C', 0},                     /* 5 */
    {GN_("Paste"), editorpaste, 'V', 0},                   /* 6 */
    {GN_("Delete"), editordelete, 0, 0},                   /* 7 */
    {"-", 0, 0, 0},
    {GN_("Select all"), editorselectall, 'A', 0},          /* 9 */
    LASTMENUITEM
};

static editor neweditor(void)
{
    int x, y, w, h, w0, h0;
    editor c;
    menuitem m;
    textbox t;
    long flags;
    font editorfn = (consolefn ? consolefn : FixedFont);
    EditorData p = neweditordata(0, NULL);
    DWORD rand;

    w = (pagercol + 1)*fontwidth(editorfn);
    h = (pagerrow + 1)*fontheight(editorfn) + 1;
#ifdef USE_MDI
    if(ismdi()) {
	RECT *pR = RgetMDIsize();
	w0 = pR->right;
	h0 = pR->bottom;
    } else {
#endif
	w0 = devicewidth(NULL);
	h0 = deviceheight(NULL);
#ifdef USE_MDI
    }
#endif
    x = (w0 - w) / 2; x = x > 20 ? x : 20;
    y = (h0 - h) / 2; y = y > 20 ? y : 20;
    rand = GetTickCount();
    w0 = 0.4*x; h0 = 0.4*y;
    w0 = w0 > 20 ? w0 : 20;
    h0 = h0 > 20 ? h0 : 20;
    x += (rand % w0) - w0/2;
    y += ((rand/w0) % h0) - h0/2;
    flags = StandardWindow | Menubar;
#ifdef USE_MDI
    if (ismdi()) flags |= Document;
#endif
    c = (editor) newwindow("", rect(x, y, w, h), flags);
    t = newrichtextarea(NULL, rect(0, 0, w, h));
    setdata(c, t);
    setdata(t, p);

    gsetcursor(c, ArrowCursor);
    setforeground(c, guiColors[editorfg]);
    setbackground(c, guiColors[editorbg]);
    setbackground(t, guiColors[editorbg]);
    
#ifdef USE_MDI
    if (ismdi() && (RguiMDI & RW_TOOLBAR)) {
	int btsize = 24;
	rect r = rect(2, 2, btsize, btsize);
	control tb, bt;
	addto(c);
	MCHECK(tb = newtoolbar(btsize + 4));
	addto(tb);
	MCHECK(bt = newtoolbutton(open_image, r, menueditoropen));
	MCHECK(addtooltip(bt, G_("Open script")));
	setdata(bt, c);
	r.x += (btsize + 1) ;
	MCHECK(bt = newtoolbutton(save_image, r, menueditorsave));
	MCHECK(addtooltip(bt,  G_("Save script")));
	setdata(bt, c);
	r.x += (btsize + 6);
	MCHECK(bt = newtoolbutton(copy1_image, r, menueditorrun));
	MCHECK(addtooltip(bt, G_("Run line or selection")));
	setdata(bt, t);
	r.x += (btsize + 6);
	MCHECK(bt = newtoolbutton(console_image, r, editorconsole));
	MCHECK(addtooltip(bt, G_("Return focus to Console")));
	r.x += (btsize + 6);
	MCHECK(bt = newtoolbutton(print_image, r, editorprint));
	MCHECK(addtooltip(bt, G_("Print script")));
	setdata(bt, t);
	MCHECK(addtooltip(bt, G_("Print")));
    }
#endif
    addto(c);
    /* Right-click context menu */
    MCHECK(m = gpopup(editormenuact, EditorPopup));
    setdata(m, t);
    setdata(EditorPopup[0].m, t);
    setdata(EditorPopup[2].m, t);
    setdata(p->mpopcut = EditorPopup[4].m, t);
    setdata(p->mpopcopy = EditorPopup[5].m, t);
    setdata(EditorPopup[6].m, t);
    setdata(p->mpopdelete = EditorPopup[7].m, t);
    setdata(EditorPopup[9].m, t);

    addto(c);
    MCHECK(m = newmenubar(editormenuact));
    setdata(m, t);
    MCHECK(newmenu(G_("File")));
    MCHECK(m = newmenuitem(G_("New script"), 'N', menueditornew));
    setdata(m, c);
    MCHECK(m = newmenuitem(G_("Open script..."), 'O', menueditoropen));
    setdata(m, c);
    MCHECK(m = newmenuitem(G_("Save"), 'S', menueditorsave));
    setdata(m, c);
    MCHECK(m = newmenuitem(G_("Save as..."), 0, menueditorsaveas));
    setdata(m, c);
    MCHECK(m = newmenuitem("-", 0, NULL));
    MCHECK(m = newmenuitem(G_("Print..."), 'P', editorprint));
    setdata(m, t);
    MCHECK(m = newmenuitem("-", 0, NULL));
    MCHECK(m = newmenuitem(G_("Close script"), 0, menueditorclose));
    setdata(m, c);
    MCHECK(newmenu(G_("Edit")));
    MCHECK(m = newmenuitem(G_("Undo"), 'Z', editorundo));
    setdata(m, t);
    MCHECK(m = newmenuitem("-", 0, NULL));
    MCHECK(p->mcut = newmenuitem(G_("Cut"), 'X', editorcut));
    setdata(p->mcut, t);
    MCHECK(p->mcopy = newmenuitem(G_("Copy"), 'C', editorcopy));
    setdata(p->mcopy, t);
    MCHECK(m = newmenuitem(G_("Paste"), 'V', editorpaste));
    setdata(m, t);
    MCHECK(p->mdelete = newmenuitem(G_("Delete"), 0, editordelete));
    setdata(p->mdelete, t);
    MCHECK(m = newmenuitem(G_("Select all"), 'A', editorselectall));
    setdata(m, t);
    MCHECK(newmenuitem(G_("Clear console"), 'L', menuclear));
    MCHECK(m = newmenuitem("-", 0, NULL));
    MCHECK(m = newmenuitem(G_("Run line or selection"), 'R', menueditorrun));
    setdata(m, t);
    MCHECK(m = newmenuitem(G_("Run all"), 0, editorrunall));
    setdata(m, t);
    MCHECK(m = newmenuitem("-", 0, NULL));
    MCHECK(p->mfind = newmenuitem(G_("Find..."), 'F', editorfind));
    setdata(p->mfind, t);
    MCHECK(p->mreplace = newmenuitem(G_("Replace..."), 'H', editorreplace));
    setdata(p->mreplace, t);
    MCHECK(m = newmenuitem("-", 0, NULL));
    MCHECK(newmenuitem(G_("GUI preferences..."), 0, menuconfig));

    /* Packages menu should go here */
    p->pmenu = (PkgMenuItems) malloc(sizeof(struct structPkgMenuItems));
    RguiPackageMenu(p->pmenu);

#ifdef USE_MDI
    newmdimenu(); /* Create and fill the 'Window' menu */
#endif

    MCHECK(m = newmenu(G_("Help")));
    MCHECK(newmenuitem(G_("Editor"), 0, menueditorhelp));
    MCHECK(newmenuitem("-", 0, NULL));
    p->hmenu = (HelpMenuItems) malloc(sizeof(struct structHelpMenuItems));
    RguiCommonHelp(m, p->hmenu);

    settextfont(t, editorfn);
    setforeground(t, guiColors[editorfg]);    
    setresize(c, editorresize);
    setclose(c, editorclose);
    setdel(c, editordel);
    setdel(t, textboxdel);
    setonfocus(c, editorfocus);
    setkeyaction(t, editorcontrolkeydown);
    setkeydown(t, editorasciikeydown);

    /* Store pointer to new editor in global array */
    REditors[neditors] = c;
    ++neditors;
    return c;
}

/* Change the font used in all running editors */

void editorsetfont(font f)
{
    int i, ismod;
    textbox t;
    for (i = 0; i < neditors; i++) {
	t = getdata(REditors[i]);
	ismod = ggetmodified(t);
	/* Don't change the modification flag when changing font  */
	settextfont(t, f);
	gsetmodified(t, ismod);
	show(t);
    }
}

static void eventloop(editor c)
{
    while (fix_editor_up) {
	/* avoid consuming 100% CPU time here */
	R_WaitEvent();
	R_ProcessEvents();
    }
}

/* Open existing file for editing or open blank editor for a new
   file. If calling from fix() or edit(), then don't send events to
   the console until editor is closed.  */

#include <unistd.h>

int Rgui_Edit(const char *filename, int enc, const char *title,
	      int modal)
{
    editor c;
    EditorData p;

    if (neditors == MAXNEDITORS) {
	R_ShowMessage(G_("Maximum number of editors reached"));
	return 1;
    }
    c = neweditor();
    if (!c) {
	R_ShowMessage(G_("Unable to create editor window"));
	return 1;
    }
    if (strlen(filename) > 0) {
	editor_load_file(c, filename, enc);
	editor_set_title(c, title);
    }
    else {
	editor_set_title(c, G_("Untitled"));
    }
    show(c);

    p = getdata(getdata(c));
    p->stealconsole = modal;
    if (modal) {
	fix_editor_up = TRUE;
	eventloop(c);
    }
    return 0;
}
