# -------------------------------------------------------------------------------------
# flo::plugin::Poll
# -------------------------------------------------------------------------------------
#
#       Author : Jean-Michel Hiver (jhiver@cisedi.com).
#    Copyright : (c) MKDoc Holdings Ltd, 2001
# 
#      Unauthorized modification, use, reuse, distribution or redistribution
#      of this module is stricly forbidden
#
#    Description:
#
#      A plugin that is used to collect votes from Poll components, send cookies
#      to the navigators which have voted, and display results
#
# -------------------------------------------------------------------------------------
package flo::plugin::Poll;
use flo::HTTP::Date;
use flo::Object;
use lib::sql::Table;
use lib::cgi::CGI;
use flo::Standard;
use lib::Exception;
use flo::HTTP::Header;
use lib::PSP;
use strict;
use vars qw /@ISA/;
@ISA = qw /flo::Object/;
use vars qw /$already_voted/;

##
# $class->main;
# -------------
#  This method is invoked when it is found that a user is querying for the
#  sitemap plugin.
##
sub main
{
    my $class = shift;
    my $document_table = table ('Document');
    my $poll_results_table = table ('Poll_Results');
    my $cgi = cgi;
    
    # if this module is not concerned, let's return ASAP
    my $config = $class->config;
    my $http_name = $config->{http_name};
    my $q_http_name = quotemeta ($http_name);
    my $raw_path_info = raw_path_info;
    return unless ( ($raw_path_info =~ /.*\/$q_http_name$/o) );
    
    # otherwise, let's process the request
    $raw_path_info =~ s/$q_http_name$//;
    
    # clean path info so that we know the document from which we want to
    # start site-mapping
    my $path_info = path_info;
    if ($path_info ne '/')
    {
	$path_info =~ s/^\///;
	$path_info =~ s/\/$//;
	my @path_info = split /\//, $path_info;
	pop (@path_info);
	if (@path_info) { $path_info = '/' . (join '/', @path_info) . '/' }
	else { $path_info = '/' }
    }
    
    # mark already_voted to FALSE
    local $already_voted = 0;
    
    # get the current document. If it does not exist, let's pass the query to the 404
    my $document = $document_table->get ( Full_Path => $path_info ) or return;
    
    # now let's parse and split the document body into a set of document components
    my $editor = new flo::Editor;
    $editor->parse_xml ($document->{Body});
    
    # this is the hash that we'll send to the template
    my $hash = {};
    
    # get the poll that we want to process
    my $poll = $class->get_poll_component ($cgi, $editor) || return;
    
    # if the user has voted, let's save his vote in the Poll_Results table
    $class->register_vote ($poll, $cgi, $config, $hash);
    
    $hash->{Poll}     = $poll;
    $hash->{Document} = $document;
    $hash->{Far_Away} = flo::HTTP::Date::http_date ( time + 5000 * 24 * 3600 ); 
    $hash->{Already_Voted} = $already_voted;
    
    # here is what might be in the $hash
    # $hash = {
    #   Cookie_Name => "MyWonderfulPollCookie",
    #   Poll        => $poll_object,
    #   Results     => [
    #     {
    #       Answer  => 'Curry',
    #       Votes   => 32154,
    #       Score   => 100,
    #     },
    #     {
    #       Answer  => 'Marmite',
    #       Vote    => 0,
    #       Score   => 0,
    
  flo::HTTP::Header->out
      ( new flo::Template ( file => template ('poll', $document->Lang),
			    hash => $hash ) );
    return 'TERMINATE';
}


##
# $class->register_vote ($poll, $cgi, $config);
# ---------------------------------------------
#   Saves this person's vote in the Poll_Results table provided
#   that he has not voted yet
##
sub register_vote
{
    my $class = shift;
    my $poll  = shift;
    my $cgi   = shift;
    my $cfg   = shift;
    my $hash  = shift;
    
    # return if the poll unless the poll has started and
    # not yet finished
    return unless ($poll->is_started and not $poll->is_stopped);
    
    # if the user did not vote, then there's nothing to do
    return unless (defined $cgi->param ('answer'));
    
    # let's find out what the cookie name is
    my $cookie_name = $cfg->{cookie_name};
    
    # if the cookie is defined, then the user has already voted,
    # therefore we should not bother saving his vote
    if (defined $cgi->cookie (-name => $cookie_name . $poll->{id}))
    {
	$already_voted = 1;
	return;
    }
    
    # now, let's find out which answer the user voted for
    # if it's empty, let's return
    my $answer = $cgi->param ('answer') || return;
    
    # let's see if this answer is defined in the poll component
    # if it's not let's return
    return unless ( $answer =~ /^answer/     and
		    defined $poll->{$answer} and
		    $poll->{$answer} ne '' );
    
    # the answer seems to be valid, thus we now need to insert
    # a new record in the Poll_Results table
    my $poll_results = table ('Poll_Results');
    $poll_results->insert ( Poll_ID => $poll->{id}, Answer => $answer );
    
    # the new method of headers always returns the same object
    # thus the cookie that we'll set here will be still there
    # when we print the page out
    my $headers = new flo::HTTP::Header;
    
    # comment this later to activate cookie stuff
    $hash->{Cookie_Name} = $cookie_name . $poll->{id};
}


##
# $class->get_poll_component ($editor);
# --------------------------------------
#   Retrieves the poll component that we have to process
##
sub get_poll_component
{
    my $class  = shift;
    my $cgi    = shift;
    my $editor = shift;
    
    # let's try to find the poll we're dealing with. If $cgi->param ('Poll_ID') is
    # defined, then we'll try to get it, otherwise we'll just take the first poll
    # component that we'll find
    my $poll_id = $cgi->param ('Poll_ID');
    my @polls   = $editor->access ( class => [ 'poll' ] );
    
    # if there are no polls on this document, then we return nothing, which will
    # redirect the query to the Error plugin
    scalar @polls or return;
    
    my $poll = undef;
    if (defined $poll_id)
    {
	for (@polls)
	{
	    if ($_->{id} eq $poll_id)
	    {
		$poll = $_;
		last;
	    }
	}
    }
    else
    {
	$poll = $polls[0];
    }
    
    return $poll;
}


1;    

