# -*- coding: utf-8 -*-
"""
Trac WebAdmin plugin for administration of custom fields.

License: BSD

(c) 2005-2012 ::: www.CodeResort.com - BV Network AS (simon-code@bvnetwork.no)
(c) 2007-2009 ::: www.Optaros.com (.....)
"""
from pkg_resources import get_distribution, parse_version, resource_filename

from trac.admin.api import IAdminPanelProvider
from trac.config import Option
from trac.core import *
from trac.web.chrome import (
    Chrome, ITemplateProvider, add_script, add_script_data, add_warning)

from customfieldadmin.api import CustomFields, _


class CustomFieldAdminPage(Component):

    implements(ITemplateProvider, IAdminPanelProvider)

    def __init__(self):
        CustomFields(self.env)  # load our message catalog

    # IAdminPanelProvider methods

    def get_admin_panels(self, req):
        if 'TICKET_ADMIN' in req.perm('admin', 'ticket/customfields'):
            yield ('ticket', _("Ticket System"),
                   'customfields', _("Custom Fields"))

    def render_admin_panel(self, req, cat, page, customfield):
        req.perm('admin', 'ticket/customfields').require('TICKET_ADMIN')

        cf_api = CustomFields(self.env)
        add_script_data(req, field_formats=cf_api.field_formats)
        add_script(req, 'customfieldadmin/js/customfieldadmin.js')

        def _customfield_from_req(self, req):
            cfield = {
                'name': req.args.get('name',''),
                'label': req.args.get('label',''),
                'type': req.args.get('type',''),
                'value': req.args.get('value',''),
                'options': [x.strip().encode('utf-8') for x in \
                            req.args.get('options','').split("\n")],
                'cols': req.args.get('cols',''),
                'rows': req.args.get('rows',''),
                'order': req.args.get('order', ''),
                'format': req.args.get('format', '')
            }
            return cfield

        cf_admin = {'field_types': cf_api.field_types}


        # Detail view?
        if customfield:
            cfield = None
            for a_cfield in cf_api.get_custom_fields():
                if a_cfield['name'] == customfield:
                    cfield = a_cfield
                    break
            if not cfield:
                raise TracError(_("Custom field %(name)s does not exist.",
                                  name=customfield))
            if req.method == 'POST':
                if req.args.get('save'):
                    cfield.update(_customfield_from_req(self, req))
                    cf_api.update_custom_field(cfield)
                    req.redirect(req.href.admin(cat, page))
                elif req.args.get('cancel'):
                    req.redirect(req.href.admin(cat, page))
            if 'options' in cfield:
                optional_line = ''
                if cfield.get('optional', False):
                    optional_line = "\n\n"
                cfield['options'] = \
                        optional_line + "\n".join(cfield['options'])
            cf_admin['cfield'] = cfield
            cf_admin['cf_display'] = 'detail'
        else:
            if req.method == 'POST':
                # Add Custom Field
                if req.args.get('add') and req.args.get('name'):
                    cfield = _customfield_from_req(self, req)
                    cf_api.update_custom_field(cfield, create=True)
                    req.redirect(req.href.admin(cat, page))

                # Remove Custom Field
                elif req.args.get('remove') and req.args.get('sel'):
                    sel = req.args.get('sel')
                    sel = isinstance(sel, list) and sel or [sel]
                    if not sel:
                        raise TracError(_("No custom field selected"))
                    for name in sel:
                        cfield =  {'name': name}
                        cf_api.delete_custom_field(cfield)
                    req.redirect(req.href.admin(cat, page))

                elif req.args.get('apply'):
                    # Change order
                    order = dict([(key[6:], req.args.get(key)) for key
                                  in req.args.keys()
                                  if key.startswith('order_')])
                    cfields = cf_api.get_custom_fields()
                    for current_cfield in cfields:
                        new_order = order.get(current_cfield['name'], 0)
                        if new_order:
                            current_cfield['order'] = new_order
                            cf_api.update_custom_field(current_cfield)
                    req.redirect(req.href.admin(cat, page))

            cfields = []
            orders_in_use = []
            for item in cf_api.get_custom_fields():
                item['href'] = req.href.admin(cat, page, item['name'])
                item['registry'] = ('ticket-custom',
                                            item['name']) in Option.registry
                cfields.append(item)
                orders_in_use.append(int(item.get('order')))
            cf_admin['cfields'] = cfields
            cf_admin['cf_display'] = 'list'
            if sorted(orders_in_use) != range(1, len(cfields)+1):
                add_warning(req, _("Custom Fields are not correctly sorted. " \
                         "This may affect appearance when viewing tickets."))

        if hasattr(Chrome(self.env), 'jenv'):
            cf_admin['domain'] = 'customfieldadmin'
            return 'customfieldadmin_jinja.html', cf_admin
        else:
            return 'customfieldadmin_genshi.html', cf_admin

    # ITemplateProvider methods

    def get_templates_dirs(self):
        return [resource_filename(__name__, 'templates')]

    def get_htdocs_dirs(self):
        return [('customfieldadmin', resource_filename(__name__, 'htdocs'))]
