# -*- coding: utf-8 -*-
"""
    MoinMoin - TaskPlanner Action
    Version 0.9

    A task planner plugin for Moin.

    General information:
    * The task database file "task-db" is located in the wiki's data dir and is
      a plain text file.
    * The total number of tasks is currently restricted to 999.999 tasks. However
      a plain text database doesn't scale very well. So try to keep the database
      small and do remove task not needed anymore.
    * Note: Removing a task from the database does also mean: deleting the task's wiki
      homepage.
    * Note: You have to be superuser to be able to remove tasks. Normal users can mark
      a completed task with the label "remove me" so superuser get to know which tasks to
      remove.
 
    @copyright: 2007 by Oliver Siemoneit
    @license: GNU GPL, see COPYING for details.

"""

import os, time
from MoinMoin import config, wikiutil, user
from MoinMoin.Page import Page
from MoinMoin.util import timefuncs


def _make_unique_task_id(request):
    """
        Make unique task id
        
        @param request: request object
        @return: 6-digit id (string)
    """
    from random import randint
    databaseFile = os.path.join(request.cfg.data_dir, "task-db")
    if os.path.isfile(databaseFile):
        existing_id = task_id = 0
        while task_id == existing_id:
            task_id = "%06d" % randint(1, 999999)
            for line in open(databaseFile).readlines():
                    tmp = line.split("\t")
                    existing_id = tmp[0]
                    if existing_id == task_id:
                        break
    else:
       task_id = "%06d" % randint(1, 999999)

    return task_id


def _make_local_timestamp(request):
    """
        Make a timestamp for creation/closing of task

        @param request: request object
        @return: timestamp (string)
    """
    now = time.time()
    user = request.user

    if user.valid and user.tz_offset:
        tz = user.tz_offset
        tz -= tz % 60
        minutes = tz / 60
        hours = minutes / 60
        minutes -= hours * 60
        now += tz

    return time.strftime("%Y.%m.%dT%H:%M:%S", timefuncs.tmtuple(now))


def do_mainform(request, actname, msg=None):
    """
        Build the main form

        @param request: request object
        @param actname: actname object 
        @param msg: message to display
        @return: html form (string)
    """
    _ = request.getText
    ticket = wikiutil.createTicket(request)
    querytext = _('TaskPlanner User Interface')
    button1 = _('Add Task')
    button2 = _('Edit Task')
    button3 = _('Remove Task')
    button4 = _('Close')

    formhtml1 = '''
<form method="post" action="">
<strong>%s <br></strong>''' % querytext
    
    if msg:
        formhtml2 = "<br> %s <br>" % msg
    else:
        formhtml2 = ""

    formhtml3 = '''
<br> 
<input type="hidden" name="action" value="%(actname)s">
<input type="hidden" name="ticket" value="%(ticket)s">
<input class="buttons" type="submit" name="button_add" value="%(button1)s">
<input class="buttons" type="submit" name="button_edit" value="%(button2)s"> '''  % {
    'actname'  : actname,
    'ticket'   : ticket,
    'button1'  : button1,
    'button2'  : button2, }

    if request.user.isSuperUser():
        formhtml4 = '''
<input class="buttons" type="submit" name="button_remove" value="%(button3)s">''' % {
    'button3'  : button3, }
    
    else:
        formhtml4 = ""

    formhtml5 = '''
<input class="buttons" type="submit" name="button_cancel" value="%(button4)s">
</form>''' % {
    'button4'  : button4, }
    
    formhtml = formhtml1 + formhtml2 + formhtml3 + formhtml4 + formhtml5
    return formhtml


