##############################################################################
#
# Copyright (c) 2007 Projekt01 GmbH and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: __init__.py 6 2006-04-16 01:28:45Z roger.ineichen $
"""
from __future__ import absolute_import
__docformat__ = "reStructuredText"
from zope.interface import implementer

import zope.interface

from z3c.template.template import getLayoutTemplate
from z3c.template.template import getPageTemplate

from j01.jsonrpc import btn
from j01.jsonrpc import jsform
from j01.dialog import interfaces
from j01.dialog.btn import IDialogButtons


@implementer(interfaces.IDialogForm)
class DialogForm(jsform.JSONRPCForm):
    """Dialog JSONRPC form."""


    layout = getLayoutTemplate(name='dialog')
    template = getPageTemplate()

    buttons = btn.Buttons()

    prefix = 'dialog'

    j01DialogTitle = None
    closeDialog = False
    nextURL = None
    contentTargetExpression = None

    def setNextURL(self, url, status, closeDialog=True):
        """Helper for set a nextURL including status message and closeDialog"""
        self.closeDialog = closeDialog
        super(DialogForm, self).setNextURL(url, status)

    def renderClose(self):
        """Return content if you need to render content after close."""
        return None

    def render(self):
        # knows what to return for the dialog parent
        if self.closeDialog:
            return self.renderClose()
        return self.template()


@implementer(interfaces.IDialogEditForm)
class DialogEditForm(DialogForm, jsform.JSONRPCEditForm):
    """Dialog JSONRPC edit form."""


    buttons = btn.Buttons()

    closeOnApplyWithoutError = True

    def doHandleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        changes = self.applyChanges(data)
        if changes:
            self.status = self.successMessage
            # close on apply without error
            if self.closeOnApplyWithoutError:
                self.closeDialog = True
        else:
            self.status = self.noChangesMessage
            # close on apply without error
            if self.closeOnApplyWithoutError:
                self.closeDialog = True
        return changes

    def doHandleCancel(self, action):
        self.closeDialog = True

    @btn.buttonAndHandler(IDialogButtons['applyChanges'])
    def handleApply(self, action):
        self.doHandleApply(action)

    @btn.buttonAndHandler(IDialogButtons['cancel'])
    def handleCancel(self, action):
        self.doHandleCancel(action)


@implementer(interfaces.IDialogAddForm)
class DialogAddForm(DialogForm, jsform.JSONRPCAddForm):
    """Dialog JSONRPC edit form."""


    buttons = btn.Buttons()

    def doHandleAdd(self, action):
        # Note we, use the data from the request.form
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        obj = self.createAndAdd(data)
        if obj is not None:
            # mark only as finished if we get the new object
            self._finishedAdd = True
            self.closeDialog = True
        return obj

    def doHandleCancel(self, action):
        self.closeDialog = True

    @btn.buttonAndHandler(IDialogButtons['add'])
    def handleAdd(self, action):
        self.doHandleAdd(action)

    @btn.buttonAndHandler(IDialogButtons['cancel'])
    def handleCancel(self, action):
        self.doHandleCancel(action)


@implementer(interfaces.IDialogDeleteForm)
class DialogDeleteForm(DialogForm):
    """Dialog JSONRPC delete form."""


    buttons = btn.Buttons()

    ignoreContext = True

    def doHandleDelete(self, action):
        raise NotImplementedError(
            'Subclass must implement doHandleDelete')

    def doHandleCancel(self, action):
        self.closeDialog = True

    @btn.buttonAndHandler(IDialogButtons['delete'])
    def handleDelete(self, action):
        self.doHandleDelete(action)

    @btn.buttonAndHandler(IDialogButtons['cancel'])
    def handleCancel(self, action):
        self.doHandleCancel(action)


@implementer(interfaces.IDialogConfirmForm)
class DialogConfirmForm(DialogForm):
    """Dialog JSONRPC confirm form."""


    buttons = btn.Buttons()

    ignoreContext = True

    def doHandleConfirm(self, action):
        raise NotImplementedError('Subclass must implement doHandleConfirm')

    def doHandleCancel(self, action):
        self.closeDialog = True

    @btn.buttonAndHandler(IDialogButtons['confirm'])
    def handleConfirm(self, action):
        self.doHandleConfirm(action)

    @btn.buttonAndHandler(IDialogButtons['cancel'])
    def handleCancel(self, action):
        self.doHandleCancel(action)
