"""
    MoinMoin - AttachTable Macro
    Author: Erick Martin

    A macro to produce a table of attached pages, leveraged from the attach file action, and AttachList macro.

    Usage:
       [[AttachTable]]
       [[AttachTable(page=FrontPage,syntax=0)]]
       [[AttachTable(readonly=1,closed=1,syntax=1]]

    args:
       @page=string display the attachemnt table for a differnet page 
       @syntax=1 display the attachemt syntax in the table
       @closed=0 display the table in a closed/open state overrideing the defualt cfg value attach_table_compact
       @readonly=0 force the display the table in a readonly mode remove the delete option

    @copyright: 2006 Erick Martin
    @copyright: 2004 Jacob Cohen, Nigel Metheringham
    @license: GNU GPL, see COPYING for details.
"""

import os, urllib, time
from MoinMoin import config, wikiutil
from MoinMoin.action.AttachFile import getAttachDir, getAttachUrl

def _get_files(base_dir):
    if os.path.isdir(base_dir):
        files = map(lambda a: a.decode(config.charset), os.listdir(base_dir))
        files.sort()
        return files
    return []

def _get_fileid( base_dir ):

    file_id = 1000

    if os.path.isdir( base_dir ) and os.name == 'posix':
        inode = os.stat(base_dir.encode(config.charset))[1]
        dev = os.stat(base_dir.encode(config.charset))[2]
        file_id = "%(dev)d%(inode)d" % { 'inode' : inode, 'dev' : dev }
    else:
        file_id = 0
        for i in range(len(base_dir)):
           file_id = file_id + ord(base_dir[i])

    return file_id

def _table_row( d ):
    str = ( '   <tr style="display:">\n'
            '      <td>\n'
            '        %(data_1)s\n'
            '        <p>\n'
            '        %(data_2)s\n'
            '      </td>\n'
            '      <td> %(data_3)s </td>\n'
            '      <td> %(data_4)s </td>\n'
            '      <td> %(data_5)s </td>\n'
            '   </tr>\n' ) % d
    return str

