package Moderate;
use strict;
#################################################################################
# Ikonboard v3 by Jarvis Entertainment Group, Inc.
#
# No parts of this script can be used outside Ikonboard without prior consent.
#
# More information available from <ib-license@jarvisgroup.net>
# (c)2001 Jarvis Entertainment Group, Inc.
# 
# http://www.ikonboard.com
#
# Please Read the license for more information
#+-----------------------------------------------------------------+
#
# Moderate: Moderation Fucntions.
#
#################################################################################

BEGIN {
    require 'Lib/FUNC.pm';
    require 'iTextparser.pm';
    require 'Searchlog.pm';
}

my $output      = FUNC::Output->new();
my $mem         = FUNC::Member->new();
my $std         = FUNC::STD->new();
my $s_log       = Searchlog->new();
my $txt         = iTextparser->new();
$Moderate::lang = $std->LoadLanguage('ModerateWords');
$Post::lang     = $std->LoadLanguage('PostWords');

# Override JS submit validation (will give error on empty post)
$Post::lang->{'override'} = 1;

sub new {
    my $pkg = shift;
    my $obj = { '.html' => undef, 'PASSED' => 0 };
    bless $obj, $pkg;
    return $obj;
}



sub CloseForm {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'CLOSE_TOPIC';
    $obj->CheckAuthorisation($db);

    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;

    $obj->CompileHTML('close');

    $output->print_ikonboard( DB           => $db,
                              STD          => $std,
                              NAV          => [ 
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=SF;f=$obj->{'FORUM'}->{'FORUM_ID'}" class='nav'>$obj->{'FORUM'}->{'FORUM_NAME'}</a>!,
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=ST;f=$obj->{'FORUM'}->{'FORUM_ID'};t=$obj->{'TOPIC'}->{'TOPIC_ID'}" class='nav'>$obj->{'TOPIC'}->{'TOPIC_TITLE'}</a>!,
                                              ],
                              OUTPUT       => $obj->{'.html'},
                              JAVASCRIPT   => '1',
                              TITLE        => "iB::" . "$Moderate::lang->{'t_close'}: $obj->{'TOPIC'}->{'TOPIC_TITLE'}"
                            );

}



sub OpenForm {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'OPEN_TOPIC';
    $obj->CheckAuthorisation($db);

    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;

    $obj->CompileHTML('open');

    $output->print_ikonboard( DB           => $db,
                              STD          => $std,
                              NAV          => [ 
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=SF;f=$obj->{'FORUM'}->{'FORUM_ID'}" class='nav'>$obj->{'FORUM'}->{'FORUM_NAME'}</a>!,
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=ST;f=$obj->{'FORUM'}->{'FORUM_ID'};t=$obj->{'TOPIC'}->{'TOPIC_ID'}" class='nav'>$obj->{'TOPIC'}->{'TOPIC_TITLE'}</a>!,
                                              ],
                              OUTPUT       => $obj->{'.html'},
                              JAVASCRIPT   => '1',
                              TITLE        => "iB::" . "$Moderate::lang->{'t_open'}: $obj->{'TOPIC'}->{'TOPIC_TITLE'}"
                            );

}


sub DeleteForm {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'DELETE_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
    $obj->CompileHTML('delete');

    $output->print_ikonboard( DB           => $db,
                              STD          => $std,
                              NAV          => [ 
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=SF;f=$obj->{'FORUM'}->{'FORUM_ID'}" class='nav'>$obj->{'FORUM'}->{'FORUM_NAME'}</a>!,
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=ST;f=$obj->{'FORUM'}->{'FORUM_ID'};t=$obj->{'TOPIC'}->{'TOPIC_ID'}" class='nav'>$obj->{'TOPIC'}->{'TOPIC_TITLE'}</a>!,
                                              ],
                              OUTPUT       => $obj->{'.html'},
                              TITLE        => "iB::" . "$Moderate::lang->{'t_delete'}: $obj->{'TOPIC'}->{'TOPIC_TITLE'}"
                             );

}

sub EditForm {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'EDIT_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
    $obj->CompileHTML('edit');

    $output->print_ikonboard( DB           => $db,
                              STD          => $std,
                              NAV          => [ 
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=SF;f=$obj->{'FORUM'}->{'FORUM_ID'}" class='nav'>$obj->{'FORUM'}->{'FORUM_NAME'}</a>!,
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=ST;f=$obj->{'FORUM'}->{'FORUM_ID'};t=$obj->{'TOPIC'}->{'TOPIC_ID'}" class='nav'>$obj->{'TOPIC'}->{'TOPIC_TITLE'}</a>!,
                                              ],
                              OUTPUT       => $obj->{'.html'},
                              JAVASCRIPT   => '1',
                              TITLE        => "iB::" . "$Moderate::lang->{'t_edit'}: $obj->{'TOPIC'}->{'TOPIC_TITLE'}"
                            );
}

sub MoveForm {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'MOVE_TOPIC';
    $obj->CheckAuthorisation($db);

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'moderate_no_permission'
               ) unless $obj->{'PASSED'} == 1;

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE =>'move_already_moved'
               ) if $obj->{'TOPIC'}->{'TOPIC_STATE'} eq 'moved';


    my $html = qq[ <select name='destination' class='forminput'>];

    require $iB::INFO->{'IKON_DIR'}.'Data/ForumJump.pm';
    my $Forums = ForumJump->new();

    for (sort { $a <=> $b } keys %{$Forums}) {
        if ($Forums->{$_}[0] eq 'c') {
            if ($Forums->{$_}[3] ne '*') {
                next unless grep { $_ == $iB::MEMBER->{'MEMBER_GROUP'} } (split (/,/, $Forums->{$_}[3]) );
            }
            my $dash = '-' x length($Forums->{$_}[2]);
            $html .= qq[<option value="">&nbsp;\n
                        <option value="">&gt;$Forums->{$_}[2]\n
                        <option value="">&nbsp;&nbsp;$dash\n
                       ];
        } elsif ($Forums->{$_}[0] eq 'f') {
            if ($Forums->{$_}[3] ne '*') {
                next unless grep { $_ == $iB::MEMBER->{'MEMBER_GROUP'} } (split (/,/, $Forums->{$_}[3]) );
            }
            $html .= qq[<option value="$Forums->{$_}[1]">&nbsp;&nbsp;&nbsp;+- $Forums->{$_}[2]\n];
        }
    }

    $html .= qq[</select>\n];

    $obj->CompileHTML('move', $html);

    $output->print_ikonboard( DB           => $db,
                              STD          => $std,
                              NAV          => [
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=SF;f=$obj->{'FORUM'}->{'FORUM_ID'}" class='nav'>$obj->{'FORUM'}->{'FORUM_NAME'}</a>!,
                                                qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?s=$iB::SESSION;act=ST;f=$obj->{'FORUM'}->{'FORUM_ID'};t=$obj->{'TOPIC'}->{'TOPIC_ID'}" class='nav'>$obj->{'TOPIC'}->{'TOPIC_TITLE'}</a>!,
                                              ],
                              OUTPUT       => $obj->{'.html'},
                              JAVASCRIPT   => '1',
                              TITLE        => "iB::" . "$Moderate::lang->{'t_move'}: $obj->{'TOPIC'}->{'TOPIC_TITLE'}"
                            );
}