def do_addform(request, actname, page, msg=None, assoc_page=None, assign=None):
    """
        Build the 'add task' form
        
        @param request: request object
        @param actname: actname object
        @param page: page object
        @param msg: message to display
        @param assoc_page: preset page association (by TaskTable macro)
        @param assign: preset assign (by TaskTable macro)
        @return: html form (string)
    """
    _ = request.getText
    ticket = wikiutil.createTicket(request)
    task_id = _make_unique_task_id(request)
    querytext = _('Add Task')
    button1 = _('Add')
    button2 = _('Cancel')
    label1 = _('Task ID')
    value1 = task_id 
    label2 = _('Created by')
    value2 = request.user.name
    label3 = _('Created on')
    value3 = _make_local_timestamp(request)
    label4 = _('Task name')
    value4 = ""
    label5 = _('Assigned to')
    if assign:
        value5 = assign.replace('%20', ' ')
    else:
        value5 = ""
    label6 = _('Time-frame')
    value6 = ""
    label7 = _('Priority')
    value7 = ""
    label8 = _('Status')
    value8 = _('to do')
    label9 = _('Task description')
    value9 = ""
    label10 = _('Task\'s wiki homepage')
    value10 = "Taskplanner/%s" % task_id
    label11 = _('Task associated with page')
    if assoc_page:
        value11 = assoc_page.replace('%20', ' ')
    else:
        value11 = page.page_name

    formhtml1 = '''
<form method="post" action="">
<div class="userpref">
<strong>%s <br></strong>''' % querytext
    
    if msg:
        formhtml2 = "%s" % msg
    else:
        formhtml2 = ""

    formhtml3 = '''
<br>
<input type="hidden" name="action" value="%(actname)s">
<input type="hidden" name="ticket" value="%(ticket)s">
<input type="hidden" name="closed_by" value="unknown">
<input type="hidden" name="closed_at" value="unknown">
<table border="0">
    <tr>
        <td class="label"><label>%(label1)s</label></td>
        <td class="content">
            <input type="text" name="task_id" value="%(value1)s" size="6" readonly="readonly">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label2)s</label></td>
        <td class="content">
            <input type="text" name="created_by" value="%(value2)s" size="36" readonly="readonly">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label3)s</label></td>
        <td class="content">
            <input type="text" name="created_at" value="%(value3)s" size="36" readonly="readonly">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label4)s</label></td>
        <td class="content">
            <input type="text" name="task_name" value="%(value4)s" size="36" maxlength="50">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label5)s</label></td>
        <td class="content">
            <input type="text" name="assigned_to" value="%(value5)s" size="36" maxlength="100">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label6)s</label></td>
        <td class="content">
            <input type="text" name="time_frame" value="%(value6)s" size="36" maxlength="20">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label7)s</label></td>
        <td class="content">
             <select name="priority" size="1">
               <option selected value="">   </option>
               <option value="low">%(low)s</option>
               <option value="medium">%(medium)s</option>
               <option value="high">%(high)s</option>
               <option value="critical">%(critical)s</option>
             </select>
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label8)s</label></td>
        <td class="content">
             <select name="status" size="1">
               <option selected value="to do">%(ToDo)s</option>
               <option value="in progress">%(InProgress)s</option>
               <option value="pending">%(Pending)s</option>
             </select>
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label9)s</label></td>
        <td class="content">
            <input type="text" name="task_desc" value="%(value9)s" size="80" maxlength="100">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label10)s</label></td>
        <td class="content">
            <input type="text" name="task_disc_page" value="%(value10)s" size="80" maxlength="100">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label11)s</label></td>
        <td class="content">
            <input type="text" name="task_assoc" value="%(value11)s" size="80" maxlength="100">
        </td>
    </tr>
    <tr>
        <td> </td>
        <td>
        <input class="buttons" type="submit" name="button_add_a" value="%(button1)s">
        <input class="buttons" type="submit" name="button_back" value="%(button2)s">
        </td>
    </tr>
</table>
</div>
</form>''' % {
    'actname'    : actname,
    'ticket'     : ticket,
    'label1'     : label1,
    'value1'     : value1,
    'label2'     : label2,
    'value2'     : value2,
    'label3'     : label3,
    'value3'     : value3,
    'label4'     : label4,
    'value4'     : value4,
    'label5'     : label5,
    'value5'     : value5,
    'label6'     : label6,
    'value6'     : value6,
    'label7'     : label7,
    'low'        : _('low'),
    'medium'     : _('medium'),
    'high'       : _('high'),
    'critical'   : _('critical'),
    'label8'     : label8,
    'ToDo'       : _('to do'),
    'Pending'    : _('pending'),
    'InProgress' : _('in progress'),
    'label9'     : label9,
    'value9'     : value9,
    'label10'    : label10,
    'value10'    : value10,
    'label11'    : label11,
    'value11'    : value11,
    'button1'    : button1,
    'button2'    : button2
}
    formhtml = formhtml1 + formhtml2 + formhtml3
    return formhtml


def _check_form_input(request):
    """
        Check for valid input in 'add task' and 'edit task' form

        @param request: request object
        @result: result (string)
    """
    _ = request.getText
    task_name = request.form.get('task_name', [""])[0]
    task_name = task_name.strip(' ')
    if task_name == "":
        return (_('You have to specify a task name.'), "warning")

    assigned_to = request.form.get('assigned_to', [""])[0]
    assigned_to = assigned_to.strip(' ')
    if assigned_to == "":
        return (_('You have to assign the task to someone.'), "warning")

    time_frame = request.form.get('time_frame', [""])[0]
    time_frame = time_frame.strip(' ')
    if time_frame != "":
        from time import strptime
        try:
            time_struct = strptime(time_frame, "%d.%m.%y")
        except ValueError:
            try:
                time_struct = strptime(time_frame, "%d.%m.%y %H:%M")
            except ValueError:
                return (_('Valid time-frame formats are either dd.mm.yy or dd.mm.yy hh:mm.'),"warning")
    return ""


def _save_task(request):
    """
        Save task data to disc

        @param request: request object
        @return: result (string)
    """
    _ = request.getText
    task_id = request.form.get('task_id', [""])[0]
    created_by = request.form.get('created_by', [""])[0]
    created_at = request.form.get('created_at', [""])[0]
    closed_by = request.form.get('closed_by', [""])[0]
    closed_at = request.form.get('closed_at', [""])[0]
    task_name = request.form.get('task_name', [""])[0]
    task_name = wikiutil.escape(task_name, 1)
    task_name = wikiutil.clean_input(task_name)
    assigned_to = request.form.get('assigned_to', [""])[0]
    assigned_to = wikiutil.escape(assigned_to, 1)
    assigned_to = wikiutil.clean_input(assigned_to)
    time_frame = request.form.get('time_frame', [""])[0]
    priority = request.form.get('priority', [""])[0]
    status = request.form.get('status', [""])[0]
    task_desc = request.form.get('task_desc', [""])[0]
    if task_desc != "":
        task_desc = wikiutil.escape(task_desc, 1)
        task_desc = wikiutil.clean_input(task_desc)
    task_disc_page = request.form.get('task_disc_page', [""])[0]
    if task_disc_page != "":
        task_disc_page = wikiutil.escape(task_disc_page, 1)
        task_disc_page = wikiutil.clean_input(task_disc_page)
    task_assoc = request.form.get('task_assoc', [""])[0]
    if task_assoc != "":
        task_assoc = wikiutil.escape(task_assoc, 1)
        task_assoc = wikiutil.clean_input(task_assoc)
            
    try:
        databaseFile = os.path.join(request.cfg.data_dir, "task-db")
        db = open(databaseFile,"a")
        db.write("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (task_id,
                                                                           created_by,
                                                                           created_at,
                                                                           closed_by,
                                                                           closed_at,
                                                                           task_name,
                                                                           assigned_to,
                                                                           time_frame,
                                                                           priority,
                                                                           status,
                                                                           task_desc,
                                                                           task_disc_page,
                                                                           task_assoc))
        db.close()
    except IOError:
        return (_('Error while trying to save task data.'), "error")
    return (_('Task successfully saved.'), "ok")