def file_table( request, base_dir, pagename, display_table_closed = 0, display_attach_syntax = 1, readonly = 0):

    _ = request.getText

    files = _get_files(base_dir)

    action = 'AttachFile'

    page_url = wikiutil.quoteWikinameURL(pagename)

    # wikiutil.link_tag does not support title so we do it long hand
    manage_url = '<a href="%(baseurl)s/%(page_url)s?action=%(action)s" title="%(title)s" >%(text)s</a>' % {
        'baseurl' : request.getScriptname(),
        'page_url' : page_url,
        'action' : action,
        'text' : _('Add/Manage'),
        'title' : _('Add/Manage uploaded files'),
    }

    if not files:
        return '<br>\n%(icon)s %(manage_url)s files for the <strong>%(pagename)s</strong> page\n' % {
                   'icon' : request.theme.make_icon('table-null'),
                   'pagename' : pagename,
                   'manage_url' : manage_url, }

    label_del = _("delete")
    label_get = _("download")
    label_edit = _("edit")
    label_view = _("view")

    table_closed_file_name = 'table-open'
    table_open_file_name = 'table-close'

    open_image = request.theme.img_url( table_open_file_name )
    closed_image = request.theme.img_url( table_closed_file_name )

    java_function = """
// Toggle display of a folder's contents.
function showHideContents ( idnum ) {
   the_table = document.getElementById( 't' + idnum );

   arrowObj  = document.getElementById( 'a' + idnum );
   // we use the image to determine if the table is open or closed
   if (arrowObj.src.indexOf('%(table_open_file_name)s') > -1) {
      arrowObj.src = '%(closed_image)s';
      display      = 'none';
   } else {
      arrowObj.src = '%(open_image)s';
      display      = '';
   }

   // change the open/closed state of the rows for the table
   for (var i = 0; i < the_table.rows.length; i++) {
      the_table.rows[i].style.display = display;
   }
}
""" % { 'closed_image' : closed_image,
        'open_image' : open_image,
        'table_open_file_name' : table_open_file_name, }

    str = ( "\n"
            '<script type="text/javascript">' "\n"
            "<!--\n"
            "%(java_function)s\n"
            "--> </script>\n"
            "\n" ) % { 'java_function' : java_function, }


    file_id = _get_fileid( base_dir )

    str = str + '\n<div class="attachmentTable" >\n'

    table_caption = ( '<a onClick="showHideContents(%(file_id)s);" title="Click to open/close">'
                  '<img id="a%(file_id)s" align="middle" border=0 src="%(open_image)s"'
                  'alt=""></a>\n'
                  ' %(manage_url)s to the %(num_files)s file(s) attached to the <strong>%(pagename)s</strong> page' ) % {
                     'file_id' :  file_id,
                     'open_image' : open_image,
                     'num_files' :  len(files),
                     'pagename' : pagename,
                     'manage_url' : manage_url, }

    str = str + ( '<br>\n'
                  '%(table_caption)s\n'
                  '<table id="t%(file_id)s" >\n'
                  '   <tr style="display:">\n'
                  '     <th>Name<p>Wiki Include Syntax</th>\n'
                  '     <th>Size</th>\n'
                  '     <th>Date</th>\n'
                  '     <th>Action</th>\n'
                  '   </tr>\n') % {
                     'file_id' :  file_id,
                     'table_caption' :  table_caption, }

    # the user cant delete so force readonly mode
    if not request.user.may.delete(pagename):
        readonly = 1

    for file in files:
        fsize = float(os.stat(os.path.join(base_dir,file).encode(config.charset))[6]) # in byte
        mtime = os.stat(os.path.join(base_dir,file).encode(config.charset))[8]
        fsize = "%.1f" % (fsize / 1024)
        fdate = time.ctime(mtime)
        urlfile = urllib.quote_plus(file.encode(config.charset))

        base, ext = os.path.splitext(file)
        get_url = getAttachUrl(pagename, file, request, escaped=1)
        parmdict = { 'page_url': page_url, 'action': action,
                    'urlfile': urlfile, 'label_del': label_del,
                    'base': base, 'label_edit': label_edit,
                    'label_view': label_view,
                    'get_url': get_url, 'label_get': label_get,
                    'file': file, 'fsize': fsize,
                    'pagename': pagename}

        del_link = ''
        if not readonly:
            action_args = 'do=del&amp;target=%(urlfile)s' % { 
               'urlfile' : urlfile,
            }
            url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
               'page_url' : page_url,
               'action' : action,
               'action_args' : action_args,
            }
            del_link = wikiutil.link_tag(request, url, text=label_del,
                                         formatter=request.formatter)


        if ext == '.draw':
            action_args = 'drawing=%(base)s' % { 
               'base' : base,
            }
            url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
               'page_url' : page_url,
               'action' : action,
               'action_args' : action_args,
            }
            viewlink = wikiutil.link_tag(request, url, text=label_edit,
                                         formatter=request.formatter)
        else:
            action_args = 'do=view&amp;target=%(urlfile)s' % { 
               'urlfile' : urlfile,
            }
            url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
               'page_url' : page_url,
               'action' : action,
               'action_args' : action_args,
            }
            viewlink = wikiutil.link_tag(request, url, text=label_view,
                                         formatter=request.formatter)


        image = ""
        if ext in request.theme.icons:
            image = request.theme.make_icon( ext )
        else:
            image = request.theme.make_icon( 'unknown' )


        parmdict['image'] = image
        parmdict['viewlink'] = viewlink
        parmdict['del_link'] = del_link

        parmdict['open_image'] = open_image
        
        action_args = 'do=get&amp;target=%(urlfile)s' % { 
           'urlfile' : urlfile,
        }
        url = '%(page_url)s?action=%(action)s&amp;%(action_args)s' % {
           'page_url' : page_url,
           'action' : action,
           'action_args' : action_args,
        }
        text = ' %(image)s %(file)s ' % { 'image' : image, 'file' : file }
        getlink = wikiutil.link_tag(request, url, text=text,
                                    formatter=request.formatter)

        parmdict['getlink'] = getlink

        depth = len(file.split(os.path.sep)) - 1
        indent_txt = "<div class=indent%d>\n         " % depth

        if not os.path.isdir(os.path.join(base_dir,file).encode(config.charset)):
            data_5 = ( '\n'
                      '         %(viewlink)s\n'
                      '         <a href="%(get_url)s"> %(label_get)s </a>\n'
                      '         %(del_link)s\n     ' ) % parmdict
            data_2 = '&nbsp;'
            if display_attach_syntax:
                if pagename == request.formatter.page.page_name:
                    data_2 = 'attachment:%(file)s' % { 'file' : wikiutil.url_quote(file) }
                else:
                    data_2 = 'attachment:%(pagename)s/%(file)s' % { 
                       'file' : wikiutil.url_quote(file),
                       'pagename' : pagename }

            str = str + _table_row( { 
                                      'data_1' : indent_txt + '<strong>%(getlink)s</strong>' % parmdict,
                                      'data_2' : data_2,
                                      'data_3' : '%(fsize)s&nbsp;KB' % parmdict,
                                      'data_4' : '%(fdate)s' % { 'fdate' : fdate },
                                      'data_5' : data_5,
                                    } )

    str = str + '\n</table>\n</div>\n'

    if display_table_closed:
        close_str = ( '\n<script type="text/javascript">\n'
                      '<!--\nshowHideContents(%(file_id)s);\n-->\n'
                      '</script>\n' ) % { 'file_id' :  file_id, }
        str = str + close_str


    return str

def getArgs(string, arguments):
    """
    @param string: string from the wiki markup [[NewPage(string)]]
    @rtype: dict
    @return: dictionary with macro options
    """
    if not string:
        return {}
    args = {}
    for s in string.split(','):
        if s and s.find('=') > 0:
            key, value = s.split('=', 1)
            if key and value:
                args[str(key.strip())] = value.strip()
    return args


def execute(macro, options):
    """
    """

    arguments = ['page', 'syntax', 'closed', 'readonly']

    args = getArgs( options, arguments )

    pagename = args.get('page', macro.formatter.page.page_name)

    default_attach_syntax = 1
    if not pagename == macro.formatter.page.page_name:
        default_attach_syntax = 0

    # access directory
    attach_dir = getAttachDir(macro.request, pagename)

    default_table_closed = 0
    if hasattr(macro.request.cfg, 'attach_table_compact'):
        default_table_closed = macro.request.cfg.attach_table_compact

    display_attach_syntax = int(args.get('syntax', default_attach_syntax))
    table_closed = int(args.get('closed', default_table_closed))
    table_readonly = int(args.get('readonly', 0))

    return file_table( macro.request, attach_dir, pagename,
                       table_closed, display_attach_syntax, table_readonly )

