/*

    Minimum Profit 5.x
    A Programmer's Text Editor

    Miscellaneous editor actions.

    Copyright (C) 1991-2012 Angel Ortega <angel@triptico.com>

    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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    http://triptico.com

*/

/** editor actions **/

mp.actions['eval']  = sub { 
    local t = mp.form(
        [
            {
                label:      L("Code to execute:"),
                type:       'text',
                history:    'eval'
            }
        ]
    );

    if (t != NULL) {
        t = t[0];

        if (! regex(t, '/;\s*$/'))
            t = t ~ ';';

        t = eval(t);

        if (ERROR != NULL) {
            mp.alert(L("Error: ") ~ ERROR);
            ERROR = NULL;
        }
        else
        if (t != NULL)
            mp.alert(L("Exit value:\n") ~ t);
    }
};

mp_doc.actions['eval_doc']  = sub (d) {
	local t = join(d->get_active_area(), "\n");

	if (t != NULL) {
		t = eval(t);

		if (ERROR != NULL) {
			mp.alert(L("Error: ") ~ ERROR);

			/* try to move the cursor to the line
			   where the error was */
			local l = regex(ERROR, [ '/, line /', '/[0-9]+/' ]);

			if (size(l) == 2)
                d->set_y(l[1]);

			ERROR = NULL;
		}
	}
};

mp_doc.actions['insert_next_item'] = sub(doc) {
    local n = 0;

    foreach (l, doc.txt.lines) {
        local r = regex(l, ['/^ \* /', '/[0-9]+/', '/: /']);

        if (r[1] > n)
            n = r[1];
    }

    doc->store_undo()->insert(' * ' ~ (n + 1) ~ ': ');
};

mp_doc.actions['insert_time_stamp'] = sub(doc) {
    doc->store_undo()->insert(strftime(mp.config.time_stamp_format));
};

mp_doc.actions['exec_action'] = sub {
    local l = join(keys(mp.actions), keys(mp_doc.actions))->sort();

    l = map(l, sub (e) { e ~ ' - ' ~ L(mp.actdesc[e] || ''); });

    local r = mp.form(
        [
            {
                label:  L("Select action to execute:"),
                type:   'list',
                list:   l
            }
        ]
    );

    if (r != NULL) {
        local a = regex(l[r[0]], '/^[^ ]+/');

        mp.process_action(a);
    }
};

mp.actions['encoding']  = sub {
    local l = EMBEDDED_ENCODINGS->hmap(sub (k, v) { [v, k]; })->keys()->sort();
    ins(l, L("<current locale>"), 0);

    local t = mp.form(
        [
            {
                label:  L("Available encodings"),
                type:   'list',
                list:   l
            }
        ]
    );

    if (t != NULL) {
        local e = t[0] && l[t[0]] || '';

        if (encoding(e) == -1)
            mp.alert(L("Invalid encoding ") ~ e);
    }
};

mp.actions['zoom_in']   = sub {
    mp.config.font_size++;
    mp.update_ui();
};

mp.actions['zoom_out']  = sub {
    if (mp.config.font_size > 4) {
        mp.config.font_size--;
        mp.update_ui();
    }
};

mp.actions['about'] = sub {
    local msg = L(
    "Minimum Profit %s (%s) - Programmer Text Editor\n\n"\
    "Components: MPDM %s, MPSL %s\n\n"\
    "Copyright (C) 1991-2014 Angel Ortega <angel@triptico.com> and others\n"\
    "\n"\
    "This program is free software; you can redistribute it and/or\n"\
    "modify it under the terms of the GNU General Public License\n"\
    "as published by the Free Software Foundation; either version 2\n"\
    "of the License, or (at your option) any later version.\n"\
    "\n"\
    "This program is distributed in the hope that it will be useful,\n"\
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"\
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"\
    "See the GNU General Public License for more details.\n"\
    "\n"\
    "You should have received a copy of the GNU General Public License\n"\
    "along with this program; if not, write to the Free Software Foundation,\n"\
    "Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"\
    "\n"\
    "Home page: http://triptico.com/software/mp.html\n");

    local mpdm = MPDM();
    msg = sprintf(msg, mp.VERSION, (mp_drv.id || 'unknown'), mpdm.version, MPSL.VERSION);

    local d = mp.open("<about>");

    if (size(d.txt.lines) == 1) {
        d->insert(msg)->move_bof();
        d.txt.mod = 0;
        d.read_only = 1;
    }
};


