#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2009-2012 Zuza Software Foundation
#
# This file is part of Pootle.
#
# 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, see <http://www.gnu.org/licenses/>.

from django.forms.util import ValidationError
from django.utils.safestring import mark_safe


class FormError(ValidationError):
    pass
class SubmitError(FormError):
    pass
class HandlerError(FormError):
    pass


class View(object):

    def find_post_handler_action(self, request):
        action_names = [action_name for action_name in self.handlers \
                        if action_name in set(request.POST)]

        if len(action_names) == 1:
            return action_names[0]
        else:
            raise SubmitError('Only one submit action may be handled per POST')


    def find_handlers(self, forms):

        handlers = {}

        for form in forms.itervalues():
            for action_name, _action_label in form.actions:

                if action_name not in handlers:
                    handlers[action_name] = form
                else:
                    raise HandlerError('More than one form defines the handler %s' % action_name)

        return handlers


    def __init__(self, forms):
        self.handlers = self.find_handlers(forms)
        self.forms = forms


    def __call__(self, request, *args, **kwargs):

        template_vars = {}

        for form_name, form_class in self.forms.iteritems():

            if form_class.must_display(request, *args, **kwargs):
                template_vars[form_name] = form_class(request)
            else:
                template_vars[form_name] = None

        if request.method == 'POST':
            action = self.find_post_handler_action(request)
            form = self.handlers[action](request, data=request.POST,
                                         files=request.FILES)
            template_vars.update(form.dispatch(action, request,
                                               *args, **kwargs))

        return self.GET(template_vars, request, *args, **kwargs)

    def GET(self, template_vars, request, *args, **kwargs):
        raise NotImplementedError()


class Handler(object):

    Form = None  # This should be implemented as an inner class

    actions = []  # This should be all


    @classmethod
    def must_display(cls, request, *args, **kwargs):
        return True


    def __init__(self, request, data=None, files=None):
        self.form = self.Form(data=data, files=files)


    def dispatch(self, action, request, *args, **kwargs):
        handler = getattr(self, action)
        return handler(request, *args, **kwargs)


    def render_submits(self):

        output = u""

        for action in self.actions:
            output += u'<input type="submit" name="%(action_name)s" ' \
                      u'value="%(action_value)s" />' % \
                      {'action_name': action[0],
                       'action_value': unicode(action[1])}

        return mark_safe(output)


    def as_p(self):
        return mark_safe("""
        %(inner_form)s
        <p class="buttons">%(submits)s</p>""" % {
            'inner_form': self.form.as_p(),
            'submits': self.render_submits(),
            })