def do_edit_search_form(request, actname, msg=None):
    """
        Build the 'search task for editing' form

        @param request: request object
        @param actname: actname object
        @param msg: message to display
        @return: html form (string)
    """
    _ = request.getText
    ticket = wikiutil.createTicket(request)
    querytext = _('Edit Task')
    button1 = _('Edit')
    button2 = _('Cancel')
    label1 = _('Task ID')
    value1 = ""

    formhtml1 = '''
<form method="post" action="">
<div class="userpref">
<strong>%s <br></strong>''' % querytext
    
    if msg:
        formhtml2 = "%s" % msg
    else:
        formhtml2 = ""

    formhtml3 = '''
<br>
<input type="hidden" name="action" value="%(actname)s">
<input type="hidden" name="ticket" value="%(ticket)s">
<table border="0">
    <tr>
        <td class="label"><label>%(label1)s</label></td>
        <td class="content">
            <input type="text" name="task_id" value="%(value1)s" size="6" maxlength="6">
        </td>
    </tr>
    <tr>
        <td> </td>
        <td>
        <input class="buttons" type="submit" name="button_search_id" value="%(button1)s">
        <input class="buttons" type="submit" name="button_back" value="%(button2)s">
        </td>
    </tr>
</table>
</div>
</form>''' % {
    'actname': actname,
    'ticket' : ticket,
    'label1' : label1,
    'value1' : value1,
    'button1': button1,
    'button2': button2
}
    formhtml = formhtml1 + formhtml2 + formhtml3
    return formhtml


