#!/bin/env perl
#
# The ticker (client & admin) loosely follows an MVC architecture.  The model
# is over in TickerAd.pm (it does all the DB work).  ticker.cgi is the view for
# the client, while this is the view+controller for the admin.
#
use strict;
use warnings;
use lib '/home/slowtwitch/forum.slowtwitch.com/cgi-bin/admin';
use GForum qw($IN);
GForum::init('/home/slowtwitch/forum.slowtwitch.com/cgi-bin/admin');
use TickerAd;
use Error qw(:try);

use constant {
    STATE_NORMAL => 0,
    STATE_UPDATE => 1,
    STATE_REDIRECT => 2,
    ADMIN_URL => "http://forum.slowtwitch.com/cgi-bin/tickerad/admin/admin.cgi"
};

# prototypes.
sub controller();
sub view($);

# And call the controller.
controller();

#
# This is the controller.  This is where work gets done.
#
sub controller() {
    my %viewstate = (state => STATE_NORMAL);

    # if we have an action parameter (that's non-empty), then do work:
    if(defined $IN->param('action') && length($IN->param('action')) > 0) {
        $viewstate{state} = STATE_REDIRECT;
        try {
            my $p = $IN->get_hash();
            if($p->{action} =~ /create/) {
                TickerAd::create_ticker($p->{msg}, $p->{link});
            } elsif($p->{action} =~ /show_update/) {
                $viewstate{state} = STATE_UPDATE;
                $viewstate{id} = $p->{'id'};
            } elsif($p->{action} =~ /do_update/) {
                TickerAd::update_ticker($p->{'id'}, $p->{'msg'}, $p->{'link'});
            } elsif($p->{action} =~ /delete/) {
                TickerAd::delete_ticker($p->{'id'});
            }
        } catch TickerAd::TickerAdException with {
            # oops.  something bad happened.
            $viewstate{error} = "Error: " . shift;
            # reset the viewstate so that we display the error message.
            $viewstate{state} = STATE_NORMAL;
        };
    }

    return view(\%viewstate);
}


#
# Build the view, which takes a single hashref describing how the view should
# behave.
#
sub view($) {
    my ($state) = @_;
    my %s = %$state;

    # If the state is redirect, we're done.
    if($s{state} == STATE_REDIRECT) {
        print $IN->redirect(ADMIN_URL);
        return;
    }

    # Now let's actually build the view, depending on our current state:
    print $IN->header();
    print qq{<html><head><title>TickerAd Admin</title></head><body>};

    # Try to load all the tickers:
    try {
        $s{data} = TickerAd::read_tickers();

        # Are we also trying to update a record?  Yeah, I know - we're
        # hitting the db again.  I wish that fetchall_hashref actually worked...
        if(defined $s{id}) {
            my $result = TickerAd::read_ticker($s{id});
            $s{msg} = $result->{ticker_text};
            $s{link} = $result->{ticker_link};
        }
    } catch TickerAd::TickerAdException with {
        $s{error} .= "  Could not read tickers from database!";
    };

    # Print an error message if we have one:
    if(defined $s{error}) {
        print "<p>" . $s{error} . "</p>";
    }

    # What should the top form look like?
    if($s{state} == STATE_NORMAL) {
        $s{title} = 'Create a ticker:';
        $s{submit} = 'Create ticker';
        $s{action} = 'create';
        $s{id} = "";
        $s{msg} = "";
        $s{link} = "";
    } elsif($s{state} == STATE_UPDATE) {
        $s{title} = 'Update a ticker:';
        $s{submit} = 'Update ticker';
        $s{action} = 'do_update';
    }
    
    # print the form, which is configured for the type of action we're
    # performing:
    print qq{<h3>} . $s{title} . qq{</h3>
        <form method="post" action="} . ADMIN_URL . qq{">
            <input type="hidden" name="action" value="} .
            $s{action} . qq{"/>
            <input type="hidden" name="id" value="} . $s{id} . qq{"/>
            <div><label for="message">Message:</label>
            <input type="text" name="msg" value="} . $s{msg} . qq{"/>
            </div><div><label for="link">Link:</label>
            <input type="text" name="link" value="} . $s{link} . qq{"/>
            </div><div><input type="submit" value="} . $s{submit} . qq{"/>
        </div></form>
    };
    
    # provide a way to get back to the create interface:
    if($s{action} =~ /update/) {
        print qq{<a href="} . ADMIN_URL . qq{">Create a ticker instead.</a>};
    }

    # Now print the entire list of all tickers.
    print qq{<h3>Current tickers:</h3>};


    # If there are no tickers, say so:
    if(@{$s{data}} == 0) {
        print "There are no tickers.";
    } else {
        # Print a table showing the ID, delete/edit links, messages, and links:
        print "<table>"; 
        print "<tr><td>ID</td><td/><td/><td>Message</td><td>Link</td></tr>";
        foreach my $k (@{$s{data}}) {
            my $id = $k->{ticker_id};
            my $msg = $k->{ticker_text};
            my $link = $k->{ticker_link};
            print qq{<tr><td>$id</td><td>
                <a href="} . ADMIN_URL . qq{?action=delete&id=$id">Delete</a></td><td>
                <a href="} . ADMIN_URL . qq{?action=show_update&id=$id">Update</a></td><td>} .
                $msg . "</td><td>" .
                qq{<a href="} . $link . qq{">} . 
                $link . "</a></td></tr>";
        }
        print "</table>";
    }
    print qq{</body></html>};
}