#+------------------------------------------------------------------------------------------------------




sub CompileHTML ($$) {
    my ($obj, $type, $other) = @_;

    if ($type eq 'close') {

        $obj->{'.html'}  = $obj->_headers('close');
        $obj->{'.html'} .= ModView::table_top("$Moderate::lang->{'top_close'} $obj->{'FORUM'}->{'FORUM_NAME'} -&gt; $obj->{'TOPIC'}->{'TOPIC_TITLE'}");
        $obj->{'.html'} .= ModView::mod_exp($Moderate::lang->{'close_topic'});
        $obj->{'.html'} .= $obj->_post_body();
        $obj->{'.html'} .= ModView::end_form($Moderate::lang->{'submit_close'});

    } elsif ($type eq 'open') {

        $obj->{'.html'}  = $obj->_headers('open');
        $obj->{'.html'} .= ModView::table_top("$Moderate::lang->{'top_open'} $obj->{'FORUM'}->{'FORUM_NAME'} -&gt; $obj->{'TOPIC'}->{'TOPIC_TITLE'}");
        $obj->{'.html'} .= ModView::mod_exp($Moderate::lang->{'open_topic'});
        $obj->{'.html'} .= $obj->_post_body();
        $obj->{'.html'} .= ModView::end_form($Moderate::lang->{'submit_open'});

    } elsif ($type eq 'delete') {

        $obj->{'.html'} .= ModView::delete_js();
        $obj->{'.html'} .= $obj->_headers('delete');
        $obj->{'.html'} .= ModView::table_top("$Moderate::lang->{'top_delete'} $obj->{'FORUM'}->{'FORUM_NAME'} -&gt; $obj->{'TOPIC'}->{'TOPIC_TITLE'}");
        $obj->{'.html'} .= ModView::mod_exp($Moderate::lang->{'delete_topic'});
        $obj->{'.html'} .= ModView::end_form($Moderate::lang->{'submit_delete'});

    } elsif ($type eq 'edit') {

        $obj->{'.html'}  = $obj->_headers('edit');
        $obj->{'.html'} .= ModView::table_top("$Moderate::lang->{'top_edit'} $obj->{'FORUM'}->{'FORUM_NAME'} -&gt; $obj->{'TOPIC'}->{'TOPIC_TITLE'}");
        $obj->{'.html'} .= ModView::mod_exp($Moderate::lang->{'edit_topic'});
        $obj->{'.html'} .= ModView::topictitle_fields($obj->{'TOPIC'}->{'TOPIC_TITLE'}, $obj->{'TOPIC'}->{'TOPIC_DESC'});
        $obj->{'.html'} .= ModView::end_form($Moderate::lang->{'submit_edit'});

    } elsif ($type eq 'move') {

        $obj->{'.html'}  = $obj->_headers('move');
        $obj->{'.html'} .= ModView::table_top("$Moderate::lang->{'top_move'} $obj->{'FORUM'}->{'FORUM_NAME'} -&gt; $obj->{'TOPIC'}->{'TOPIC_TITLE'}");
        $obj->{'.html'} .= ModView::mod_exp($Moderate::lang->{'move_topic'});
        $obj->{'.html'} .= ModView::move_form($other, $obj->{'FORUM'}->{'FORUM_NAME'});
        $obj->{'.html'} .= $obj->_post_body();
        $obj->{'.html'} .= ModView::end_form($Moderate::lang->{'submit_move'});
    }

    my $smilies = qq~<tr align='center'>\n~;
    my $cnt = 0;
    my $show_table = 0;
    for my $e (split (/\|&\|/,$iB::INFO->{'EMOTICONS'}) ) {
        my ($type, $image, $p_inc) = split (/\|/,$e);
        next unless $type and $image;
        next unless $p_inc;

        $cnt++;
        $show_table++;
        $smilies .= qq~<td><a href="javascript:emoticon('$type')"><img src="$iB::INFO->{'EMOTICONS_URL'}/$image" alt="smilie" border="0"></a>&nbsp;</td>\n~;

        if ($cnt == $iB::INFO->{'EMO_PER_ROW'}) {
            $smilies .= qq~</tr>\n\n<tr align='center'>\n~;
            $cnt = 0;
        }
    }

    if ($cnt != $iB::INFO->{'EMO_PER_ROW'}) {
        $cnt++;
        for ($cnt .. $iB::INFO->{'EMO_PER_ROW'}) {
            $smilies .= qq~<td>&nbsp;</td>\n~;
        }
        $smilies .= qq~</tr>~;
    }

    my $table = PostView::smilie_table();
    if ($show_table) {
        $table =~ s:<!--THE SMILIES-->:$smilies:;
        $obj->{'.html'} =~ s:<!--SMILIE TABLE-->:$table:;
    }

}

sub _post_body ($) {
    my ($obj, $extra) = @_;
    $Post::lang->{'the_max_length'} = $iB::INFO->{'MAX_POST_LENGTH'} * 1024;
    return PostView::PostIcons() . PostView::postbox_buttons($extra) . PostView::CheckBoxes();
}

sub _headers ($$) {
    my ($obj, $type) = @_;
    my $return = qq[<form action="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}" method="post" name='REPLIER' onSubmit='return ValidateForm()'>\n<input type='hidden' name='act' value='Mod'>\n];
    $return   .= qq[<input type='hidden' name='s' value='$iB::SESSION'>\n<input type='hidden' name='st' value='$iB::IN{'st'}'>\n];
    if ($type eq 'close') {

        $return .= qq[<input type='hidden' name='CODE' value='06'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>\n];
        
    } elsif ($type eq 'open') {

        $return .= qq[<input type='hidden' name='CODE' value='07'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>\n];

    } elsif ($type eq 'delete') {

        $return .= qq[<input type='hidden' name='CODE' value='08'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>\n];

    } elsif ($type eq 'edit') {
   
        $return .= qq[<input type='hidden' name='CODE' value='12'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>\n];

    } elsif ($type eq 'move') {
   
        $return .= qq[<input type='hidden' name='CODE' value='14'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>\n];

    } 
}             

#+------------------------------------------------------------------------------------------------------