def do_editform(request, actname, page, task, msg=None):
    """
        Build the 'edit task' form

        @param request: request object
        @param actname: actname object
        @param page: page object
        @param task: task to edit
        @param msg: message to display
        @return: html form (string)
    """
    _ = request.getText
    ticket = wikiutil.createTicket(request)
    querytext = _('Edit Task')
    button1 = _('Save')
    button2 = _('Cancel')
    label1 = _('Task ID')
    value1 = task[0] 
    label2 = _('Created by')
    value2 = task[1]
    label3 = _('Created on')
    value3 = task[2]
    label4 = _('Closed by')
    value4 = task[3]
    label5 = _('Closed at')
    value5 = task[4]
    label6 = _('Task name')
    value6 = task[5]
    label7 = _('Assigned to')
    value7 = task[6]
    label8 = _('Time-frame')
    value8 = task[7]
    label9 = _('Priority')
    value9 = task[8]
    label10 = _('Status')
    value10 = task[9]
    label11 = _('Task description')
    value11 = task[10]
    label12 = _('Task\'s wiki homepage')
    value12 = task[11]
    label13 = _('Task associated with page')
    value13 = task[12]
    
    formhtml1 = '''
<form method="post" action="">
<div class="userpref">
<strong>%s <br></strong>''' % querytext

    if msg:
        formhtml2 = "%s" % msg
    else:
        formhtml2 = ""

    formhtml3 = '''
<br>
<input type="hidden" name="action" value="%(actname)s">
<input type="hidden" name="ticket" value="%(ticket)s">
<table border="0">
    <tr>
        <td class="label"><label>%(label1)s</label></td>
        <td class="content">
            <input type="text" name="task_id" value="%(value1)s" size="6" readonly="readonly">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label2)s</label></td>
        <td class="content">
            <input type="text" name="created_by" value="%(value2)s" size="36" readonly="readonly">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label3)s</label></td>
        <td class="content">
            <input type="text" name="created_at" value="%(value3)s" size="36" readonly="readonly">
        </td>
    </tr> ''' % {
        'actname': actname,
        'ticket' : ticket,
        'label1' : label1,
        'value1' : value1,
        'label2' : label2,
        'value2' : value2,
        'label3' : label3,
        'value3' : value3
}
    
    if value4 != "unknown":
        formhtml4 = '''
   <tr>
        <td class="label"><label>%(label4)s</label></td>
        <td class="content">
            <input type="text" name="closed_by" value="%(value4)s" size="36" readonly="readonly">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label5)s</label></td>
        <td class="content">
            <input type="text" name="closed_at" value="%(value5)s" size="36" readonly="readonly">
        </td>
    </tr> ''' % {
        'label4' : label4,
        'value4' : value4,
        'label5' : label5,
        'value5' : value5
}
    else:
        formhtml4 = '''
<input type="hidden" name="closed_by" value="%(value4)s">
<input type="hidden" name="closed_at" value="%(value5)s"> ''' % {
    'value4' : value4,
    'value5' : value5
}

    formhtml5 = '''
    <tr>
        <td class="label"><label>%(label6)s</label></td>
        <td class="content">
            <input type="text" name="task_name" value="%(value6)s" size="36" maxlength="50">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label7)s</label></td>
        <td class="content">
            <input type="text" name="assigned_to" value="%(value7)s" size="36" maxlength="100">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label8)s</label></td>
        <td class="content">
            <input type="text" name="time_frame" value="%(value8)s" size="36" maxlength="20">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label9)s</label></td>
        <td class="content">
             <select name="priority" size="1"> ''' % {
                 'label6' : label6,
                 'value6' : value6,
                 'label7' : label7,
                 'value7' : value7,
                 'label8' : label8,
                 'value8' : value8,
                'label9'  : label9
}
    # ToDo: Make code more compact. Don't use if value9 = ..
    if value9 == "":
        formhtml6 = '''    
                   <option selected value="">   </option>
                   <option value="low">%(low)s</option>
                   <option value="medium">%(medium)s</option>
                   <option value="high">%(high)s</option>
                   <option value="critical">%(critical)s</option>
                 </select>''' % { 'low'      : _('low'),
                                  'medium'   : _('medium'),
                                  'high'     : _('high'),
                                  'critical' : _('critical') }

    if value9 == "low":
        formhtml6 = '''    
                   <option value="">   </option>
                   <option selected value="low">%(low)s</option>
                   <option value="medium">%(medium)s</option>
                   <option value="high">%(high)s</option>
                   <option value="critical">%(critical)s</option>
                 </select>''' % { 'low'      : _('low'),
                                  'medium'   : _('medium'),
                                  'high'     : _('high'),
                                  'critical' : _('critical') }

    if value9 == "medium":
        formhtml6 = '''    
                   <option value="">   </option>
                   <option value="low">%(low)s</option>
                   <option selected value="medium">%(medium)s</option>
                   <option value="high">%(high)s</option>
                   <option value="critical">%(critical)s</option>
                 </select>''' % { 'low'      : _('low'),
                                  'medium'   : _('medium'),
                                  'high'     : _('high'),
                                  'critical' : _('critical') }

    if value9 == "high":
        formhtml6 = '''    
                   <option value="">   </option>
                   <option value="low">%(low)s</option>
                   <option value="medium">%(medium)s</option>
                   <option selected value="high">%(high)s</option>
                   <option value="critical">%(critical)s</option>
                 </select>''' % { 'low'      : _('low'),
                                  'medium'   : _('medium'),
                                  'high'     : _('high'),
                                  'critical' : _('critical') }

    if value9 == "critical":
        formhtml6 = '''    
                   <option value="">   </option>
                   <option value="low">%(low)s</option>
                   <option value="medium">%(medium)s</option>
                   <option value="high">%(high)s</option>
                   <option selected value="critical">%(critical)s</option>
                 </select>''' % { 'low'      : _('low'),
                                  'medium'   : _('medium'),
                                  'high'     : _('high'),
                                  'critical' : _('critical') }

    formhtml7 = '''
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label10)s</label></td>
        <td class="content">
             <select name="status" size="1"> ''' % {
                 'label10' : label10 }

    # ToDo: Make code more compact. Don't use if value10 = ..
    if value10 == "to do":
        formhtml8 = '''
               <option selected value="to do">%(ToDo)s</option>
               <option value="in progress">%(InProgress)s</option>
               <option value="pending">%(Pending)s</option>
               <option value="done">%(Done)s</option>
               <option value="failed">%(Undone)s</option>
               <option value="closed">%(Closed)s</option>
               <option value="remove me">%(RemoveMe)s</option>''' % { 'ToDo'       : _('to do'),
                                                                     'InProgress' : _('in progress'),
                                                                     'Pending'    : _('pending'),
                                                                     'Done'       : _('done'),
                                                                     'Undone'     : _('failed'),
                                                                     'Closed'     : _('closed'),
                                                                     'RemoveMe'   : _('remove me') }

    if value10 == "in progress":
        formhtml8 = '''
               <option value="to do">%(ToDo)s</option>
               <option selected value="in progress">%(InProgress)s</option>
               <option value="pending">%(Pending)s</option>
               <option value="done">%(Done)s</option>
               <option value="failed">%(Undone)s</option>
               <option value="closed">%(Closed)s</option>
               <option value="remove me">%(RemoveMe)s</option>''' % { 'ToDo'       : _('to do'),
                                                                     'InProgress' : _('in progress'),
                                                                     'Pending'    : _('pending'),
                                                                     'Done'       : _('done'),
                                                                     'Undone'     : _('failed'),
                                                                     'Closed'     : _('closed'),
                                                                     'RemoveMe'   : _('remove me') }

    if value10 == "pending":
        formhtml8 = '''
               <option value="to do">%(ToDo)s</option>
               <option value="in progress">%(InProgress)s</option>
               <option selected value="pending">%(Pending)s</option>
               <option value="done">%(Done)s</option>
               <option value="failed">%(Undone)s</option>
               <option value="closed">%(Closed)s</option>
               <option value="remove me">%(RemoveMe)s</option>''' % { 'ToDo'       : _('to do'),
                                                                     'InProgress' : _('in progress'),
                                                                     'Pending'    : _('pending'),
                                                                     'Done'       : _('done'),
                                                                     'Undone'     : _('failed'),
                                                                     'Closed'     : _('closed'),
                                                                     'RemoveMe'   : _('remove me') }

    if value10 == "done":
        formhtml8 = '''
               <option value="to do">%(ToDo)s</option>
               <option value="in progress">%(InProgress)s</option>
               <option value="pending">%(Pending)s</option>
               <option selected value="done">%(Done)s</option>
               <option value="failed">%(Undone)s</option>
               <option value="closed">%(Closed)s</option>
               <option value="remove me">%(RemoveMe)s</option>''' % { 'ToDo'       : _('to do'),
                                                                     'InProgress' : _('in progress'),
                                                                     'Pending'    : _('pending'),
                                                                     'Done'       : _('done'),
                                                                     'Undone'     : _('failed'),
                                                                     'Closed'     : _('closed'),
                                                                     'RemoveMe'   : _('remove me') }

    if value10 == "failed":
        formhtml8 = '''
               <option value="to do">%(ToDo)s</option>
               <option value="in progress">%(InProgress)s</option>
               <option value="pending">%(Pending)s</option>
               <option value="done">%(Done)s</option>
               <option selected value="failed">%(Undone)s</option>
               <option value="closed">%(Closed)s</option>
               <option value="remove me">%(RemoveMe)s</option>''' % { 'ToDo'       : _('to do'),
                                                                     'InProgress' : _('in progress'),
                                                                     'Pending'    : _('pending'),
                                                                     'Done'       : _('done'),
                                                                     'Undone'     : _('failed'),
                                                                     'Closed'     : _('closed'),
                                                                     'RemoveMe'   : _('remove me') }

    if value10 == "closed":
        formhtml8 = '''
               <option value="to do">%(ToDo)s</option>
               <option value="in progress">%(InProgress)s</option>
               <option value="pending">%(Pending)s</option>
               <option value="done">%(Done)s</option>
               <option value="failed">%(Undone)s</option>
               <option selected value="closed">%(Closed)s</option>
               <option value="remove me">%(RemoveMe)s</option>''' % { 'ToDo'       : _('to do'),
                                                                     'InProgress' : _('in progress'),
                                                                     'Pending'    : _('pending'),
                                                                     'Done'       : _('done'),
                                                                     'Undone'     : _('failed'),
                                                                     'Closed'     : _('closed'),
                                                                     'RemoveMe'   : _('remove me') }

    if value10 == "remove me":
        formhtml8 = '''
               <option value="to do">%(ToDo)s</option>
               <option value="in progress">%(InProgress)s</option>
               <option value="pending">%(Pending)s</option>
               <option value="done">%(Done)s</option>
               <option value="failed">%(Undone)s</option>
               <option value="closed">%(Closed)s</option>
               <option selected value="remove me">%(RemoveMe)s</option>''' % { 'ToDo'       : _('to do'),
                                                                              'InProgress' : _('in progress'),
                                                                              'Pending'    : _('pending'),
                                                                              'Done'       : _('done'),
                                                                              'Undone'     : _('failed'),
                                                                              'Closed'     : _('closed'),
                                                                              'RemoveMe'   : _('remove me') }

    formhtml9 = '''
             </select>
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label11)s</label></td>
        <td class="content">
            <input type="text" name="task_desc" value="%(value11)s" size="80" maxlength="100">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label12)s</label></td>
        <td class="content">
            <input type="text" name="task_disc_page" value="%(value12)s" size="80" maxlength="100">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(label13)s</label></td>
        <td class="content">
            <input type="text" name="task_assoc" value="%(value13)s" size="80" maxlength="100">
        </td>
    </tr>
    <tr>
        <td> </td>
        <td>
        <input class="buttons" type="submit" name="button_save_edit" value="%(button1)s">
        <input class="buttons" type="submit" name="button_back_search" value="%(button2)s">
        </td>
    </tr>
</table>
</div>
</form>''' % {
    'label11' : label11,
    'value11' : value11,
    'label12' : label12,
    'value12' : value12,
    'label13' : label13,
    'value13' : value13,
    'button1' : button1,
    'button2' : button2
}
    formhtml = formhtml1 + formhtml2 + formhtml3 + formhtml4 + formhtml5 + formhtml6 + formhtml7 + formhtml8 + formhtml9
    return formhtml


