# -*- 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.


"""Elections Module"""


import libxml2

import elements
import html
import namespaces
import parsers
import stations
import things


class Election(things.Thing):
    def fillResult1FieldValueLayout(self, description, layout):
        ballotBoxHolder = self.walkToLocation(self.ballotBoxLocation)
        ballotBox = ballotBoxHolder.getRootElement()
        formDescriptionLocation = "/descriptions/Form1.xml"
        formDescriptionHolder = self.walkToLocation(formDescriptionLocation)
        formDescription = formDescriptionHolder.getRootElement()
        votePageNodes = formDescription.evaluateXpath("yep:page[starts-with(@name, 'question')]")
        votePageNames = {}
        for votePageNode in votePageNodes:
            votePageNames[votePageNode] = formDescription.evaluateXpath(
                "@name", votePageNode)[0].content
        voteSubjects = {}
        for votePageNode in votePageNodes:
            nodes = formDescription.evaluateXpath(
                "yep:body/xforms:group/yep:spip[1]", votePageNode)
            if nodes:
                subject = nodes[0].content
            else:
                subject = _("Unknown Subject")
            voteSubjects[votePageNode] = subject
        voteXpaths = {}
        for votePageNode in votePageNodes:
            nodes = formDescription.evaluateXpath(
                "yep:body/xforms:group/*[starts-with(@ref, 'yep:reponse')]/@ref",
                votePageNode)
            if nodes:
                voteXpaths[votePageNode] = nodes[0].content
        votePossibleAnswers = ["-2", "-1", "0", "1", "2"]
        votePossibleAnswerLabels = {
            "-2": "Pas du tout d'accord",
            "-1": "Plutôt pas d'accord",
            "0": "Cela dépend / Ne sait pas / Hésite",
            "1": "Plutôt d'accord",
            "2": "Tout à fait d'accord",
            }        
        results = {}
        for voteXpath in voteXpaths.values():
            results[voteXpath] = {}
        voteTokens = ballotBox.itemLocalIds
        for voteToken in voteTokens:
            vote = ballotBoxHolder.getItem(voteToken)
            for voteXpath in voteXpaths.values():
                voteValue = vote.getContentAtXpath(voteXpath)
                if voteValue is None:
                    voteValue = "0"
                result = results[voteXpath]
                if voteValue in result:
                    result[voteValue] += 1
                else:
                    result[voteValue] = 1
        for votePageNode in votePageNodes:
            if votePageNode not in voteXpaths:
                continue
            voteXpath = voteXpaths[votePageNode]
            result = results[voteXpath]
            votesCount = 0
            div = html.div(class_ = "question")
            layout.append(div)
            
            # Add vote subject to layout.
            subjectDiv = html.div(class_ = "subject")
            div.append(subjectDiv)
            spipText = voteSubjects[votePageNode]
            htmlText = "<spip>%s</spip>" % parsers.makeHtmlFromSpip(spipText)
            doc = libxml2.readDoc(
                htmlText, None, None, libxml2.XML_PARSE_DTDLOAD | libxml2.XML_PARSE_NONET)
            node = doc.getRootElement().children
            while node is not None:
                subjectDiv.append(node)
                node = node.next

            for voteValue, count in result.items():
                votesCount += count

            if votesCount:
                ul = html.ul(class_ = "result-bar")
                div.append(ul)
                for voteValue in votePossibleAnswers:
                    if voteValue in result:
                        count = result[voteValue]
                    else:
                        count = 0
                    ul.append(html.li(
                        html.span(votePossibleAnswerLabels[voteValue], class_ = 'libelle'),
                        html.span(" %d%%" % int(round(float(100 * count) / votesCount)),
                            class_ = 'percent'),
                        class_ = "bar%s" % voteValue,
                        # Rounding error below is required for proper display on
                        # Internet Explorer.
                        style = "width: %s%%"
                            % (int(round(float(99 * count) / votesCount)))))
                ul.append(html.li(class_ = 'end-of-bar'))
            else:
                p = html.p('Pas encore de résultats.')
                div.append(p)
        return True

    def getBallotBoxLocation(self):
        nodes = self.evaluateXpath("yep:ballotBox/@src")
        if not nodes:
            return None
        return nodes[0].content

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

    def getSimpleLabel(self):
        return self.title

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


elements.registerElement(namespaces.yep.uri, "election", Election)