sub DoMove ($) {
    my ($obj,$db) = @_;

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'move_no_forum'
               ) unless defined $iB::IN{'destination'};

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'move_no_source'
               ) unless defined $iB::IN{'f'};


    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'move_same_forum'
               ) if $iB::IN{'f'} == $iB::IN{'destination'};


    $obj->{'MODE'} = 'MOVE_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;

    # Get the sources

    my @topics = split /,/, $iB::IN{'t'};

    # Get the number of replies / posts to add
    my $info = $obj->move_topic( SOURCE       => $iB::IN{'f'},
                                 DESTINATION  => $iB::IN{'destination'},
                                 TOPICS       => \@topics,
                                 LINK         => $iB::IN{'leave'},
                                 DB           => $db,
                               );

    # Get the old forum details...

    my $s_forum = $db->select( TABLE => 'forum_info',
                               KEY   => $iB::IN{'f'},
                             );

    my $d_forum = $db->select( TABLE => 'forum_info',
                               KEY   => $iB::IN{'destination'},
                             );


    # Sort out the last post stuff [ Source Forum ]
    my $old_topic = $db->query( TABLE    => 'forum_topics',
                                ID       => $iB::IN{'f'},
                                WHERE    => "FORUM_ID == $iB::IN{'f'} and APPROVED == 1",
                                RANGE    => "0 to 1",
                                SORT_KEY => "TOPIC_LAST_DATE",
                                SORT_BY  => "Z-A"
                              );

    $db->update(  TABLE  => 'forum_info',
                  KEY    => $iB::IN{'f'},
                  VALUES => { L_TOPIC_TITLE       => $old_topic->[0]->{'TOPIC_TITLE'},
                              L_TOPIC_ID          => $old_topic->[0]->{'TOPIC_ID'},
                              FORUM_LAST_POST     => $old_topic->[0]->{'TOPIC_LAST_DATE'},
                              FORUM_LAST_POSTER_N => $old_topic->[0]->{'TOPIC_LASTP_N'},
                              FORUM_LAST_POSTER   => $old_topic->[0]->{'TOPIC_LAST_POSTER'},
                              FORUM_TOPICS        => $s_forum->{'FORUM_TOPICS'} + $info->{'S_TOPICS'},
                              FORUM_POSTS         => $s_forum->{'FORUM_POSTS'}  + $info->{'S_POSTS'},
                            },
               );

    # Sort out the last post stuff [ Destination Forum ]
    my $new_topic = $db->query( TABLE    => 'forum_topics',
                                ID       => $iB::IN{'destination'},
                                WHERE    => "FORUM_ID == $iB::IN{'destination'} and APPROVED == 1",
                                RANGE    => "0 to 1",
                                SORT_KEY => "TOPIC_LAST_DATE",
                                SORT_BY  => "Z-A"
                              );

    $db->update(  TABLE  => 'forum_info',
                  KEY    => $iB::IN{'destination'},
                  VALUES => { L_TOPIC_TITLE       => $new_topic->[0]->{'TOPIC_TITLE'},
                              L_TOPIC_ID          => $new_topic->[0]->{'TOPIC_ID'},
                              FORUM_LAST_POST     => $new_topic->[0]->{'TOPIC_LAST_DATE'},
                              FORUM_LAST_POSTER_N => $new_topic->[0]->{'TOPIC_LASTP_N'},
                              FORUM_LAST_POSTER   => $new_topic->[0]->{'TOPIC_LAST_POSTER'},
                              FORUM_TOPICS        => $d_forum->{'FORUM_TOPICS'} + $info->{'D_TOPICS'},
                              FORUM_POSTS         => $d_forum->{'FORUM_POSTS'}  + $info->{'D_POSTS'},
                            },
               );

    $output->redirect_screen(TEXT => $Moderate::lang->{p_moved}, URL => "act=SF;f=$iB::IN{'f'}");       

}



sub move_topic {
    my $obj = shift;

    my %IN = ( SOURCE      => "",
               DESTINATION => "",
               TOPICS      => [],
               LINK        => "",
               DB          => "",
               @_,
             );

    my $db = $IN{'DB'};


    #XXX Check for errors....



    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'move_no_topic'
               ) unless scalar @{$IN{'TOPICS'}} > 0;


    # Init global counter...

    my $return = { S_POSTS => 0, S_TOPICS => 0, D_POSTS => 0, D_TOPICS => 0 };

    # Start the loop...

    for my $mt ( @{$IN{'TOPICS'}} ) {

        $IN{'TOPIC_ID'} = $mt;

        #XXX Grab the old topic
    
        my $topic = $db->select( TABLE  => 'forum_topics',
                                 ID     => $IN{'SOURCE'},
                                 KEY    => $IN{'TOPIC_ID'}
                               );

        # Double check...
        next unless defined $topic->{'TOPIC_ID'};

        # Write the log..
        $db->insert(  TABLE  => 'moderator_logs',
                      VALUES => { FORUM_ID     => $IN{'SOURCE'},
                                  TOPIC_ID     => $topic->{'TOPIC_ID'},
                                  POST_ID      => undef,
                                  MEMBER_ID    => $iB::MEMBER->{'MEMBER_ID'},
                                  MEMBER_NAME  => $iB::MEMBER->{'MEMBER_NAME'},
                                  REMOTE_ADDR  => $iB::IN{'IP_ADDRESS'},
                                  HTTP_REFERER => $ENV{'HTTP_REFERER'},
                                  TIME         => time,
                                  TOPIC_TITLE  => $topic->{'TOPIC_TITLE'},
                                  ACTION       => "Moved a topic",
                                  QUERY_STRING => $ENV{'QUERY_STRING'},
                                },
                   );

        #XXX Are we adding a post?
        
        if ( $iB::IN{'Post'} ) {
            my $post = $obj->create_post($db);
            $post->{'FORUM_ID'} = $IN{'SOURCE'};
            $post->{'TOPIC_ID'} = $topic->{'TOPIC_ID'};
            $db->insert( TABLE    => 'forum_posts',
                         DBID     => 'f'.$IN{'SOURCE'},
                         ID       => $topic->{'TOPIC_ID'},
                         VALUES   => $post
                      ); 
            # Update the topic...
            $topic->{'TOPIC_POSTS'}++;
            $topic->{'TOPIC_LAST_POSTER'} = $obj->{'MEMBER'}->{'MEMBER_ID'};
            $topic->{'TOPIC_LASTP_N'}     = $obj->{'MEMBER'}->{'MEMBER_NAME'};
            $topic->{'TOPIC_LAST_DATE'}   = time;
            $db->update( TABLE  => 'forum_topics',
                         ID     => $IN{'SOURCE'},
                         KEY    => $topic->{'TOPIC_ID'},
                         VALUES => $topic,
                       );
        }

        # We need to do this so they show in the destination forum
        $topic->{'FORUM_ID'} = $IN{'DESTINATION'};
        delete ($topic->{'TOPIC_ID'});
        # Insert new topic into destination forum...
        my $nu_id = $db->insert(TABLE  => 'forum_topics',
                                ID     => $IN{'DESTINATION'},
                                VALUES => $topic,
                               );
        &iB::catch_die($db->{error}) if $db->{error};
        #XXX Move the posts over
    
        my $posts = $db->query( TABLE  => 'forum_posts',
                                DBID   => 'f'.$IN{'SOURCE'},
                                ID     => $IN{'TOPIC_ID'},
                                WHERE  => "FORUM_ID == '$IN{'SOURCE'}' and TOPIC_ID == '$IN{'TOPIC_ID'}'",
                              );
    
        for my $p (@{$posts}) {
            delete ($p->{'POST_ID'});
            $p->{'TOPIC_ID'} = $nu_id;
            $p->{'FORUM_ID'} = $IN{'DESTINATION'};
    
            $db->insert( TABLE  => 'forum_posts',
                         DBID   => 'f'.$IN{'DESTINATION'},
                         ID     => $nu_id,
                         VALUES => $p
                       );
        }
    
        #XXX Do we have any polls to move?
    
        $db->update( TABLE  => 'forum_polls',
                     WHERE  => "POLL_ID == $IN{'TOPIC_ID'} and FORUM_ID == $IN{'SOURCE'}",
                     VALUES => { POLL_ID => $nu_id, FORUM_ID => $IN{'DESTINATION'} }
                   );
    
        $db->update( TABLE  => 'forum_poll_voters',
                     WHERE  => "POLL_ID == $IN{'TOPIC_ID'} and FORUM_ID == $IN{'SOURCE'}",
                     VALUES => { POLL_ID => $nu_id, FORUM_ID => $IN{'DESTINATION'} }
                   );
    
    
        #XXX Are we keeping a link to the destination forum/new topic id?
    
        if ($IN{'LINK'} ne 'delete') {
    
            my $breadcrumb = $IN{'LINK'} eq 'leave_empty' ? 'link' : 'moved';
    
            $db->update(  TABLE  => 'forum_topics',
                          ID     => $IN{'SOURCE'},
                          KEY    => $IN{'TOPIC_ID'},
                          VALUES => { TOPIC_STATE  => $breadcrumb ,
                                      MOVED_TO     => $IN{'DESTINATION'}.'&'.$nu_id,
                                      PIN_STATE    => 0,
                                    }
                      );
        } else {
    
            if ($IN{'LINK'} eq 'delete') {
                $db->delete(  TABLE  => 'forum_topics',
                              ID     => $IN{'SOURCE'},
                              KEY    => $IN{'TOPIC_ID'},
                           );
                $return->{'S_TOPICS'}--;
            }
    
            # Delete posts
            if ($IN{'LINK'} eq 'delete' or $IN{'LINK'} eq 'leave_empty') {
                $db->delete( TABLE   => 'forum_posts',
                             DBID    => 'f'.$IN{'SOURCE'},
                             ID      => $IN{'TOPIC_ID'},
                             WHERE   => "TOPIC_ID == $IN{'TOPIC_ID'}"
                           );
                $return->{'S_POSTS'} -= $topic->{'TOPIC_POSTS'};
            }
        }

        # Add to our counters..

        $return->{'D_POSTS'}  += $topic->{'TOPIC_POSTS'};
        $return->{'D_TOPICS'}++;

    }  # End loop

   

    #XXX Done, lets return the post/topic count

    return $return;

}



