# <beans>
#     ...
#     <bean id="chooseVotingWizard" class="com.infopark.cm.htmlgui.browse.menuaction.CustomCommand">
#         <property name="titles">
#             <map>
#                 <entry key="en">
#                     <value>Choose Voting</value>
#                 </entry>
#                 <entry key="de">
#                     <value>Umfrage auswählen</value>
#                 </entry>
#             </map>
#         </property>
#         <property name="selectionType">
#             <value>single</value>
#         </property>
#         <property name="command">
#             <value>::chooseVoting::render</value>
#         </property>
#         <property name="dialog">
#             <value>true</value>
#         </property>
#     </bean>
#     ...
# </beans>

namespace eval ::chooseVoting {
    source [file join [app get shareDir]\
            script/cm/serverCmds/wizards/lib/wizardController.tcl]

    variable radioButtonFunc

    proc handleInitPage {buttonName} {
        variable objIds
        if {![userCanEditObject [lindex $objIds 0]]} {
            # Fehlende Berechtigung
        }
        set allVotings [getVotings]
        if {![llength $allVotings]} {
            # Keine Umfrage verfuegbar
        }
        return [renderChooseVotingPage $allVotings]
    }

    proc handleCancelAction {page} {
        return ""
    }

    proc handleChooseVotingOkPageAction {} {
        set selectedVotingId [getParam "selectedVotingId"]
        set existingVotings [getSelectedVotings]
        set newVotings [list $selectedVotingId]
        if {$selectedVotingId eq "no_voting"} {
            set newVotings [list]
        }
        set hasChanged [updateVotings $existingVotings $newVotings]
        return [renderFinalPage $hasChanged]
    }

    proc renderFinalPage {hasChanged} {
        if {$hasChanged} {
            variable objIds
            logMessage 0 "Refreshing $objIds"
            addNpsRefresh [lindex $objIds 0]
        }
        return ""
    }

    proc renderChooseVotingPage {allVotings} {
        set selectedVotings [getSelectedVotings]
        set valuesAndLabels [list]
        if {![llength $selectedVotings]} {
            set selectedVotings [list "no_voting"]
        }
        foreach v $allVotings {
            lappend valuesAndLabels [list $v [htmlVotingDescription $v]]
        }
        lappend valuesAndLabels [list "no_voting" [localize "no_voting"]]
        variable radioButtonFunc
        set fields [$radioButtonFunc selectedVotingId $valuesAndLabels\
                $selectedVotings ""]

        set content ""
        append content [::layout::fieldSet [localize "choose_voting"]\
                [$radioButtonFunc selectedVotingId $valuesAndLabels\
                $selectedVotings "" required true]]
        variable objIds
        return [npsPage -affectedNodes $objIds -title [localize "choose_voting"]\
                -buttons {ok cancel} chooseVoting $content]
    }

    ##########################################################################

    proc init {} {
        initLocalizer de {
            "question" "Frage"
            "answers" "Antworten"
            "no_voting" "Keine Umfrage"
            "choose_voting" "Umfrage ausw\u00e4hlen"
            "votingBox" "Umfragen"
        }

        initLocalizer en {
            "question" "Question"
            "answers" "Answers"
            "no_voting" "No Voting"
            "choose_voting" "Choose voting"
            "votingBox" "Votings"
        }

        variable radioButtonFunc ::layout::radioButtons
        if {![llength [info procs $radioButtonFunc]]} {
            proc radioButtons {name valuesAndLabels selectedValues {label {}} args} {
                 return [eval [list ::layout::_selectFields single -label $label\
                        -renderMode vertical $name $valuesAndLabels $selectedValues]\
                        $args]
            }
            set radioButtonFunc radioButtons
        }
    }

    init

    ##########################################################################
    proc getVotings {} {
        variable objIds
        set localHome [::playland::homeFolder [lindex $objIds 0]]

        set allVotings [obj where objClass Voting]
        set assignedReleasedVotings [news where channels voting]

        set votings [list]
        foreach v $allVotings {
            if {[lsearch $assignedReleasedVotings $v] == -1} {
                continue
            }
            if {$localHome ne [::playland::homeFolder $v]} {
                continue
            }
            lappend votings $v
        }
        return $votings
    }

    proc getVotingLinks {} {
        variable objIds
        set objId [lindex $objIds 0]
        return [content withId [getContentId $objId] get ip_votingSelected]
    }

    proc getSelectedVotings {} {
        set votings [list]
        foreach l [getVotingLinks] {
            lappend votings [link withId $l get destination]
        }
        return $votings
    }

    proc getVotingQuestion {votingId} {
        return [obj withId $votingId get ip_votingQuestion]
    }

    proc getVotingAnswers {votingId} {
        set answersRaw [obj withId $votingId get ip_votingAnswers]
        return [split $answersRaw "\n"]
    }

    proc getVotingId {votingLink} {
        return [link withId $votingLink get destination]
    }

    proc htmlVotingDescription {votingId} {
        set text ""
        return [format "<em>%s</em>: %s<br/><em>%s</em>: %s<br/>"\
                [localize "question"]\
                [quote [getVotingQuestion $votingId]]\
                [localize "answers"]\
                [quote [join [getVotingAnswers $votingId] ", "]]]

    }

    proc updateVotings {oldVotings newVotings} {
        if {[lindex $oldVotings 0] eq [lindex $newVotings 0]} {
            return 0
        }

        variable objIds
        set objId [lindex $objIds 0]
        if {![prepareEditObject $objId]} {
            # Kann nicht aktualisieren
            return 0
        }
        foreach l [getVotingLinks] {
            set destination [link withId $l get destination]
            if {-1 == [lsearch $newVotings $destination]} {
                link withId $l delete
            } elseif {0 <= [set index [lsearch $newVotings $destination]]} {
                set newVotings [lreplace $newVotings $index $index]
            }
        }
        foreach dest $newVotings {
            obj withId $objId editedContent addLinkTo\
                    attribute ip_votingSelected\
                    destinationUrl [obj withId $dest get path]
        }
        return 1
    }

    proc userCanEditObject {objId {login ""}} {
        if {$login eq ""} {
            set login [whoami]
        }

        if {![obj withId $objId permission permissionWrite isGrantedToUser $login]} {
            return 0
        }

        set keys [list isEdited isCommitted validControlActionKeys]

        foreach $keys [eval [list obj withId $objId mget] $keys] {}

        if {$isEdited} {
            set editor [obj withId $objId editedContent get editor]
            return [expr {$editor eq $login ||
                    [lsearch $validControlActionKeys "take"] >= 0}]
        }

        if {$isCommitted} {
            return [expr {[lsearch $validControlActionKeys "reject"] >= 0}]
        }

        return [expr {[lsearch $validControlActionKeys "edit"] >= 0}]
    }

    proc prepareEditObject {objId} {
        if {![userCanEditObject $objId]} {
            return 0
        }

        set keys [list isEdited isCommitted isReleased]
        foreach $keys [eval [list obj withId $objId mget] $keys] {}
        if {!$isEdited} {
            if {$isCommitted} {
                if {[catch {
                    obj withId $objId reject
                }]} {
                    return 0
                }
            } else {
                if {[catch {
                    obj withId $objId edit
                }]} {
                    return 0
                }
            }
        }

        set editor [obj withId $objId editedContent get editor]
        if {$editor ne [whoami]} {
            if {[catch {
                obj withId $objId take
            }]} {
                return 0
            }
        }

        return [expr {[whoami] eq [obj withId $objId editedContent get editor]}]
    }
}