mp.actions.check_for_updates = sub {
    local d = mp.open("<updates>");

    d->move_bof();
    d.txt.mod   = 0;
    d.read_only = 1;

    mp.busy(1);

    local c = [];
    local f = connect("triptico.com", "www");

    if (f != NULL) {
        local l;

        write(f, "GET /download/mp_release_notes HTTP/1.1\r\n");
        write(f, "Host: triptico.com\r\n");
        write(f, "User-Agent: Minimum Profit ",
            mp.VERSION, " (", mp_drv.id, ") Update Checker\r\n");
        write(f, "Connection: close\r\n\r\n");

        /* ignore HTTP response */
        while ((l = read(f)) != NULL) {
            l = mp.chomp(l);

            if (l eq '')
                break;
        }

        /* content */
        /* drop first 3 lines */
        read(f);
        read(f);
        read(f);

        /* read until current version is found or EOF */
        local st = 0;

        while ((l = read(f)) != NULL) {
            l = mp.chomp(l);

            if (regex(l, "/^[0-9]+\.[0-9]+\.[0-9]+$/")) {
                st = cmp(mp.normalize_version(l), mp.normalize_version(mp.VERSION));

                if (st <= 0)
                    break;
            }

            push(c, l);
        }

        close(f);

        if (size(c) == 0) {
            if (st < 0)
                c = [L("You have a development version newer than any stable release."), ''];
            else
                c = [L("You already have the latest version."), ''];
        }
        else {
            ins(c, "", 0);
            ins(c, L("There are new versions available:"), 0);
            push(c, "", L("Update Minimum Profit from http://triptico.com/software/mp.html"), "");
        }
    }
    else {
        c = [ L("Cannot connect -- please try later."), '' ];
    }

    mp.busy(0);

    d.txt.lines = c;
};


/** default key bindings **/

mp.keycodes['escape']           = 'eval';
mp.keycodes['f12']              = 'zoom_in';
mp.keycodes['ctrl-kp-plus' ]    = 'zoom_in';
mp.keycodes['f11']              = 'zoom_out';
mp.keycodes['ctrl-kp-minus' ]   = 'zoom_out';

/** action descriptions **/

mp.actdesc['eval']              = LL("Execute MPSL code...");
mp.actdesc['eval_doc']          = LL("Execute document as MPSL");
mp.actdesc['exec_action']       = LL("Execute action on document...");
mp.actdesc['insert_next_item']  = LL("Insert next item");
mp.actdesc['insert_time_stamp'] = LL("Insert time stamp");
mp.actdesc['encoding']          = LL("Set charset encoding...");
mp.actdesc['zoom_in']           = LL("Bigger font");
mp.actdesc['zoom_out']          = LL("Smaller font");
mp.actdesc['about']             = LL("About...");
mp.actdesc['check_for_updates'] = LL("Check for updates...");

/** code **/

sub dump(v)
/* overwrite of the MPSL dump() function, dumping over a text document */
{
    local d = mp.open("<dump>");

    d->move_eof()->insert(dumper(v));
    d.txt.mod   = 0;
    d.read_only = 1;
    d.syntax    = mp.syntax.mpsl;
}


sub mp.add_keyseq(seq, keycode)
{
    local p = mp.keycodes.ansi;
    local l = split(seq);
    local v = pop(l);

    /* split by character and store as a chain of hashes
       with the keycode as the final, scalar value */
    foreach (k, l) {
        if (! p[k])
            p[k] = {};
        p = p[k];
    }

    p[v] = keycode;
}