sub DoEdit ($) {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'EDIT_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'You do not have permission') unless $obj->{'PASSED'} == 1;
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'no_topic_title') unless $iB::IN{'TopicTitle'};

    $obj->{'TOPIC'}->{'TOPIC_TITLE'} = $iB::IN{'TopicTitle'};
    $obj->{'TOPIC'}->{'TOPIC_DESC'}  = $iB::IN{'TopicDesc'};

    $db->update(  TABLE  => 'forum_topics',
                  KEY    => $obj->{'.topic_id'},
                  ID     => $obj->{'.forum_id'},
                  VALUES => { TOPIC_TITLE => $iB::IN{'TopicTitle'},
                              TOPIC_DESC  => $iB::IN{'TopicDesc'},
                            },
               );


    if ($obj->{'.topic_id'} == $obj->{'FORUM'}->{'L_TOPIC_ID'}) {
        # Update the last post info in board view
        my $title = $obj->{'TOPIC'}->{'TOPIC_TITLE'};
        $title = substr($title,0,22) . '...' if length $title > 22;
    
        $db->update(  TABLE  => 'forum_info',
                      KEY    => $obj->{'.forum_id'},
                      VALUES => { L_TOPIC_TITLE => $title },
                   );
    }

    # Is this the news forum?
	
	  if ( defined $iB::INFO->{'NEWS_FORUM'} and ($iB::INFO->{'NEWS_FORUM'} == $obj->{'.forum_id'}) ) {
	
	    require SSI::Parser;

    	SSI::Parser::parse( DB       => $db,
                        	TEMPLATE => 'news',
                      	 );
    }

    # Write the log..
    $db->insert(  TABLE  => 'moderator_logs',
                  VALUES => { FORUM_ID     => $obj->{'.forum_id'},
                              TOPIC_ID     => $obj->{'.topic_id'},
                              POST_ID      => undef,
                              MEMBER_ID    => $iB::MEMBER->{'MEMBER_ID'},
                              MEMBER_NAME  => $iB::MEMBER->{'MEMBER_NAME'},
                              REMOTE_ADDR  => $iB::IN{'IP_ADDRESS'},
                              HTTP_REFERER => $ENV{'HTTP_REFERER'},
                              TIME         => time,
                              TOPIC_TITLE  => $iB::IN{'TopicTitle'},
                              ACTION       => "Edited a topic",
                              QUERY_STRING => $ENV{'QUERY_STRING'},
                            },
               );

    $output->redirect_screen(TEXT => $Moderate::lang->{p_edited}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'};st=$iB::IN{'st'}"); 
}


#+------------------------------------------------------------------------------------------------------
# CLOSE TOPIC

