# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - Editor Action
    Version 0.1

    ?action=Editor

    Edits a page.

    @copyright: 2007 by Kenneth Bull
    @license: GNU GPL, see COPYING for details.

"""

import os, codecs
from MoinMoin import config, wikiutil
from MoinMoin.util import filesys
from MoinMoin.Page import Page
from MoinMoin.widget import html
from MoinMoin.widget.dialog import Status
from MoinMoin.logfile import editlog, eventlog

def execute(pagename, request):
    _ = request.getText
    pg = Page(request,pagename)
    backto = request.form.get('backto', [None])[0]
    page = backto and Page(request, backto) or pg
    rev = pg.exists() and pg.current_rev() or 0

    if not request.user.may.write(pagename):
        page.send_page(request, msg = _('You are not allowed to edit this page.'))
        return
    if not pg.isWritable():
        page.send_page(request, msg = _('Page is immutable!'))
        return

    if 'button_cancel' in request.form:
        page.send_page(request, msg = _('Edit Cancelled'));
        return
    if 'button_save' in request.form:
        savetext = '\n'.join(request.form.get('savetext',[''])[0].splitlines())
        if savetext[-1] != '\n':
            savetext += '\n'

        action = "SAVE" if pg.exists() else "SAVENEW"

        from MoinMoin.wikiacl import parseACL
        #from MoinMoin.security import parseACL
        if (not request.user.may.admin(pagename) and
            parseACL(request, savetext).acl != acl.acl):
            page.send_page(msg = _("You can't change ACLs on this page since you have no admin rights on it!"))
            return

        pagedir = pg.getPagePath(use_underlay=0, check_create=1)
        revdir = os.path.join(pagedir, 'revisions')
        cfn = os.path.join(pagedir, 'current')
        clfn = os.path.join(pagedir, 'current-locked')
        pagelog = pg.getPagePath('edit-log', use_underlay=0, isfile=1)
        llog = editlog.EditLog(request, filename=pagelog,
                               uid_override=None)
        glog = editlog.EditLog(request, uid_override=None)
        if not os.path.exists(revdir):
            os.mkdir(revdir)
            f = file(cfn, 'w')
            f.write('%08d\n' % 0)
            f.close()

        got_lock = False
        retry = 0

        try:
            while not got_lock and retry < 100:
                retry += 1
                try:
                    filesys.rename(cfn, clfn)
                    got_lock = True
                except OSError, err:
                    got_lock = False
                    if err.errno == 2: # there was no 'current' file
                        time.sleep(0.1)
                    else:
                        page.send_page(request, msg = _("Page could not get locked. Unexpected error (errno=%d).") % err.errno)

            if not got_lock:
                page.send_page(request, msg = _("Page could not get locked. Missing 'current' file?"))

            # increment rev number of current(-locked) page
            f = file(clfn)
            revstr = f.read()
            f.close()
            rev = int(revstr)
            if rev == 0:
                rev += 1
            revstr = '%08d' % rev
            f = file(clfn, 'w')
            f.write(revstr+'\n')
            f.close()

            # save to page file
            pagefile = os.path.join(revdir, revstr)
            f = codecs.open(pagefile, 'wb', config.charset)
            # Write the file using text/* mime type
            f.write(pg.encodeTextMimeType(savetext))
            f.close()
            mtime_usecs = wikiutil.timestamp2version(os.path.getmtime(pagefile))
            # set in-memory content
            pg.set_raw_body(savetext)

            # reset page object
            pg.reset()


            # write the editlog entry
            # for now simply make 2 logs, better would be some multilog stuff maybe
            glog.add(request, mtime_usecs, rev, action, pg.page_name, None, u'', u'')
            llog.add(request, mtime_usecs, rev, action, pg.page_name, None, u'', u'')
        finally:
            if got_lock:
                filesys.rename(clfn, cfn)

        # add event log entry
        elog = eventlog.EventLog(request)
        elog.add(request, 'SAVEPAGE', {'pagename': pg.page_name}, 1, mtime_usecs)

        pg.clean_acl_cache()
        page.send_page(request)
        return

    raw_body = pg.get_raw_body() if pg.exists() else _('Describe %s here.') % (pg.page_name,)
    wikiutil.send_title(request,
        _('Edit "%(pagename)s"') % {'pagename': pg.split_title(request), },
        page = pg, pagename = pagename,
        msg = Status(request, content=''),
        html_head = '',
        editor_mode = 1)
    request.write(request.formatter.startContent("content"))

    request.write('<form id="editor" method="post" action="%s/%s" onSubmit="flgChange = false;">' % (
        request.getScriptname(),
        wikiutil.quoteWikinameURL(pagename)))
    request.write('<fieldset style="border:none;padding:0;">')
    request.write(unicode(html.INPUT(type="hidden", name="action", value="Editor")))
    request.write(unicode(html.INPUT(type="hidden", name="do", value="submit")))
    request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto)))
    request.write(unicode(html.INPUT(type="hidden", name="rev", value=str(rev))))

    save_button_text = _('Save Changes')
    cancel_button_text = _('Cancel')
    
    if pg.cfg.page_license_enabled:
        request.write('<p><em>', _(
"""By hitting '''%(save_button_text)s''' you put your changes under the %(license_link)s.
If you don't want that, hit '''%(cancel_button_text)s''' to cancel your changes.""") % {
            'save_button_text': save_button_text,
            'cancel_button_text': cancel_button_text,
            'license_link': wikiutil.getLocalizedPage(request, pg.cfg.page_license_page).link_to(request),
        }, '</em></p>')

    request.write('''<input class="button" type="submit" name="button_save" value="%s">''' % save_button_text);
    request.write('''<input class="button" type="submit" name="button_cancel" value="%s">''' % cancel_button_text);

    try:
        text_rows = int(form['rows'][0])
    except StandardError:
        text_rows = pg.cfg.edit_rows
        if request.user.valid:
            text_rows = int(request.user.edit_rows)

    request.write(u'''
<textarea id="editor-textarea" name="savetext" rows="%(rows)d" cols="80"
          onChange="flgChange = true;" onKeyPress="flgChange = true;">%(text)s</textarea>
''' % {'rows': text_rows, 'text': wikiutil.escape(raw_body)})
    
    request.write('</fieldset>')
    request.write("</form>")

    request.write(request.formatter.endContent())
    wikiutil.send_footer(request,pagename)