def _save_changed_task(request, page):
    """
        Save changed task data to disc

        @param request: request object
        @param page: page object
        @return: result (string)

    """
    _ = request.getText
    task_id = request.form.get('task_id', [""])[0]
    created_by = request.form.get('created_by', [""])[0]
    created_at = request.form.get('created_at', [""])[0]
    closed_by = request.form.get('closed_by', [""])[0]
    closed_at = request.form.get('closed_at', [""])[0]
    task_name = request.form.get('task_name', [""])[0]
    task_name = wikiutil.escape(task_name, 1)
    task_name = wikiutil.clean_input(task_name)
    assigned_to = request.form.get('assigned_to', [""])[0]
    assigned_to = wikiutil.escape(assigned_to, 1)
    assigned_to = wikiutil.clean_input(assigned_to)
    time_frame = request.form.get('time_frame', [""])[0]
    priority = request.form.get('priority', [""])[0]
    status = request.form.get('status', [""])[0]
    task_desc = request.form.get('task_desc', [""])[0]
    if task_desc != "":
        task_desc = wikiutil.escape(task_desc, 1)
        task_desc = wikiutil.clean_input(task_desc)
    task_disc_page = request.form.get('task_disc_page', [""])[0]
    if task_disc_page != "":
        task_disc_page = wikiutil.escape(task_disc_page, 1)
        task_disc_page = wikiutil.clean_input(task_disc_page)
    task_assoc = request.form.get('task_assoc', [""])[0]
    if task_assoc != "":
        task_assoc = wikiutil.escape(task_assoc, 1)
        task_assoc = wikiutil.clean_input(task_assoc)
        
    databaseFile = os.path.join(request.cfg.data_dir, "task-db")
    try:
        db = open(databaseFile,"r")
        taskdata = db.readlines()
        db.close()  
    except IOError:
        return (_('Error while trying to read task data.'), "error")

    new_taskdata = []    
    for line in taskdata:
        tmp = line.split("\t")
        if tmp[0] == task_id:
            # task closed
            if (status == "closed" or status == "remove me") and (tmp[9] != "closed" or tmp[9] != "remove me"):
                tmp[3] = request.user.name
                tmp[4] = _make_local_timestamp(request)
            # task reopend
            if status in ["to do", "in progress", "pending", "done", "failed"] and (tmp[9] == "closed" or tmp[9] == "remove me"):
                tmp[3] = "unknown"
                tmp[4] = "unknown"
            tmp[5] = task_name
            tmp[6] = assigned_to
            tmp[7] = time_frame
            tmp[8] = priority
            tmp[9] = status
            tmp[10] = task_desc
            tmp[11] = task_disc_page
            tmp[12] = task_assoc
            newline = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (tmp[0],
                                                                                tmp[1],
                                                                                tmp[2],
                                                                                tmp[3],
                                                                                tmp[4],
                                                                                tmp[5],
                                                                                tmp[6],
                                                                                tmp[7],
                                                                                tmp[8],
                                                                                tmp[9],
                                                                                tmp[10],
                                                                                tmp[11],
                                                                                tmp[12])
            new_taskdata += newline
        else:
            new_taskdata += line
            
    try:
        db = open(databaseFile,"w")
        db.writelines(new_taskdata)
        db.close()    
    except IOError:
        return (_('Error while trying to save task data.'),"error")
   
    return (_('Task successfully saved.'),"ok")


