# -*- coding: UTF-8 -*-


# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
#     Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


"""Page Sequences (aka Slideshows) Module"""


import elements
import environs
import html
import locations
import logs
import namespaces
import stations
import things


class PageSequence(things.Thing):
    def fillPageLayout(self, layout):
        dataHolder = self.getDataHolder()
        action = environs.getVar("pageName")
        if action in (None, "view") or action.isdigit():
            if action is not None and action.isdigit():
                pageNumber = int(action)
            else:
                pageNumber = 1
            pageNodes = self.evaluateXpath("yep:pages/*[%d]" % pageNumber)
            if not pageNodes:
                logs.error("Page number %d doesn't exist in %s" % (
                    pageNumber, dataHolder.getAbsolutePath()))
                return False
            pageNode = pageNodes[0]
            pageLocation = self.evaluateXpath("@src", pageNode)[0].content
            pageHolder = self.walkToLocation(pageLocation)
            page = pageHolder.getRootElement()
            environs.push(_level = "PageSequence.fillPageLayout",
                          currentStation = page)
            try:
                inForm = page.layoutRequiresForm()
            finally:
                environs.pull(_level = "PageSequence.fillPageLayout")

            if inForm:
                pageLayout = html.form(
                    action = locations.cleanUpUrl(dataHolder.getHttpPostUri(), "sessionToken"),
                    enctype = "multipart/form-data", method = "post")
                layout.append(pageLayout)
                if not environs.getVar("canUseCookie") \
                       or environs.getVar("testCookieSupport"):
                    session = environs.getVar("session")
                    if session is not None and session.publishToken:
                        pageLayout.append(html.input(
                            name = "sessionToken", type = "hidden",
                            value = session.token))
                pageLayout.append(html.input(
                    name = "pageNumber", type = "hidden",
                    value = str(pageNumber)))
            else:
                pageLayout = layout

            environs.push(_level = "PageSequence.fillPageLayout",
                          currentStation = page)
            try:
                page.fillPageBodyLayout(pageLayout, inForm = inForm)
            finally:
                environs.pull(_level = "PageSequence.fillPageLayout")

            # Layout page buttons bar.
            buttonsBarLayout = html.div(class_ = "buttons-bar")
            actionButtonsBarLayout = html.span(class_ = "action-buttons-bar")
            buttonsBarLayout.append(actionButtonsBarLayout)
            buttonsBarFilled = False
            if pageNumber > 1:
                previousPageNodes = self.evaluateXpath("yep:pages/*[%d]" % (pageNumber - 1))
                if previousPageNodes:
                    previousPageNode = previousPageNodes[0]
                    if previousPageNode.name not in ("login", "logout"):
                        labelNodes = self.evaluateXpath("yep:previous/yep:label", pageNode)
                        if labelNodes:
                            label = labelNodes[0].content
                        else:
                            label = _("Previous")
                        if inForm:
                            previousButtonLayout = html.input(
                                class_ = "button", name = "previous",
                                type = "submit", value = label)
                        else:
                            previousButtonLayout = html.a(
                                label, class_ = "button",
                                href = dataHolder.getActionUri(
                                    "%d" % (pageNumber - 1)))
                        actionButtonsBarLayout.append(previousButtonLayout)
                        buttonsBarFilled = True
            if pageNumber < len(self.evaluateXpath("yep:pages/*")):
                labelNodes = self.evaluateXpath("yep:next/yep:label", pageNode)
                if labelNodes:
                    label = labelNodes[0].content
                else:
                    label = _("Next")
                if inForm:
                    previousButtonLayout = html.input(
                        class_ = "button next", name = "next", type = "submit",
                        value = label)
                else:
                    previousButtonLayout = html.a(
                        label, class_ = "button previous",
                        href = dataHolder.getActionUri(
                            "%d" % (pageNumber + 1)))
                actionButtonsBarLayout.append(previousButtonLayout)
                buttonsBarFilled = True
            if buttonsBarFilled:
                pageLayout.append(buttonsBarLayout)
            return True
        return things.Thing.fillPageLayout(self, layout)

    def getTitle(self):
        nodes = self.evaluateXpath("yep:title")
        if not nodes:
            return None
        return nodes[0].content

    def getSimpleLabel(self):
        return self.title

    def submit(self, *arguments):
        dataHolder = self.getDataHolder()
        submission = environs.getVar("submission")
        try:
            pageNumber = int(submission.getField("pageName"))
        except:
            pageNumber = None
        if pageNumber:
            if submission.getField("previous") and pageNumber > 1:
                return environs.getVar("httpRequestHandler").outputRedirect(
                    dataHolder.getActionUri(str(pageNumber - 1)))
            elif submission.getField("next") \
                     and pageNumber < len(self.evaluateXpath("yep:pages/*")):
                pageNodes = self.evaluateXpath("yep:pages/*[%d]" % pageNumber)
                pageNode = pageNodes[0]
                pageLocation = self.evaluateXpath("@src", pageNode)[0].content
                # FIXME.
                raise "FIXME"
                page, splitedAction = self.walkToLocation(pageLocation)
                if splitedAction:
                    pageName = splitedAction[0]
                else:
                    pageName = None
                environs.push(_level = "PageSequence.submit",
                              currentStation = page,
                              pageName = pageName)
                try:
                    return page.submitToUrl(dataHolder.getActionUri(
                        str(pageNumber + 1)))
                finally:
                    environs.pull(_level = "PageSequence.submit")
            raise faults.PathNotFound("/".join(arguments))
        return things.Thing.submit(self, *arguments)

    #~ def walkActions1(self, uriPathFragments):
        #~ name = uriPathFragments[0]
        #~ remainingNames = uriPathFragments
        #~ if name == 'doHttpRequest':
            #~ pageNumber = 1
        #~ elif name.isdigit():
            #~ pageNumber = int(name)
            #~ remainingNames = remainingNames[1:]
        #~ else:
            #~ pageNumber = None
        #~ if pageNumber is not None:
            #~ dataHolder = self.getDataHolder()
            #~ pageNodes = self.evaluateXpath('yep:pages/*[%d]' % pageNumber)
            #~ if not pageNodes:
                #~ if uriPathFragments[-1] == 'exists':
                    #~ return False
                #~ else:
                    #~ raise faults.PathNotFound('/'.join(uriPathFragments))
            #~ pageNode = pageNodes[0]
            #~ if pageNode.name == 'login':
                #~ libertyAlliance = self.walkToLocation(
                    #~ '/liberty-alliance')
                #~ return libertyAlliance.do(
                    #~ 'view', remainingNames, libertyAlliance.loginToUrl,
                    #~ dataHolder.getActionUri('%d' % (pageNumber + 1)))
            #~ elif pageNode.name == 'logout':
                #~ libertyAlliance = self.walkToLocation(
                    #~ '/liberty-alliance')
                #~ return libertyAlliance.do(
                    #~ 'view', remainingNames, libertyAlliance.logoutToUrl,
                    #~ dataHolder.getActionUri('%d' % (pageNumber + 1)))
            #~ else:
                #~ pageLocation = self.evaluateXpath("@src", pageNode)[0].content
                #~ page = self.walkToLocation(pageLocation)
                #~ return page.walk(remainingNames)
                #~ return self.do('view', remainingNames, self.output)
        #~ return things.Thing.walkActions1(self, uriPathFragments)

    title = property(getTitle)
    simpleLabel = property(getSimpleLabel)


elements.registerElement(
    namespaces.yep.uri, "pageSequence", PageSequence,
    "http://www.entrouvert.org/expression/schemas/PageSequence.xsd",
    "http://www.entrouvert.org/expression/descriptions/PageSequence.xml")