sub CloseTopic {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'CLOSE_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
    $obj->{'TOPIC'}->{'TOPIC_STATE'} = 'closed';
    $obj->create_post($db) if $iB::IN{'Post'};
    $db->update(  TABLE  => 'forum_topics',
                  KEY    => $obj->{'.topic_id'},
                  ID     => $obj->{'.forum_id'},
                  VALUES => $obj->{'TOPIC'},
                )        || die $db->{'error'};

    # Write the log..
    $db->insert(  TABLE  => 'moderator_logs',
                  VALUES => { FORUM_ID     => $obj->{'.forum_id'},
                              TOPIC_ID     => $obj->{'.topic_id'},
                              POST_ID      => undef,
                              MEMBER_ID    => $iB::MEMBER->{'MEMBER_ID'},
                              MEMBER_NAME  => $iB::MEMBER->{'MEMBER_NAME'},
                              REMOTE_ADDR  => $iB::IN{'IP_ADDRESS'},
                              HTTP_REFERER => $ENV{'HTTP_REFERER'},
                              TIME         => time,
                              TOPIC_TITLE  => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                              ACTION       => "Closed a topic",
                              QUERY_STRING => $ENV{'QUERY_STRING'},
                            },
               );
    $output->redirect_screen(TEXT => $Moderate::lang->{p_closed}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'};st=$iB::IN{'st'}"); 
}

#+------------------------------------------------------------------------------------------------------
# OPEN TOPIC


sub OpenTopic {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'OPEN_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
    $obj->{'TOPIC'}->{'TOPIC_STATE'} = 'open';
    $obj->create_post($db) if $iB::IN{'Post'};
    $db->update(  TABLE  => 'forum_topics',
                  KEY    => $obj->{'.topic_id'},
                  ID     => $obj->{'.forum_id'},
                  VALUES => $obj->{'TOPIC'}
                )        || die $db->{'error'};
    # Write the log..
    $db->insert(  TABLE  => 'moderator_logs',
                  VALUES => { FORUM_ID     => $obj->{'.forum_id'},
                              TOPIC_ID     => $obj->{'.topic_id'},
                              POST_ID      => undef,
                              MEMBER_ID    => $iB::MEMBER->{'MEMBER_ID'},
                              MEMBER_NAME  => $iB::MEMBER->{'MEMBER_NAME'},
                              REMOTE_ADDR  => $iB::IN{'IP_ADDRESS'},
                              HTTP_REFERER => $ENV{'HTTP_REFERER'},
                              TIME         => time,
                              TOPIC_TITLE  => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                              ACTION       => "Opened a topic",
                              QUERY_STRING => $ENV{'QUERY_STRING'},
                            },
               );
    $output->redirect_screen(TEXT => $Moderate::lang->{p_opened}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'};st=$iB::IN{'st'}"); 
}

#+------------------------------------------------------------------------------------------------------
# DELETE TOPIC


sub DeleteTopic {
    my ($obj,$db) = @_;
    $obj->{'MODE'} = 'DELETE_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;

    $db->delete(  TABLE  => 'forum_polls',
                  WHERE  => "POLL_ID == $obj->{'.topic_id'} and FORUM_ID == $obj->{'.forum_id'}"
               );

    $db->delete(  TABLE  => 'forum_poll_voters',
                  WHERE  => "POLL_ID == $obj->{'.topic_id'} and FORUM_ID == $obj->{'.forum_id'}"
               );

    $db->delete(  TABLE  => 'forum_topics',
                  ID     => $obj->{'.forum_id'},
                  KEY    => $obj->{'.topic_id'}
               );

    $db->delete(  TABLE  => 'forum_posts',
                  DBID   => 'f'.$obj->{'.forum_id'},
                  ID     => $obj->{'.topic_id'},
                  WHERE  => "TOPIC_ID == $obj->{'.topic_id'} and FORUM_ID == $obj->{'.forum_id'} and POST_ID > '0'",
                );

    $db->delete(  TABLE  => 'search_log',
                  ID     => $obj->{'.forum_id'},
                  WHERE  => qq[FORUM_ID == $obj->{'.forum_id'} and TOPIC_ID == $obj->{'.topic_id'}],
               );

    my $stats = {};

    $obj->{'FORUM'}->{'FORUM_TOPICS'}--;
    $obj->{'FORUM'}->{'FORUM_POSTS'} -= $obj->{'TOPIC'}->{'TOPIC_POSTS'};
    $stats->{'TOTAL_REPLIES'}         = '-'.$obj->{'TOPIC'}->{'TOPIC_POSTS'};
    $stats->{'TOTAL_TOPICS'}          = '-1';

    my $old_topic = $db->query( TABLE    => 'forum_topics',
                                ID       => $obj->{'.forum_id'},
                                WHERE    => "FORUM_ID == $obj->{'.forum_id'} and APPROVED == 1",
                                RANGE    => "0 to 1",
                                SORT_KEY => "TOPIC_LAST_DATE",
                                SORT_BY  => "Z-A"
                              );
    
    
    $obj->{'FORUM'}->{'L_TOPIC_TITLE'}       = $old_topic->[0]->{'TOPIC_TITLE'}       || '';
    $obj->{'FORUM'}->{'L_TOPIC_ID'}          = $old_topic->[0]->{'TOPIC_ID'}          || '';
    $obj->{'FORUM'}->{'FORUM_LAST_POST'}     = $old_topic->[0]->{'TOPIC_LAST_DATE'}   || '';
    $obj->{'FORUM'}->{'FORUM_LAST_POSTER_N'} = $old_topic->[0]->{'TOPIC_LASTP_N'}     || '';
    $obj->{'FORUM'}->{'FORUM_LAST_POSTER'}   = $old_topic->[0]->{'TOPIC_LAST_POSTER'} || '';



    $db->update(  TABLE  => 'forum_info',
                  KEY    => $obj->{'.forum_id'},
                  VALUES => $obj->{'FORUM'}
               );

    $std->ib_stats($stats);

    # Is this the news forum?
	
	  if ( defined $iB::INFO->{'NEWS_FORUM'} and ($iB::INFO->{'NEWS_FORUM'} == $obj->{'.forum_id'}) ) {
	
	    require SSI::Parser;

    	SSI::Parser::parse( DB       => $db,
                        	TEMPLATE => 'news',
                      	 );
    }

    # Write the log..
    $db->insert(  TABLE  => 'moderator_logs',
                  VALUES => { FORUM_ID     => $obj->{'.forum_id'},
                              TOPIC_ID     => $obj->{'.topic_id'},
                              POST_ID      => undef,
                              MEMBER_ID    => $iB::MEMBER->{'MEMBER_ID'},
                              MEMBER_NAME  => $iB::MEMBER->{'MEMBER_NAME'},
                              REMOTE_ADDR  => $iB::IN{'IP_ADDRESS'},
                              HTTP_REFERER => $ENV{'HTTP_REFERER'},
                              TIME         => time,
                              TOPIC_TITLE  => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                              ACTION       => "Deleted a topic",
                              QUERY_STRING => $ENV{'QUERY_STRING'},
                            },
               );

    $output->redirect_screen(TEXT => $Moderate::lang->{p_deleted}, URL => "act=SF;f=$obj->{'.forum_id'}");
}


sub DeletePost {
    my ($obj,$db) = @_;
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'missing_files') unless defined $iB::IN{'t'} and defined $iB::IN{'f'} and defined $iB::IN{'p'};
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'Cannot remove the first post') if $iB::IN{'p'} == 1;
    $obj->{'MODE'} = 'DELETE_POST';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;

    my $p = $db->select(  TABLE    => 'forum_posts',
                          DBID     => 'f'.$obj->{'.forum_id'},
                          ID       => $obj->{'.topic_id'},
                          KEY      => $obj->{'.post_id'},
                       );

    if ($p->{'ATTACH_ID'}) {
		# Ensure a directory is specified for the public uploads
        unless ($iB::INFO->{'PUBLIC_UPLOAD'}) {
            $iB::INFO->{'PUBLIC_UPLOAD'} = $iB::INFO->{'HTML_DIR'};
            $iB::INFO->{'PUBLIC_UPLOAD'} =~ s/non-cgi/uploads/;
        }
        # Make sure it's got a trailing slash..
        
        $iB::INFO->{'PUBLIC_UPLOAD'} .= '/' unless $iB::INFO->{'PUBLIC_UPLOAD'} =~ m!/$!;

        my $at = $db->select( TABLE => 'attachments',
                              KEY   => $p->{'ATTACH_ID'},
                           );
        $db->delete( TABLE => 'attachments',
                     KEY   => $p->{'ATTACH_ID'},
                   );
        unlink($iB::INFO->{'PUBLIC_UPLOAD'}.$at->{'FILE_NAME'});
    }
 
    $db->delete(  TABLE  => 'search_log',
                  ID     => $obj->{'.forum_id'},
                  WHERE  => qq[TOPIC_ID == "$obj->{'.topic_id'}" and POST_ID == "$obj->{'.post_id'}"],
               );

    $db->delete(  TABLE    => 'forum_posts',
                  DBID     => 'f'.$obj->{'.forum_id'},
                  ID       => $obj->{'.topic_id'},
                  KEY      => $obj->{'.post_id'},
               );

    my $stats = {};

    $obj->{'FORUM'}->{'FORUM_POSTS'}--;
    $obj->{'TOPIC'}->{'TOPIC_POSTS'}--;
    $stats->{'TOTAL_REPLIES'}       = '-1';
    $std->ib_stats($stats);

    #Sort out the last poster details in topic/board view

    my $old_post = $db->query( TABLE    => 'forum_posts',
                               DBID     => 'f'.$obj->{'.forum_id'},
                               ID       => $obj->{'.topic_id'},
                               COLUMNS  => ['POST_DATE', 'AUTHOR', 'AUTHOR_TYPE'],
                               WHERE    => "TOPIC_ID == $obj->{'.topic_id'} and QUEUED != 1",
                               RANGE    => '0 to 1',
                               SORT_KEY => 'POST_DATE',
                               SORT_BY  => 'Z-A'
                             );

    $obj->{'TOPIC'}->{'TOPIC_LAST_DATE'}   = $old_post->[0]->{'POST_DATE'};

    if ($old_post->[0]->{'AUTHOR_TYPE'}) {

        my $old_member = $mem->LoadMember( DB => $db, KEY => $old_post->[0]->{'AUTHOR'}, METHOD => 'by id');
        $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'} = $old_member->{'MEMBER_ID'};
        $obj->{'TOPIC'}->{'TOPIC_LASTP_N'}     = $old_member->{'MEMBER_NAME'};
        
    } else {
        
        $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'} = 0;
        $obj->{'TOPIC'}->{'TOPIC_LASTP_N'}     = $old_post->[0]->{'AUTHOR'};

    }


    if ($obj->{'.topic_id'} == $obj->{'FORUM'}->{'L_TOPIC_ID'}) {

        $obj->{'FORUM'}->{'FORUM_LAST_POST'}     = $obj->{'TOPIC'}->{'TOPIC_LAST_DATE'};
        $obj->{'FORUM'}->{'FORUM_LAST_POSTER_N'} = $obj->{'TOPIC'}->{'TOPIC_LASTP_N'};
        $obj->{'FORUM'}->{'FORUM_LAST_POSTER'}   = $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'};
        
    }

    $db->update(  TABLE  => 'forum_info',
                  KEY    => $obj->{'.forum_id'},
                  VALUES => $obj->{'FORUM'}
               );

    $db->update(  TABLE  => 'forum_topics',
                  KEY    => $obj->{'.topic_id'},
                  ID     => $obj->{'.forum_id'},
                  VALUES => $obj->{'TOPIC'}
                )        || die $db->{'error'};
    # Write the log..
    $db->insert(  TABLE  => 'moderator_logs',
                  VALUES => { FORUM_ID     => $obj->{'.forum_id'},
                              TOPIC_ID     => $obj->{'.topic_id'},
                              POST_ID      => undef,
                              MEMBER_ID    => $iB::MEMBER->{'MEMBER_ID'},
                              MEMBER_NAME  => $iB::MEMBER->{'MEMBER_NAME'},
                              REMOTE_ADDR  => $iB::IN{'IP_ADDRESS'},
                              HTTP_REFERER => $ENV{'HTTP_REFERER'},
                              TIME         => time,
                              TOPIC_TITLE  => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                              ACTION       => "Deleted a post",
                              QUERY_STRING => $ENV{'QUERY_STRING'},
                            },
               );
    $output->redirect_screen(TEXT => $Moderate::lang->{p_pdeleted}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'};st=$iB::IN{'st'}"); 
}




sub create_post ($) {
    my ($obj,$db) = @_;

    return unless (length($iB::IN{'Post'}) > 1);

    my %POST;
    #+-----------------------------------------------
    $iB::IN{'enablesig'} = $iB::IN{'enablesig'} eq 'yes' ? 1 : 0;
    $iB::IN{'enableemo'} = $iB::IN{'enableemo'} eq 'yes' ? 1 : 0;
    #+-----------------------------------------------
        
    $POST{'AUTHOR'}       = $obj->{'MEMBER'}->{'MEMBER_ID'};
    $POST{'ENABLE_SIG'}   = $iB::IN{'enablesig'};
    $POST{'ENABLE_EMO'}   = $iB::IN{'enableemo'};
    $POST{'IP_ADDR'}      = $ENV{'REMOTE_ADDR'};
    $POST{'POST_DATE'}    = time;
    $POST{'POST_ICON'}    = $std->IsNumber($iB::IN{'iconid'}) || 0;
    $POST{'POST'}         = $txt->Convert_for_db( TEXT    => $iB::IN{'Post'},
                                                  SMILIES => $POST{'ENABLE_EMO'},
                                                  IB_CODE => $obj->{'FORUM'}->{'FORUM_IBC'},
                                                  HTML    => $obj->{'FORUM'}->{'FORUM_HTML'}
                                                );
    $POST{'AUTHOR_TYPE'}  = 1;
    $POST{'TOPIC_ID'}     = $obj->{'.topic_id'};
    $POST{'FORUM_ID'}     = $obj->{'.forum_id'};
    $POST{'QUEUED'}       = 0;
    $POST{'ATTACH_ID'}    = undef;
    $POST{'ATTACH_HITS'}  = undef;
    $POST{'ATTACH_TYPE'}  = undef;

    return \%POST if $obj->{'MODE'} eq 'MOVE_TOPIC';

    #+-----------------------------------------------
    $obj->{'.post_id'}   = $db->insert( TABLE    => 'forum_posts',
                                        DBID     => 'f'.$obj->{'.forum_id'},
                                        ID       => $obj->{'.topic_id'},
                                        VALUES   => \%POST
                                     ); 
    #+-----------------------------------------------
    ++$obj->{'TOPIC'}->{'TOPIC_POSTS'};
    $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'} = $obj->{'MEMBER'}->{'MEMBER_ID'};
    $obj->{'TOPIC'}->{'TOPIC_LASTP_N'}     = $obj->{'MEMBER'}->{'MEMBER_NAME'};
    $obj->{'TOPIC'}->{'TOPIC_LAST_DATE'}   = time;

    $obj->{'MEMBER'}->{'MEMBER_POSTS'}++;
    $obj->{'MEMBER'}->{'LAST_POST'} = $obj->{'.forum_id'}.'-'.$obj->{'.topic_id'}.'-'.time;
    $mem->UpdateMember( DB       => $db,
                        MEMBER   => $obj->{'MEMBER'}
                      );

    $obj->{'FORUM'}->{'L_TOPIC_TITLE'} = $obj->{'TOPIC'}->{'TOPIC_TITLE'};
    $obj->{'FORUM'}->{'L_TOPIC_ID'}    = $obj->{'TOPIC'}->{'TOPIC_ID'};

    ++$obj->{'FORUM'}->{'FORUM_POSTS'};

    $std->ib_stats( { TOTAL_REPLIES => '+1'} );

    $obj->{'FORUM'}->{'L_TOPIC_TITLE'}       = substr($obj->{'FORUM'}->{'L_TOPIC_TITLE'},0,22) . '...' if length $obj->{'FORUM'}->{'L_TOPIC_TITLE'} > 22;
    $obj->{'FORUM'}->{'FORUM_LAST_POST'}     = time;
    $obj->{'FORUM'}->{'FORUM_LAST_POSTER_N'} = $obj->{'.g_post'} == 0 ? $std->unHTML($obj->{'MEMBER'}->{'MEMBER_NAME'}) : $iB::IN{'UserName'};
    $obj->{'FORUM'}->{'FORUM_LAST_POSTER'}   = $obj->{'.g_post'} == 0 ? $obj->{'MEMBER'}->{'MEMBER_ID'} : 0;

    $db->update( TABLE  => 'forum_info',
                 KEY    => $obj->{'.forum_id'},
                 VALUES => $obj->{'FORUM'}
               );
}





sub UpdateStats {
        my ($obj,$db) = @_;

}





sub PinTopic {
    my ($obj, $db) = @_;
    $obj->{'MODE'} = 'PIN_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
    $db->update(  TABLE  => 'forum_topics',
                  KEY    => $obj->{'.topic_id'},
                  ID     => $obj->{'.forum_id'},
                  VALUES => { PIN_STATE => 1 }
                )        || die $db->{'error'};
    $output->redirect_screen(TEXT => $Moderate::lang->{p_pinned}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}");
}


sub UNPinTopic {
    my ($obj, $db) = @_;
    $obj->{'MODE'} = 'UNPIN_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
    $db->update(  TABLE  => 'forum_topics',
                  KEY    => $obj->{'.topic_id'},
                  ID     => $obj->{'.forum_id'},
                  VALUES => { PIN_STATE => 0 }
                )        || die $db->{'error'};
    $output->redirect_screen(TEXT => $Moderate::lang->{p_unpinned}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}");
}


sub rebuild {
    my ($obj,$db) = @_;
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'missing_files') unless defined $iB::IN{'t'} and defined $iB::IN{'f'};
    $obj->{'MODE'} = 'EDIT_TOPIC';
    $obj->CheckAuthorisation($db);
    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;

    my $p = $db->query(   TABLE    => 'forum_posts',
                          DBID     => 'f'.$obj->{'.forum_id'},
                          ID       => $obj->{'.topic_id'},
                          WHERE    => "TOPIC_ID == $obj->{'.topic_id'}",
                       );
    my $replies = 0;
    my $last_post = {};
    my @delete;

    for my $i (@{$p}) {
        # Don't intefere with any queued posts..
        next if $i->{QUEUED};
        # Check to see if this is a duplicate post.
        if ($i->{POST} eq $last_post->{POST} and $i->{AUTHOR} eq $last_post->{AUTHOR}) {
            push @delete, $i->{POST_ID};
            next;
        } else {
            $last_post->{POST}   = $i->{POST};
            $last_post->{AUTHOR} = $i->{AUTHOR};
        }
        ++$replies;
    }

    # As the $replies actually equals the number of replies PLUS the first post,
    # we need to remove one from the counter to make it accurate.

    --$replies;

    # Safety check, lets make sure it doesn't fall into silly numbers
    
    $replies = 0 if $replies < 0;

    my $stats = {};

    my $del_count = scalar (@delete) || 0;

    # Do we have any to delete?

    if (scalar (@delete) > 0) {

        $db->delete(  TABLE    => 'forum_posts',
                      DBID     => 'f'.$obj->{'.forum_id'},
                      ID       => $obj->{'.topic_id'},
                      KEY      => \@delete,
                   );
    
        $obj->{'FORUM'}->{'FORUM_POSTS'} -= $del_count;
    
        $stats->{'TOTAL_REPLIES'}       = '-'.$del_count;
        $std->ib_stats($stats);
    
        #Sort out the last poster details in topic/board view
    
        my $old_post = $db->query( TABLE    => 'forum_posts',
                                   DBID     => 'f'.$obj->{'.forum_id'},
                                   ID       => $obj->{'.topic_id'},
                                   COLUMNS  => ['POST_DATE', 'AUTHOR', 'AUTHOR_TYPE'],
                                   WHERE    => "TOPIC_ID == $obj->{'.topic_id'} and QUEUED != 1",
                                   RANGE    => '0 to 1',
                                   SORT_KEY => 'POST_DATE',
                                   SORT_BY  => 'Z-A'
                                 );
    
        $obj->{'TOPIC'}->{'TOPIC_LAST_DATE'}   = $old_post->[0]->{'POST_DATE'};
    
        if ($old_post->[0]->{'AUTHOR_TYPE'}) {
    
            my $old_member = $mem->LoadMember( DB => $db, KEY => $old_post->[0]->{'AUTHOR'}, METHOD => 'by id');
            $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'} = $old_member->{'MEMBER_ID'};
            $obj->{'TOPIC'}->{'TOPIC_LASTP_N'}     = $old_member->{'MEMBER_NAME'};
            
        } else {
            
            $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'} = 0;
            $obj->{'TOPIC'}->{'TOPIC_LASTP_N'}     = $old_post->[0]->{'AUTHOR'};
    
        }
    
    
        if ($obj->{'.topic_id'} == $obj->{'FORUM'}->{'L_TOPIC_ID'}) {
    
            $obj->{'FORUM'}->{'FORUM_LAST_POST'}     = $obj->{'TOPIC'}->{'TOPIC_LAST_DATE'};
            $obj->{'FORUM'}->{'FORUM_LAST_POSTER_N'} = $obj->{'TOPIC'}->{'TOPIC_LASTP_N'};
            $obj->{'FORUM'}->{'FORUM_LAST_POSTER'}   = $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'};
            
        }

        $db->update(  TABLE  => 'forum_info',
                      KEY    => $obj->{'.forum_id'},
                      VALUES => $obj->{'FORUM'}
                   );
    }

    #update the topic counter.

    $obj->{'TOPIC'}->{'TOPIC_POSTS'} = $replies;

    $db->update(  TABLE  => 'forum_topics',
                  KEY    => $obj->{'.topic_id'},
                  ID     => $obj->{'.forum_id'},
                  VALUES => $obj->{'TOPIC'}
                )        || die $db->{'error'};

    # Write the log..
    $db->insert(  TABLE  => 'moderator_logs',
                  VALUES => { FORUM_ID     => $obj->{'.forum_id'},
                              TOPIC_ID     => $obj->{'.topic_id'},
                              POST_ID      => undef,
                              MEMBER_ID    => $iB::MEMBER->{'MEMBER_ID'},
                              MEMBER_NAME  => $iB::MEMBER->{'MEMBER_NAME'},
                              REMOTE_ADDR  => $iB::IN{'IP_ADDRESS'},
                              HTTP_REFERER => $ENV{'HTTP_REFERER'},
                              TIME         => time,
                              TOPIC_TITLE  => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                              ACTION       => "Rebuilt a topic",
                              QUERY_STRING => $ENV{'QUERY_STRING'},
                            },
               );

    $Moderate::lang->{final_rebuild} =~ s!<#DELETE_COUNT#>!$del_count!;
    $Moderate::lang->{final_rebuild} =~ s!<#REPLY_COUNT#>!$replies!;    

    $output->redirect_screen(TEXT => $Moderate::lang->{final_rebuild}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'};st=$iB::IN{'st'}"); 
}



sub CheckAuthorisation {
    my ($obj,$db) = @_;
    # For mod_perl...
    $obj->{'PASSED'} = 0;
    $obj->{'PASSED'} = 1 if $iB::MEMBER_GROUP->{'IS_SUPMOD'};
    $obj->{'PASSED'} = 1 if $obj->{'moderator'}->{ $obj->{'MODE'} };

    # Test for member features...
    unless ($obj->{'PASSED'}) {
        # Are we deleting a post, and are we able to delete our own posts?
        if (($obj->{'MODE'} eq 'DELETE_POST') and ($iB::MEMBER_GROUP->{'DELETE_OWN_POSTS'})) {
            $obj->GetPost( $db );
            # Is this the post author?
            if ($obj->{'SAVED'}->{'AUTHOR'} eq $iB::MEMBER->{'MEMBER_ID'}) {
                $obj->{'PASSED'} = 1;
            }
        } elsif (($obj->{'MODE'} eq 'DELETE_TOPIC') and ($iB::MEMBER_GROUP->{'DELETE_OWN_TOPICS'})) {
            if ($iB::MEMBER->{'MEMBER_ID'} eq $obj->{'TOPIC'}->{'TOPIC_STARTER'}) {
                $obj->{'PASSED'} = 1;
            }
        } elsif (($obj->{'MODE'} eq 'OPEN_TOPIC') and ($iB::MEMBER_GROUP->{'OPEN_CLOSE_TOPICS'})) {
            if ($iB::MEMBER->{'MEMBER_ID'} eq $obj->{'TOPIC'}->{'TOPIC_STARTER'}) {
                $obj->{'PASSED'} = 1;
            }
        } elsif (($obj->{'MODE'} eq 'CLOSE_TOPIC') and ($iB::MEMBER_GROUP->{'OPEN_CLOSE_TOPICS'})) {
            if ($iB::MEMBER->{'MEMBER_ID'} eq $obj->{'TOPIC'}->{'TOPIC_STARTER'}) {
                $obj->{'PASSED'} = 1;
            }
        }
    }

    $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;

}







sub Process {
    my ($obj,$db) = @_;
    $std->Error(LEVEL=>'1',MESSAGE=>'Wha.....?') unless (defined $iB::IN{'CODE'}) and
                                                      (defined $iB::IN{'f'});
    require "$iB::SKIN->{'DIR'}" . '/ModView.pm';
    require "$iB::SKIN->{'DIR'}" . '/PostView.pm';

    $obj->{'.topic_id'} = $std->IsNumber($iB::IN{'t'}) || 0;
    $obj->{'.forum_id'} = $std->IsNumber($iB::IN{'f'}) || 0;
    $obj->{'.post_id'}  = $std->IsNumber($iB::IN{'p'}) || 0;
    $obj->{'MEMBER'}    = $iB::MEMBER;

    $obj->LoadForum($db);
    $obj->LoadTopic($db) if defined $iB::IN{'t'};
    $obj->SetSession($db);
    my $CodeNo = $std->CheckCodeNo($iB::IN{'CODE'});
    my %Mode = ( '00'     => \&CloseForm,
                 '01'     => \&OpenForm,
                 '02'     => \&MoveForm,
                 '03'     => \&DeleteForm,
                 '04'     => \&DeletePost,
                 '05'     => \&EditForm,

                 '06'     => \&CloseTopic,
                 '07'     => \&OpenTopic,
                 '08'     => \&DeleteTopic,
                 '09'     => \&DeletePost,

                 '10'     => \&ForumModForm,
                 '11'     => \&Announcement,

                 '12'     => \&DoEdit,
                 '13'     => \&Unlucky_for_some,
                 '14'     => \&DoMove,

                 '15'     => \&PinTopic,
                 '16'     => \&UNPinTopic,
                 '17'     => \&rebuild,
                 
               );

  $Mode{$CodeNo} ? $Mode{$CodeNo}->($obj, $db) : ModerateError();
} 
sub Unlucky_for_some { my $luck = 'Usually very bad'; }

#+------------------------------------------------------------------------------------------------------
#+------------------------------------------------------------------------------------------------------
# UNIVERSAL


sub GetPost {
    my ($obj, $db) = @_;
    
    $obj->{'SAVED'} = $db->select( TABLE   => 'forum_posts',
                                   DBID    => 'f'.$obj->{'.forum_id'},
                                   ID      => $obj->{'.topic_id'},
                                   KEY     => $obj->{'.post_id'}
                                 );

    $obj->{'SAVED'}->{'POST'}   = $txt->Convert_for_textfield($obj->{'SAVED'}->{'POST'});

}

#+------------------------------------------------------------------------------------------------------



sub LoadForum {
    my ($obj, $db) = @_;
    $obj->{'.forum_id'} ||= $iB::IN{'f'};
    $obj->{'FORUM'} = $db->select( TABLE   => 'forum_info',
                                   KEY     => $obj->{'.forum_id'},
                                 );

}

#+------------------------------------------------------------------------------------------------------

sub LoadTopic {
    my ($obj, $db) = @_;

    $obj->{'TOPIC'} = $db->select( TABLE  => 'forum_topics',
                                   ID     => $obj->{'.forum_id'},
                                   KEY    => $obj->{'.topic_id'}
                                 );

}

#+------------------------------------------------------------------------------------------------------

sub SetSession {
    my ($obj, $db) = @_;

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE =>'moderate_no_permission'
               ) unless $iB::MEMBER->{'MEMBER_ID'};

    unless( !$iB::MEMBER->{'MEMBER_ID'} or $iB::MEMBER_GROUP->{'IS_SUPMOD'} ) {

        $obj->{'moderator'} = $db->query( TABLE      => 'forum_moderators',
                                          MATCH      => 'ONE',
                                          WHERE      => qq!FORUM_ID == "$obj->{'.forum_id'}" and MEMBER_ID eq "$iB::MEMBER->{'MEMBER_ID'}"!
                                        );
        $obj->{'moderator'} ||= { }; # unless  $obj->{'moderator'}->{'MODERATOR_ID'};
    }


}

#+------------------------------------------------------------------------------------------------------

sub ModerateError  { $std->Error(LEVEL=>'1',MESSAGE=>'No Action has been specified') }


1;