def do_removeform(request, actname, msg=None):
    """
        Build the 'remove task' form

        @param request: request object
        @param actname: actname object
        @param msg: message to display
        @return: html form (string)
    """
    _ = request.getText
    ticket = wikiutil.createTicket(request)
    querytext = _('Remove Task')
    button1 = _('Remove')
    button2 = _('Cancel')
    label1 = _('Task ID')
    value1 = ""

    formhtml1 = '''
<form method="post" action="">
<div class="userpref">
<strong>%s <br></strong>''' % querytext
    
    if msg:
        formhtml2 = "%s" % msg
    else:
        formhtml2 = ""

    formhtml3 = '''
<br>
<input type="hidden" name="action" value="%(actname)s">
<input type="hidden" name="ticket" value="%(ticket)s">
<table border="0">
    <tr>
        <td class="label"><label>%(label1)s</label></td>
        <td class="content">
            <input type="text" name="task_id" value="%(value1)s" size="6" maxlength="6">
        </td>
    </tr>
    <tr>
        <td> </td>
        <td>
        <input class="buttons" type="submit" name="button_remove_id" value="%(button1)s">
        <input class="buttons" type="submit" name="button_back" value="%(button2)s">
        </td>
    </tr>
</table>
</div>
</form>''' % {
    'actname': actname,
    'ticket' : ticket,
    'label1' : label1,
    'value1' : value1,
    'button1': button1,
    'button2': button2
}
    formhtml = formhtml1 + formhtml2 + formhtml3
    return formhtml


def _remove_task(request, task_to_remove=None):
    """
        Remove task from database

        @param request: request object
        @param task_to_remove: id of task to remove
        @return: tuple result, message (bool, string)
    """
    _ = request.getText
    if task_to_remove == None:
        task_id = request.form['task_id'][0]
    else:
        task_id = task_to_remove
    databaseFile = os.path.join(request.cfg.data_dir, "task-db")
    if os.path.isfile(databaseFile):
        try:
            db = open(databaseFile, "r")
            database = db.readlines()
            db.close()
        except:
            return (False, (_('Error while trying to remove task from database.'), "error"))
        found = False
        task_homepage = ""
        new_database = []
        for line in database:
            tmp = line.split("\t")
            if tmp[0] == task_id:
                found = True
                task_homepage = tmp[11]
            else:
                new_database += line

        if found == True:
            try:
                db = open(databaseFile, "w")
                db.writelines(new_database)
                db.close()
            except:
                return (False, (_('Error while trying to remove task from database.'), "error"))
            if Page(request, task_homepage).exists():
                if request.user.may.delete(task_homepage):
                    page = PageEditor(request, task_homepage, do_editor_backup=0)
                    success, msg = page.deletePage()
                    if success:
                        return (True, (_("Task and task's wiki homepage successfully removed."),"ok"))
                    else:
                        return (True, (_("Task successfully removed from database. Error while trying to delete task's wiki homepage."),"warning"))
                else:
                    return (True, (_("Task successfully removed from database. Error while trying to delete task's wiki homepage: You are not allowed to delete this page."),"warning"))
            return (True, (_('Task successfully removed.'),"ok"))
        else:
            return (False, (_('Task not found.'),"error"))
    else:
        return (False, (_('Database not found.'),"error"))
    

def execute(pagename, request):
    _ = request.getText
    actname = __name__.split('.')[-1]
    page = Page(request, pagename)

    # check whether user is logged in
    if request.user.valid == 0:
#        return page.send_page(msg=_('Please log in first.'))
	request.theme.add_msg(_('Please log in first.'),'error')
        return page.send_page()
    
    # ckeck whether action is allowed
    if actname in request.cfg.actions_excluded:
#        return page.send_page(msg=_('You are not allowed to perform this action.'))
	request.theme.add_msg(_('You are not allowed to perform this action.'),"warning")
        return page.send_page()

    # check whether page does really exist
    if not page.exists():
#        return page.send_page(msg=_('This page is already deleted or was never created!'))
	request.theme.add_msg(_('This page is already deleted or was never created!'),"error")
        return page.send_page()

    #
    # 'add task' called from outside by the macro via "?action=TaskPlanner&add" (currently not used)
    #
    if request.form.has_key('action') and request.form.has_key('add'):
        # check whether this is a valid request (make outside
        # attacks harder by requiring two full HTTP transactions)
        if not request.form.has_key('ticket'):
#            return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
#	    msg=_('Please use the interactive user interface for adding, editing and removing tasks.')
	    request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	    return page.send_page()

        if not wikiutil.checkTicket(request, request.form['ticket'][0]):
#            return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
	    request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	    return page.send_page()
        
        if request.form.has_key('button_back'):
            return page.send_page()

        # check whether TaskTable macro has forwarded information on page and assign
        assoc_page = assign = None
        if request.form.has_key('page'):
            assoc_page = request.form.get('page', [None])[0]
        if request.form.has_key('assign'):
            assign = request.form.get('assign', [None])[0]

        if request.form.has_key('button_add_a'):
            result = _check_form_input(request)
            if result =="":
                result = _save_task(request)
 #               return page.send_page(msg=result)        
		request.theme.add_msg(*result)
		return page.send_page()
            else:  
#                return page.send_page(msg=do_addform(request, actname, page, msg=result, assoc_page=assoc_page, assign=assign))
		request.theme.add_msg(_(do_addform(request, actname, page, msg=result[0], assoc_page=assoc_page, assign=assign)),result[1])
		return page.send_page()

#        return page.send_page(msg=do_addform(request, actname, page, assoc_page=assoc_page, assign=assign))
	request.theme.add_msg(_(do_addform(request, actname, page, assoc_page=assoc_page, assign=assign)))
	return page.send_page()

    #
    # 'edit task' called from outside by the macro via "?action=TaskPlanner&edit=[task_id]"
    #
    elif request.form.has_key('action') and request.form.has_key('edit'):
        # check whether this is a valid request (make outside
        # attacks harder by requiring two full HTTP transactions)
        if not request.form.has_key('ticket'):
#            return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
	    request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	    return page.send_page()

        if not wikiutil.checkTicket(request, request.form['ticket'][0]):
#            return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
	    request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	    return page.send_page()
        
        if request.form.has_key('button_back_search'):
            return page.send_page()

        task_id = request.form.get('edit', [""])[0]
        databaseFile = os.path.join(request.cfg.data_dir, "task-db")
        if os.path.isfile(databaseFile):
            existing_id = 0
            found = False
            for line in open(databaseFile).readlines():
                tmp = line.split("\t")
                existing_id = tmp[0]
                if existing_id == task_id:
                    found = True
                    break
        else:
#            return page.send_page(msg=_('/!\\ Database not found. '))
	    request.theme.add_msg(_('Database not found. '),"error")
	    return page.send_page()

        if request.form.has_key('button_save_edit'):
            result = _check_form_input(request)
            if result =="":
                result = _save_changed_task(request, page)
#                return page.send_page(msg=result)
		request.theme.add_msg(*result)
		return page.send_page()
            else:
#                return page.send_page(msg=do_editform(request, actname, page, tmp, msg=result))
		request.theme.add_msg(do_editform(request, actname, page, tmp, msg=result[0]))
		return page.send_page()

        if found == True:
#            return page.send_page(msg=do_editform(request, actname, page, tmp))
	    request.theme.add_msg(_(do_editform(request, actname, page, tmp)))
	    return page.send_page()

        else:
	    #return page.send_page(msg=_('/!\\ Task not found. '))
	    request.theme.add_msg(_('Task not found. '),"error")
	    return page.send_page()

    #
    # 'remove task' called from outside by the macro via "?action=TaskPlanner&remove=[task_id]"
    #
    elif request.form.has_key('action') and request.form.has_key('remove'):
        # check whether this is a valid request (make outside
        # attacks harder by requiring two full HTTP transactions)
        if not request.form.has_key('ticket'):
            #return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
	    request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	    return page.send_page()

        if not wikiutil.checkTicket(request, request.form['ticket'][0]):
           #return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
	   request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	   return page.send_page()

        if not request.user.isSuperUser():
            # return page.send_page(msg=_('You have to be superuser to remove items from the task list database.'))
	    request.theme.add_msg(_('You have to be superuser to remove items from the task list database.'),"warning")
	    return page.send_page()
        
        task_id = request.form.get('remove', [""])[0]
        success, msg = _remove_task(request, task_id)
        # return page.send_page(msg=msg)
	request.theme.add_msg(*msg)
	return page.send_page()

    #
    # Event handling for TaskPlanner user interface
    #
    elif request.form.has_key('action') and request.form.has_key('ticket'):
        # check whether ticket is valid (make outside attacks harder
        # by requiring two full HTTP transactions)
        if not request.form.has_key('ticket'):
            #return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
	    request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	    return page.send_page()

        if not wikiutil.checkTicket(request, request.form['ticket'][0]):
            # return page.send_page(msg=_('Please use the interactive user interface for adding, editing and removing tasks.'))
	    request.theme.add_msg(_('Please use the interactive user interface for adding, editing and removing tasks.'),"warning")
	    return page.send_page()
        #
        # 'add task' stuff
        #
        
        # check whether TaskTable macro has forwarded information on page and assign
        assoc_page = assign = None
        if request.form.has_key('page'):
            assoc_page = request.form.get('page', [None])[0]
        if request.form.has_key('assign'):
            assign = request.form.get('assign', [None])[0]

        # display menu for adding tasks
        if request.form.has_key('button_add'):
            #return page.send_page(msg=do_addform(request, actname, page, assoc_page=assoc_page, assign=assign))
    	    request.theme.add_msg(do_addform(request, actname, page, assoc_page=assoc_page, assign=assign))
	    return page.send_page()

        # user pressed button 'add task'
        if request.form.has_key('button_add_a'):
            result = _check_form_input(request)
            if result != "":
                #return page.send_page(msg=do_addform(request, actname, page, msg=result, assoc_page=assoc_page, assign=assign))
		request.theme.add_msg(_(do_addform(request, actname, page, msg=result[0], assoc_page=assoc_page, assign=assign)),result[1])
		return page.send_page()
            else:
                result = _save_task(request)
                # return page.send_page(msg=do_mainform(request, actname, msg=result))
		request.theme.add_msg(_(do_mainform(request, actname, msg=result[0])),result[1])
		return page.send_page()

        #
        # 'edit task' stuff
        #

        # display menu for searching task to edit
        if request.form.has_key('button_edit'):
            # return page.send_page(msg=do_edit_search_form(request, actname))
	    request.theme.add_msg(_(do_edit_search_form(request, actname)))
	    return page.send_page()

        # user pressed button 'edit task' in the search task form
        if request.form.has_key('button_search_id'):
            task_id = request.form['task_id'][0]
            databaseFile = os.path.join(request.cfg.data_dir, "task-db")
            if os.path.isfile(databaseFile):
                existing_id = 0
                found = False
                for line in open(databaseFile).readlines():
                    tmp = line.split("\t")
                    existing_id = tmp[0]
                    if existing_id == task_id:
                        found = True
                        break
            else:
                # return page.send_page(msg=do_edit_search_form(request, actname, msg=_('/!\\ Database not found. '))) 
		request.theme.add_msg(_('Database not found. '),"error")
		return page.send_page()

            if found == True:
                # return page.send_page(msg=do_editform(request, actname, page, tmp))
		request.theme.add_msg(do_editform(request, actname, page, tmp))
		return page.send_page()
            else:
                # return page.send_page(msg=do_edit_search_form(request, actname, msg=_('/!\\ Task not found. ')))
		request.theme.add_msg(_('Task not found. '),"warning")
		return page.send_page()

        # user pressed button 'save edited' task
        if request.form.has_key('button_save_edit'):
            result = _check_form_input(request)
            # if we have invalid input, reload task data and display edit form again
            if result != "":
                task_id = request.form['task_id'][0]
                databaseFile = os.path.join(request.cfg.data_dir, "task-db")
                if os.path.isfile(databaseFile):
                    existing_id = 0
                    found = False
                    for line in open(databaseFile).readlines():
                        tmp = line.split("\t")
                        existing_id = tmp[0]
                        if existing_id == task_id:
                            found = True
                            break
                else:
                    #return page.send_page(msg=do_edit_search_form(request, actname, msg=_('/!\\ Database not found. '))) 
		    request.theme.add_msg(_('Database not found. '),"error")
		    return page.send_page()
                # return page.send_page(msg=do_editform(request, actname, page, tmp, msg=result))
		request.theme.add_msg(do_editform(request, actname, page, tmp, msg=result[0]),result[1])
		return page.send_page()

            else:
                result = _save_changed_task(request, page)
                # return page.send_page(msg=do_mainform(request, actname, msg=result))
		request.theme.add_msg(do_mainform(request, actname, msg=result[0]),result[1])
		return page.send_page()
            
        # user pressed button cancel editing task
        if request.form.has_key('button_back_search'):
            # return page.send_page(msg=do_mainform(request, actname))
	    request.theme.add_msg(do_mainform(request, actname))
	    return page.send_page()
            
        #
        # 'remove task' stuff
        #

        # display menu for removing tasks
        if request.form.has_key('button_remove'):
            if not request.user.isSuperUser():
                # return page.send_page(msg=do_mainform(request, actname, msg=_('You have to be superuser to remove items from the task list database.')))
		request.theme.add_msg(do_mainform(request, actname, msg=_('You have to be superuser to remove items from the task list database.')),"warning")
		return page.send_page()
            # return page.send_page(msg=do_removeform(request, actname))
	    request.theme.add_msg(do_removeform(request, actname))
	    return page.send_page()
	    
	    

        # user pressed button 'remove task'
        if request.form.has_key('button_remove_id'):
            if not request.user.isSuperUser():
                # return page.send_page(msg=do_mainform(request, actname, msg= _('You have to be superuser to remove items from the task list database.')))
		request.theme.add_msg(do_mainform(request, actname, msg= _('You have to be superuser to remove items from the task list database.')),"warning")
		return page.send_page()
            
            success, msg = _remove_task(request)
            if success:
                # return page.send_page(msg=do_mainform(request, actname, msg=msg))
		request.theme.add_msg(do_mainform(request, actname, msg=msg[0]),msg[1])
		return page.send_page()
            else:
                #return page.send_page(msg=do_removeform(request, actname, msg=msg))
		request.theme.add_msg(do_removeform(request, actname, msg=msg[0]),msg[1])
		return page.send_page()

        # user pressed button 'cancel' in the main form
        if request.form.has_key('button_cancel'):
            return page.send_page()                

    # either no button was pressed (i.e. just display TaskPlanner user interface after calling the action
    # or 'button_back' was pressed (then show main form again)
    # return page.send_page(msg=do_mainform(request, actname))
    request.theme.add_msg(do_mainform(request, actname))
    return page.send_page()    


