package Post;
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
#+-----------------------------------------------------------------+
#
# Post: Posting Fucntions.
#
#################################################################################
BEGIN {
    require 'Lib/FUNC.pm';
    require 'iTextparser.pm';
    require 'Searchlog.pm';
   
}

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


sub new {
  my $pkg = shift;
  my $obj = {};
     $obj->{'_pkg'} = (caller(0))[0];
     $obj->{'MEMBER'} = $iB::MEMBER;
     $obj->{'FORUM'}  = undef;
     $obj->{'TOPIC'}  = undef;
     $obj->{'SAVED'}  = undef;
     $obj->{'_CAN_UPLOAD'} = undef;
  bless $obj, $pkg;
  return $obj;
}

####################################################################################
#
#                 >> New Poll Form
#
###################################################################################

sub NewPollForm {
    my ($obj, $db, $POST) = @_;
    $obj->LoadForum($db);
    $obj->CompileHTML('poll', $POST);
    $output->print_ikonboard( DB           => $db,
                              STD          => $std,
                              NAV          => [qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?act=SF;f=$obj->{'FORUM'}->{'FORUM_ID'}" class='nav'>$obj->{'FORUM'}->{'FORUM_NAME'}</a>!],
                              OUTPUT       => $obj->{'.html'},
                              JAVASCRIPT   => '1',
                              TITLE        => "iB::" . $Post::lang->{'posting_new_topic'}
                            );
}


sub NewPoll {
    my ($obj, $db, $preview) = @_;
   
    if ($obj->{'_pkg'} eq 'iPoll') {
        $obj->LoadForum($db);
        $obj->{'MEMBER'} = $iB::MEMBER;
        $obj->{preview} = $preview;
    }
    
    my $POST = $obj->CompilePost($db);

    if ($txt->{'ERROR'}) {
        $POST->{'_ERROR'} = $Post::lang->{$txt->{'ERROR'}};
        $obj->NewPollForm($db, $POST)
    }


    $iB::IN{'preview'} ? $obj->NewPollForm($db, $POST) : $obj->_do_new_post($db, $POST);
}




####################################################################################
#
#                 >> New Post
#
###################################################################################

sub NewPostForm {
    my ($obj, $db, $POST) = @_;
    $obj->CompileHTML('new', $POST);
    $output->print_ikonboard( DB           => $db,
                              STD          => $std,
                              NAV          => [qq!<a href="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?act=SF;f=$obj->{'FORUM'}->{'FORUM_ID'}" class='nav'>$obj->{'FORUM'}->{'FORUM_NAME'}</a>!],
                              OUTPUT       => $obj->{'.html'},
                              JAVASCRIPT   => '1',
                              TITLE        => "iB::" . $Post::lang->{'posting_new_topic'}
                            );
}


sub NewPost {
    my ($obj, $db) = @_;
   
    if ($obj->{'_pkg'} eq 'iPoll') {
        $obj->LoadForum($db);
        $obj->{'MEMBER'} = $iB::MEMBER;
    }

    my $POST = $obj->CompilePost($db);

    if ($txt->{'ERROR'}) {
        $POST->{'_ERROR'} = $Post::lang->{$txt->{'ERROR'}};
        $obj->NewPostForm($db, $POST)
    }

    $iB::IN{'preview'} ? $obj->NewPostForm($db, $POST) : $obj->_do_new_post($db, $POST);
}



sub _do_new_post {
    my ($obj, $db, $POST) = @_;
    
        # Sort out the etiquette filter
    
    if ($iB::INFO->{ETFILTER_PUNCT}) {
        $iB::IN{'TopicTitle'} =~ s/\?{1,}/\?/g;
        $iB::IN{'TopicTitle'} =~ s/(?:&#33;){1,}/&#33;/g;
        $iB::IN{'TopicDesc'}  =~ s/\?{1,}/\?/g;
        $iB::IN{'TopicDesc'}  =~ s/(?:&#33;){1,}/&#33;/g;
    }
    if ($iB::INFO->{ETFILTER_SHOUT}) {
        $iB::IN{'TopicTitle'} = lc($iB::IN{'TopicTitle'});
        $iB::IN{'TopicTitle'} = ucfirst($iB::IN{'TopicTitle'});
        $iB::IN{'TopicDesc'}  = lc($iB::IN{'TopicDesc'});
        $iB::IN{'TopicDesc'}  = ucfirst($iB::IN{'TopicDesc'});
    }
    
    my %TOPIC;
    $TOPIC{'TOPIC_TITLE'}      = $iB::IN{'TopicTitle'};
    $TOPIC{'TOPIC_DESC'}       = $iB::IN{'TopicDesc'};
    $TOPIC{'TOPIC_STATE'}      = 'open';
    $TOPIC{'TOPIC_POSTS'}      = 0;
    $TOPIC{'TOPIC_STARTER'}    = $obj->{'MEMBER'}->{'MEMBER_ID'};
    $TOPIC{'TOPIC_STARTER_N'}  = $obj->{'.g_post'} == 0 ? $obj->{'MEMBER'}->{'MEMBER_NAME'} : $iB::IN{'UserName'};
    $TOPIC{'TOPIC_START_DATE'} = time;
    $TOPIC{'TOPIC_LAST_POSTER'}= $obj->{'.g_post'} == 0 ? $obj->{'MEMBER'}->{'MEMBER_ID'}   : 0;
    $TOPIC{'TOPIC_LASTP_N'}    = $obj->{'.g_post'} == 0 ? $obj->{'MEMBER'}->{'MEMBER_NAME'} : $iB::IN{'UserName'};
    $TOPIC{'TOPIC_LAST_DATE'}  = time;
    $TOPIC{'TOPIC_ICON'}       = $obj->{'_pkg'} eq 'iPoll' ? 99 : $std->IsNumber($iB::IN{'iconid'});
    $TOPIC{'TOPIC_AUTHOR_TYPE'}= $obj->{'.g_post'} == 0 ? 1 : 0;
    $TOPIC{'POLL_STATE'}       = $obj->{'_pkg'} eq 'iPoll' ? $iB::IN{'allow_disc'} : 0;
    $TOPIC{'LAST_VOTE'}        = $obj->{'_pkg'} eq 'iPoll' ? time : 0;
    $TOPIC{'TOPIC_VIEWS'}      = 0;
    $TOPIC{'FORUM_ID'}         = $obj->{'.forum_id'};
    $TOPIC{'APPROVED'}         = $obj->{preview} ? 0 : 1;
    $TOPIC{'PIN_STATE'}        = 0;
    $obj->{'.topic_id'} = $db->insert( TABLE    => 'forum_topics',
                                       ID       => $obj->{'.forum_id'},
                                       VALUES   => \%TOPIC
                                     );
    $POST->{'TOPIC_ID'} = $obj->{'.topic_id'};

    $obj->{'post_id'}   = $db->insert( TABLE    => 'forum_posts',
                                       DBID     => 'f'.$obj->{'.forum_id'},
                                       ID       => $obj->{'.topic_id'},
                                       VALUES   => $POST
                                     );
                                     
    # Add to our preview table if preview posts is on
    
    if ($obj->{preview}) {
        my $type = $iB::IN{'CODE'} eq '01' ? 'new' : 'rep';
        $db->insert(  TABLE     => 'mod_posts',
                      VALUES    => { AUTHOR      => $POST->{'AUTHOR'},
                                     IP_ADDR     => $iB::IN{'IP_ADDRESS'},
                                     POST_DATE   => $POST->{'POST_DATE'},
                                     POST        => $POST->{'POST'},
                                     AUTHOR_TYPE => $POST->{'AUTHOR_TYPE'},
                                     TOPIC_ID    => $obj->{'.topic_id'},
                                     FORUM_ID    => $obj->{'.forum_id'},
                                     TYPE        => $type,
                                     POST_ID     => $obj->{'post_id'},
                                     ATTACH_ID   => $POST->{'ATTACH_ID'}
                                   },
                   );
    } else {

        $obj->check_email_replies( DB    => $db,
                                   TOPIC => \%TOPIC,
                                   POST  => $POST
                                 );
        $s_log->compile_entry(     DB    => $db,
                                   TOPIC => \%TOPIC,
                                   FORUM => $obj->{'FORUM'},
                                   POST  => $POST
                             );
    
    
        $obj->{'FORUM'}->{'L_TOPIC_TITLE'} = $TOPIC{'TOPIC_TITLE'};
        $obj->{'FORUM'}->{'L_TOPIC_ID'}    = $TOPIC{'TOPIC_ID'};
        $obj->{'TOPIC'}->{'TOPIC_TITLE'}   = $TOPIC{'TOPIC_TITLE'};
        $obj->UpdateBoardStats($db, 'New');
    
        # Is this the news forum?
        
        if ( defined $iB::INFO->{'NEWS_FORUM'} and ($iB::INFO->{'NEWS_FORUM'} == $obj->{'FORUM'}->{'FORUM_ID'}) ) {
        
            require SSI::Parser;
    
            SSI::Parser::parse( DB       => $db,
                                TEMPLATE => 'news',
                             );
        }
    }
    
    if ($obj->{preview} && $obj->{'_pkg'} ne 'iPoll') {
        $output->redirect_screen( TEXT => $Post::lang->{'moderate_topic'}, URL => "act=SF;f=$iB::IN{'f'}" );
    } else {
        $obj->{'_pkg'} eq 'iPoll' ? return $obj->{'.topic_id'}
                                  : $output->pure_redirect( URL => "act=ST;f=$iB::IN{'f'};t=$obj->{'.topic_id'}");
    }
}







####################################################################################
#
#                 >> Reply Post
#
###################################################################################

sub ReplyPostForm {
    my ($obj, $db, $POST) = @_;
    $obj->CompileHTML('reply', $POST);
    $obj->do_topic_summary($db);
    $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::" . $Post::lang->{'replying_in'} .' '. $obj->{'TOPIC'}->{'TOPIC_TITLE'}
                            );
}


sub ReplyPost {
    my ($obj, $db) = @_;
    my $POST = $obj->CompilePost($db);
    
    if (defined $obj->{'SAVED'}) {
        $obj->{'SAVED'}->{'DATE'} = $std->get_date( TIME => $iB::IN{'QDate'}, METHOD => 'LONG');
        my $html = iTextparser::do_wrapper({STYLE => "QUOTE", EXTRA => "($obj->{'SAVED'}->{'AUTHOR'}->{'MEMBER_NAME'} \@ $obj->{'SAVED'}->{'DATE'})" });
        $POST->{'POST'} = qq!<\!--QuoteBegin--$obj->{'SAVED'}->{'AUTHOR'}->{'MEMBER_NAME'}+$obj->{'SAVED'}->{'DATE'}-->$html->{START}<\!--QuoteEBegin-->!
                         . $txt->Convert_for_db( TEXT    => $obj->{'SAVED'}->{'POST'},
                                                 SMILIES => $POST->{'ENABLE_EMO'},
                                                 IB_CODE => $obj->{'FORUM'}->{'FORUM_IBC'},
                                                 HTML    => $obj->{'FORUM'}->{'FORUM_HTML'}
                                                )
                         . qq!<\!--QuoteEnd-->$html->{END}<\!--QuoteEEnd--><br>$POST->{'POST'}!;
    }

    if ($txt->{'ERROR'}) {
        $POST->{'_ERROR'} = $Post::lang->{$txt->{'ERROR'}};
        $obj->ReplyPostForm($db, $POST)
    }

    $iB::IN{'preview'} ? $obj->ReplyPostForm($db, $POST) : $obj->_do_reply($db, $POST);
}


sub _do_reply {
    my ($obj, $db, $POST) = @_;
    
    $obj->{'post_id'}   = $db->insert( TABLE    => 'forum_posts',
                                       DBID     => 'f'.$obj->{'.forum_id'},
                                       ID       => $obj->{'.topic_id'},
                                       VALUES   => $POST
                                     );
                                     
    # Add to our preview table if preview posts is on
    
    if ($obj->{preview}) {
        my $type = $iB::IN{'CODE'} eq '01' ? 'new' : 'rep';
        $db->insert(  TABLE     => 'mod_posts',
                      VALUES    => { AUTHOR      => $POST->{'AUTHOR'},
                                     IP_ADDR     => $iB::IN{'IP_ADDRESS'},
                                     POST_DATE   => $POST->{'POST_DATE'},
                                     POST        => $POST->{'POST'},
                                     AUTHOR_TYPE => $POST->{'AUTHOR_TYPE'},
                                     TOPIC_ID    => $obj->{'.topic_id'},
                                     FORUM_ID    => $obj->{'.forum_id'},
                                     TYPE        => $type,
                                     POST_ID     => $obj->{'post_id'},
                                     ATTACH_ID   => $POST->{'ATTACH_ID'}
                                   },
                   );
    } else {
        $obj->{'TOPIC'}->{'TOPIC_POSTS'}++;
        $obj->{'TOPIC'}->{'TOPIC_LAST_POSTER'} = $obj->{'.g_post'} == 0 ? $obj->{'MEMBER'}->{'MEMBER_ID'} : 0;
        $obj->{'TOPIC'}->{'TOPIC_LASTP_N'}     = $obj->{'.g_post'} == 0 ? $obj->{'MEMBER'}->{'MEMBER_NAME'} : $iB::IN{'UserName'};
        $obj->{'TOPIC'}->{'TOPIC_LAST_DATE'}   = time;
        $obj->{'FORUM'}->{'L_TOPIC_TITLE'}     = $obj->{'TOPIC'}->{'TOPIC_TITLE'};
        $obj->{'FORUM'}->{'L_TOPIC_ID'}        = $obj->{'TOPIC'}->{'TOPIC_ID'};

        $obj->check_email_replies( DB    => $db,
                                   TOPIC => $obj->{'TOPIC'},
                                   POST  => $POST
                                 );
        $s_log->compile_entry(     DB    => $db,
                                   TOPIC => $obj->{'TOPIC'},
                                   FORUM => $obj->{'FORUM'},
                                   POST  => $POST
                             );
    
        $db->update( TABLE    => 'forum_topics',
                     ID       => $obj->{'.forum_id'},
                     KEY      => $obj->{'.topic_id'},
                     VALUES   => $obj->{'TOPIC'}
                   ); 
    
        $obj->UpdateBoardStats($db, 'Reply');
        
         # Is this the news forum?
        
        if ( defined $iB::INFO->{'NEWS_FORUM'} and ($iB::INFO->{'NEWS_FORUM'} == $obj->{'FORUM'}->{'FORUM_ID'}) ) {
        
            require SSI::Parser;
    
            SSI::Parser::parse( DB       => $db,
                                TEMPLATE => 'news',
                             );
        }
    }
    
    my $Pages = $obj->{'TOPIC'}->{'TOPIC_POSTS'} / $iB::INFO->{'DISPLAY_MAX_POSTS'};
    my ($Int, $Dec) = split /\./,$Pages;
    $Pages  = $Int * $iB::INFO->{'DISPLAY_MAX_POSTS'};
    if ($obj->{preview}) {
        $output->redirect_screen( TEXT => $Post::lang->{'moderate_post'}, URL => "act=ST;f=$iB::IN{'f'};t=$obj->{'.topic_id'};st=$Pages");
    } else {
        $output->pure_redirect(  URL   => "act=ST;f=$iB::IN{'f'};t=$obj->{'.topic_id'};st=$Pages" );
    }
}


sub ReplyQuoteForm {
    my ($obj, $db) = @_;
    $obj->GetPost($db);
    $obj->CompileHTML('replyquote');
    $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::" . $Post::lang->{'quoting_post'} . $obj->{'TOPIC'}->{'TOPIC_TITLE'}
                            );
}


sub ReplyQuote {
    my ($obj, $db) = @_;
    $obj->{'SAVED'}->{'AUTHOR'} = $mem->LoadMember( DB     => $db,
                                                    KEY    => $iB::IN{'QAuthor'},
                                                    METHOD => 'by id'
                                                  );
    $obj->{'SAVED'}->{'DATE'}   = $std->GetDate($iB::IN{'QDate'});
    $obj->{'SAVED'}->{'POST'}   = $iB::IN{'QPost'};
    $obj->ReplyPost($db);
}


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

    $obj->{'.html'} .= PostView::TopicSummary_top();

    my $posts = $db->query( TABLE    => 'forum_posts',
                            DBID     => 'f'.$obj->{'.forum_id'},
                            ID       => $obj->{'.topic_id'},
                            WHERE    => "FORUM_ID == $obj->{'.forum_id'} and TOPIC_ID == $obj->{'.topic_id'}",
                            RANGE    => "0 to 10",
                            SORT_KEY => 'POST_DATE',
                            SORT_BY  => 'Z-A',
                            MATCH    => 'ALL',
                          );


    for my $Row (@{$posts}) {
       
        $Row->{'POSTER'} = $Row->{'AUTHOR_TYPE'} == 1 ? $mem->LoadMember( DB => $db, KEY => $Row->{'AUTHOR'},METHOD => 'by id')
                                                      : $mem->SetUpGuest($Row->{'AUTHOR'});
       
        $Row->{'POST_BACK_COL'} = $iB::SKIN->{'POST_COL_ONE'};
        
        $Row->{'POST_DATE'} = $std->get_date( TIME => $Row->{'POST_DATE'}, METHOD => 'LONG' );
        
        $obj->{'.html'} .= PostView::TopicSummary_body($Row);
        
    }

  
    $obj->{'.html'} .= PostView::TopicSummary_bottom();
}








####################################################################################
#
#                 >> EDIT
#
####################################################################################

sub EditForm {
    my ($obj, $db, $POST) = @_;
    $obj->GetPost($db);
    my $post = $POST || $obj->{'SAVED'};
    $obj->CompileHTML('edit', $post);
    $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::" . $Post::lang->{'editing_post'} . $obj->{'TOPIC'}->{'TOPIC_TITLE'}
                            );
}


sub DoEdit {
    my ($obj, $db) = @_;
    $iB::IN{'enablesig'} = $iB::IN{'enablesig'} eq 'yes' ? 1 : 0;
    $iB::IN{'enableemo'} = $iB::IN{'enableemo'} eq 'yes' ? 1 : 0;

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

    $obj->GetPost($db);

    unless (($iB::IN{'Post'}) and (length $iB::IN{'Post'} >= 2)) {
        $obj->{'SAVED'}->{'_ERROR'} = $Post::lang->{'no_post'};
        $obj->EditForm($db, $obj->{'SAVED'});
    }
    
    if ($txt->{'ERROR'}) {
        $obj->{'SAVED'}->{'_ERROR'} = $Post::lang->{$txt->{'ERROR'}};
        $obj->EditForm($db, $obj->{'SAVED'});
    }

    $obj->{'SAVED'}->{'ENABLE_SIG'}   = $iB::IN{'enablesig'};
    $obj->{'SAVED'}->{'ENABLE_EMO'}   = $iB::IN{'enableemo'};
    $obj->{'SAVED'}->{'POST'}         = $iB::IN{'Post'};

    $iB::IN{'preview'} ? $obj->EditForm($db, $obj->{'SAVED'}) : $obj->_do_edit($db);
}


sub _do_edit {
    my ($obj, $db) = @_;
    my $time = $std->get_date( TIME => time, METHOD => 'LONG');

    unless ( $iB::MEMBER_GROUP->{'IS_SUPMOD'}
               or $obj->{'.active_mod'}->{'EDIT_POST'}
               or ($obj->{'SAVED'}->{'AUTHOR'} eq $obj->{'MEMBER'}->{'MEMBER_ID'} and $iB::MEMBER_GROUP->{'EDIT_OWN_POSTS'})
           )
        {
 
            $std->Error( DB      => $db,
                         LEVEL   => 1,
                         MESSAGE => 'not_op'
                       );
        }



    $obj->{'SAVED'}->{'POST'}  = $txt->Convert_for_db( TEXT    => $iB::IN{'Post'},
                                                       SMILIES => $iB::IN{'enableemo'},
                                                       IB_CODE => $obj->{'FORUM'}->{'FORUM_IBC'},
                                                       HTML    => $obj->{'FORUM'}->{'FORUM_HTML'}
                                                     );
                                                     
    if ($iB::MEMBER_GROUP->{'APPEND_EDIT'}) {
        $obj->{'SAVED'}->{'POST'} .= qq[\n\n\<br><br><!--EDIT|$obj->{'MEMBER'}->{'MEMBER_NAME'}|$time-->];
    }
                                                     
    $obj->{'SAVED'}->{'POST_ICON'}    = $std->IsNumber($iB::IN{'iconid'}) || 0;

    $db->update( TABLE     => 'forum_posts',
                 DBID      => 'f'.$obj->{'.forum_id'},
                 ID        => $obj->{'.topic_id'},
                 KEY       => $obj->{'.post_id'},
                 VALUES    => $obj->{'SAVED'}
               );
               
    # Is this the news forum?
	
	if ( defined $iB::INFO->{'NEWS_FORUM'} and ($iB::INFO->{'NEWS_FORUM'} == $obj->{'FORUM'}->{'FORUM_ID'}) ) {
	
	    require SSI::Parser;

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

    $output->redirect_screen( TEXT => $Post::lang->{'post_edited'}, URL => "act=ST;f=$iB::IN{'f'};t=$iB::IN{'t'};st=$iB::IN{'st'}");
}









####################################################################################
#
#                 >> HTML Compiler
#
####################################################################################

sub CompileHTML ($$$) {
    my ($obj, $type, $post) = @_;
    #$iB::IN{'enablesig'} = $iB::IN{'enablesig'} eq 'yes' ? 1 : 0;
    #$iB::IN{'enableemo'} = $iB::IN{'enableemo'} eq 'yes' ? 1 : 0;
    my $in_post = $txt->Convert_for_db( TEXT    => $iB::IN{'Post'},
                                        SMILIES => $iB::IN{'enableemo'},
                                        IB_CODE => $obj->{'FORUM'}->{'FORUM_IBC'},
                                        HTML    => $obj->{'FORUM'}->{'FORUM_HTML'}
                                      ) if $post->{'POST'};

    my $real_post = $txt->Convert_for_textfield($post->{'POST'}) if $post->{'POST'};

    my $topic_title = $iB::IN{'TopicTitle'};
    my $topic_desc  = $iB::IN{'TopicDesc'};

    if ($type eq 'poll') {
        my $vote = $iB::CGI->param('PollAnswers');
        $obj->{'.html'}  = PostView::errors($post->{'_ERROR'})  if $post->{'_ERROR'};
        unless ($post->{'_ERROR'}) {
            if ($in_post) {
                $obj->{'.html'}  = PostView::preview($in_post);
            }
        }
        $obj->{'.html'} .= $obj->_headers('poll');
        $obj->{'.html'} .= PostView::table_top("$Post::lang->{'top_txt_poll'} $obj->{'FORUM'}->{'FORUM_NAME'}");
        $obj->{'.html'} .= $obj->_name_field();
        $obj->{'.html'} .= PostView::topictitle_fields( {
                                                           TITLE => $topic_title,
                                                           DESC  => $topic_desc
                                                        }
                                                      );

        $obj->{'.html'} .= PostView::poll_box($vote);
        $obj->{'.html'} .= $obj->_post_body($real_post);
        if ($obj->{'_CAN_UPLOAD'}) {
        	$obj->{'.html'} .= PostView::Upload_field($iB::MEMBER_GROUP->{'ATTACH_MAX'}*1024);
        }
        $obj->{'.html'} .= PostView::EndForm($Post::lang->{'submit_poll'});
        $obj->{'.html'} .= $obj->Stats();

    } elsif ($type eq 'new') {
        $obj->{'.html'}  = PostView::errors($post->{'_ERROR'})  if $post->{'_ERROR'};
        unless ($post->{'_ERROR'}) {
            if ($in_post) {
                $obj->{'.html'}  = PostView::preview($in_post);
            }
        }
        $obj->{'.html'} .= $obj->_headers('new');
        $obj->{'.html'} .= PostView::table_top("$Post::lang->{'top_txt_new'} $obj->{'FORUM'}->{'FORUM_NAME'}");
        $obj->{'.html'} .= $obj->_name_field();
        $obj->{'.html'} .= PostView::topictitle_fields( {
                                                           TITLE => $topic_title,
                                                           DESC  => $topic_desc
                                                        }
                                                      );
        $obj->{'.html'} .= $obj->_post_body($real_post);
        if ($obj->{'_CAN_UPLOAD'}) {
        	$obj->{'.html'} .= PostView::Upload_field($iB::MEMBER_GROUP->{'ATTACH_MAX'}*1024);
        }
        $obj->{'.html'} .= PostView::EndForm($Post::lang->{'submit_new'});
        $obj->{'.html'} .= $obj->Stats();

    } elsif ($type eq 'reply') {
        $obj->{'.html'}  = PostView::errors($post->{'_ERROR'})  if $post->{'_ERROR'};
        unless ($post->{'_ERROR'}) {
            if ($in_post) {
                $obj->{'.html'}  = PostView::preview($in_post);
            }
        }
        $obj->{'.html'} .= $obj->_headers('reply');
        $obj->{'.html'} .= PostView::table_top("$Post::lang->{'top_txt_reply'} $obj->{'TOPIC'}->{'TOPIC_TITLE'} -&gt; $obj->{'FORUM'}->{'FORUM_NAME'}");
        $obj->{'.html'} .= $obj->_name_field();
        $obj->{'.html'} .= $obj->_post_body($real_post);
        if ($obj->{'_CAN_UPLOAD'}) {
        	$obj->{'.html'} .= PostView::Upload_field($iB::MEMBER_GROUP->{'ATTACH_MAX'}*1024);
        }
        $obj->{'.html'} .= PostView::EndForm($Post::lang->{'submit_reply'});
        $obj->{'.html'} .= $obj->Stats();;

    } elsif ($type eq 'replyquote') {

        $obj->{'.html'}  = $obj->_headers('replyquote');
        $obj->{'.html'} .= PostView::table_top("$Post::lang->{'top_txt_reply'} $obj->{'TOPIC'}->{'TOPIC_TITLE'} -&gt; $obj->{'FORUM'}->{'FORUM_NAME'}");
        $obj->{'.html'} .= $obj->_name_field();
        $obj->{'.html'} .= $obj->_post_body();
        $obj->{'.html'} .= PostView::quote_box($obj->{'SAVED'});
        if ($obj->{'_CAN_UPLOAD'}) {
        	$obj->{'.html'} .= PostView::Upload_field($iB::MEMBER_GROUP->{'ATTACH_MAX'}*1024);
        }
        $obj->{'.html'} .= PostView::EndForm($Post::lang->{'submit_reply'});
        $obj->{'.html'} .= $obj->Stats();

    } elsif ($type eq 'edit') {
        $obj->{'.html'}  = PostView::errors($post->{'_ERROR'})  if $post->{'_ERROR'};
        unless ($post->{'_ERROR'}) {
            if ($in_post) {
                $obj->{'.html'}  = PostView::preview($in_post);
            }
        }
        $obj->{'.html'} .= $obj->_headers('edit');
        $obj->{'.html'} .= PostView::table_top("$Post::lang->{'top_txt_edit'} $obj->{'TOPIC'}->{'TOPIC_TITLE'} -&gt; $obj->{'FORUM'}->{'FORUM_NAME'}");
        $obj->{'.html'} .= $obj->_name_field();
        $obj->{'.html'} .= $obj->_post_body($real_post, $post->{POST_ICON});
        $obj->{'.html'} .= PostView::EndForm($Post::lang->{'submit_edit'});
        $obj->{'.html'} .= $obj->Stats();

    }

    my $smilies = qq~<tr align='center'>\n~;
    my $show_table = 0;
    my $cnt = 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_icon) = @_;
    $iB::IN{iconid} = $iB::IN{iconid} || $post_icon;
    $Post::lang->{'the_max_length'} = $iB::INFO->{'MAX_POST_LENGTH'} * 1024;
    my $tmp_html = PostView::PostIcons() . PostView::postbox_buttons($extra) . PostView::CheckBoxes();
    # Check for current topic icon
    if (defined $iB::IN{iconid}) {
        $tmp_html =~ s#name=["']iconid["']\s*value=["']$iB::IN{iconid}\s?["']#name="iconid" value="$iB::IN{iconid}" checked#i;
        # Uncheck default topic icon
        $tmp_html =~ s#name=["']iconid["']\s*value=["']0["']\s*checked#name="iconid" value="0"#i;
    }
    return $tmp_html;
}


sub Stats {
    my $obj = shift;
    $Post::lang->{'ib_state'}        = $obj->{'FORUM'}->{'FORUM_IBC'}   ? $Post::lang->{'ib_on'}   : $Post::lang->{'ib_off'};
    $Post::lang->{'html_state'}      = $obj->{'FORUM'}->{'FORUM_HTML'}  ? $Post::lang->{'html_on'} : $Post::lang->{'html_off'};
    $Post::lang->{'stat_allow_img'} .= $iB::INFO->{'ALLOW_IMAGES'}  ? $Post::lang->{'enabled'} : $Post::lang->{'disabled'};
    $Post::lang->{'stat_max_img'}   .= $iB::INFO->{'MAX_IMAGES'}   || $Post::lang->{'unlimited'};
    $Post::lang->{'stat_flash'}     .= $iB::INFO->{'ALLOW_FLASH'}   ? $Post::lang->{'enabled'} : $Post::lang->{'disabled'};
    $Post::lang->{'stat_flash_w'}   .= $iB::INFO->{'MAX_W_FLASH'}  || $Post::lang->{'unlimited'};
    $Post::lang->{'stat_flash_h'}   .= $iB::INFO->{'MAX_H_FLASH'}  || $Post::lang->{'unlimited'};
    $Post::lang->{'stat_dyn_img'}   .= $iB::INFO->{'ALLOW_DYNAMIC_IMG'}  ? $Post::lang->{'enabled'} : $Post::lang->{'disabled'};
    $Post::lang->{'stat_max_emo'}   .= $iB::INFO->{'MAX_EMOS'}     || $Post::lang->{'unlimited'};        
    return PostView::post_stats();
}





sub _headers ($$) {
    my ($obj, $type) = @_;
    
    # Sort out the file uploads
   	my $form_extra;
    
	# Due a bug in some browsers won't allow
	# file upload fields, so..
	if ($ENV{'HTTP_USER_AGENT'} =~ /Mozilla\/(\d+)/) {
		my $moz_ver = $1;
		if ($moz_ver >= 4) {
			# Ok, we're using a compatible browser
			# Has the admin allowed us to upload?
			if ($obj->{'FORUM'}->{'ALLOW_ATTACH'} and $iB::MEMBER_GROUP->{'ATTACH_MAX'} > 0) {
				# Lets set a global flag to tell the rest of the
				# module to render a file upload field
				$obj->{'_CAN_UPLOAD'} = 1;
				$form_extra = ' enctype="multipart/form-data"';
			}
		}
	}
    
    my $return = qq[<form action="$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}" method="POST" name='REPLIER' onSubmit='return ValidateForm()'$form_extra>\n<input type='hidden' name='st' value='$iB::IN{'st'}'>];
    if ($type eq 'new') {
        $return .= qq[\n<input type='hidden' name='act' value='Post'>\n<input type='hidden' name='CODE' value='01'>\n<input type='hidden' name='s' value='$iB::SESSION'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>];
    
    } elsif ($type eq 'reply') {

        $return .= qq[\n<input type='hidden' name='act' value='Post'>\n<input type='hidden' name='CODE' value='03'>\n<input type='hidden' name='s' value='$iB::SESSION'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>];

    } elsif ($type eq 'replyquote') {

        $return .= qq[\n<input type='hidden' name='act' value='Post'>\n<input type='hidden' name='CODE' value='07'>\n<input type='hidden' name='s' value='$iB::SESSION'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>\n<input type='hidden' name='p' value='$obj->{'SAVED'}->{'POST_ID'}'>];
       
    } elsif ($type eq 'edit') {

        $return .= qq[\n<input type='hidden' name='act' value='Post'>\n<input type='hidden' name='CODE' value='09'>\n<input type='hidden' name='s' value='$iB::SESSION'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>\n<input type='hidden' name='t' value='$obj->{'TOPIC'}->{'TOPIC_ID'}'>\n<input type='hidden' name='p' value='$obj->{'SAVED'}->{'POST_ID'}'>];

    } elsif ($type eq 'poll') {

        $return .= qq[\n<input type='hidden' name='act' value='Poll'>\n<input type='hidden' name='s' value='$iB::SESSION'>\n<input type='hidden' name='CODE' value='00'>\n<input type='hidden' name='f' value='$obj->{'FORUM'}->{'FORUM_ID'}'>];

    }

    return $return;
}             

sub _name_field ($$) {
    my $obj = shift;
    return $iB::MEMBER->{'MEMBER_ID'} ? PostView::nameField_reg() : PostView::nameField_unreg( $iB::IN{'UserName'} );
}








####################################################################################
#
#                 >> Post Compiler
#
####################################################################################

sub CompilePost {
    my ($obj, $db) = @_;
    my %POST;
    $iB::IN{'enablesig'} = $iB::IN{'enablesig'} eq 'yes' ? 1 : 0;
    $iB::IN{'enableemo'} = $iB::IN{'enableemo'} eq 'yes' ? 1 : 0;
    
    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE =>'no_post'
               ) unless length ($iB::CGI->param('Post')) >= 2;

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE =>'incorrect_use'
               ) unless lc($ENV{'REQUEST_METHOD'}) eq 'post';

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE =>'post_too_long'
               ) if length ($iB::CGI->param('Post')) > $iB::INFO->{'MAX_POST_LENGTH'} * 1024;

    $POST{'AUTHOR'}       = $obj->{'.g_post'} == 0 ? $obj->{'MEMBER'}->{'MEMBER_ID'} : $iB::IN{'UserName'};
    $POST{'ENABLE_SIG'}   = $obj->{'.g_post'} == 0 ? $iB::IN{'enablesig'} : 0;
    $POST{'ENABLE_EMO'}   = $iB::IN{'enableemo'};
    $POST{'IP_ADDR'}      = $iB::IN{'IP_ADDRESS'};
    $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'}  = $obj->{'.g_post'} == 0 ? 1 : 0;
    $POST{'TOPIC_ID'}     = $obj->{'.topic_id'};
    $POST{'FORUM_ID'}     = $obj->{'.forum_id'};
    $POST{'QUEUED'}       = $obj->{preview};
    
    # Test for new topic
    
    if ($iB::IN{CODE} eq '01') {
        unless (($iB::CGI->param('TopicTitle')) and (length $iB::CGI->param('TopicTitle') > 2)) {
            $POST{'_ERROR'} = $Post::lang->{'no_topic_title'};
            $obj->NewPostForm($db, \%POST);
        }
    
        unless (length($iB::CGI->param('TopicTitle')) < 51) {
            $POST{'_ERROR'} = $Post::lang->{'topic_title_long'};
            $obj->NewPostForm($db, \%POST);
        }
    } 

    # Attachements
    
    if ($obj->{'FORUM'}->{'ALLOW_ATTACH'} and $iB::MEMBER_GROUP->{'ATTACH_MAX'} > 0 and $iB::IN{'FILE_UPLOAD'} ne '') {
        chmod(0777, $iB::INFO->{'DB_DIR'}.'Temp');
    	# Ignore and skip to the end if we're previewing
    	goto "SKIPPED" if $iB::IN{'preview'};
    	# We must have a file to upload and
    	# we're allowed to do so.
    	
    	# Require the mime types file
    	require 'MimeTypes.cfg';
    	my $mime = MimeTypes->new();
    	
    	# Require the File::copy module
    	use File::Copy;
    	
		my $file_name        = undef;
	    
  		my $file_to_attach  = $iB::CGI->param('FILE_UPLOAD');
    	my $mime_type       = $iB::CGI->uploadInfo($file_to_attach)->{'Content-Type'};
    	my $tmp_attach_file = $iB::CGI->tmpFileName($file_to_attach);
    	

    	unless ($mime->{ $mime_type }[0]) {
      		close ($file_to_attach) if ($file_to_attach);
      		$txt->{'ERROR'} = "invalid_mime_type";
      		goto "SKIPPED";
    	}
    	
    	my ($file_size) = (stat ($tmp_attach_file))[7];

		if ($file_size > ($iB::MEMBER_GROUP->{'ATTACH_MAX'} * 1024)) {
		   close ($file_to_attach) if ($file_to_attach);
		   $txt->{'ERROR'} = "upload_to_big";
		   goto "SKIPPED";
		}

		$file_to_attach =~ /([^\\\/\:]+)$/;
		$file_name = $1;
		$file_name =~ s/[^\w\.]/\_/g;
		
		$file_name = "post-$iB::IN{f}-".substr(time, 5,10)."-".$file_name;
		
		# Make perl/php scripts safe
		
		if ( ($file_name =~ /\.(cgi|pl|js|asp)$/i) or ($file_name =~ /\.php\d{0,2}$/i) ) {
			$file_name =~ s!\.!-!g;
			$file_name .= '.txt';
		}
		
		my $id = $db->insert( TABLE  => 'attachments',
							  VALUES => { MIME_TYPE => $mime_type,
										  FILE_NAME => $file_name,
										}
							);
		
		# Add it to the post DB
		$POST{'ATTACH_ID'}   = $id;
		$POST{'ATTACH_HITS'} = 0;
		$POST{'ATTACH_TYPE'} = $mime_type;
		
		# 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!/$!;
        
		# Move it to the public upload path
		chmod(0777, $iB::INFO->{'PUBLIC_UPLOAD'});
		my $new_file = $iB::INFO->{'PUBLIC_UPLOAD'}."$file_name";
		my ($buffer, $bytes_read, $size);
		open(OUTFILE, ">$new_file") or die "Cannot upload to $iB::INFO->{'PUBLIC_UPLOAD'}$file_name ($@)";
		binmode(OUTFILE);
		while ($bytes_read = read($file_to_attach, $buffer, 2096)) {
		    $size += $bytes_read;
			print OUTFILE $buffer; 
		}
		close (OUTFILE);
		
		chmod(0777, $new_file);
		
		# Double check the file size incase a race condition occurs
		
		$file_size = (stat ($new_file))[7];

		if ($file_size > ($iB::MEMBER_GROUP->{'ATTACH_MAX'} * 1024)) {
		   close ($file_to_attach) if ($file_to_attach);
		   unlink $new_file;
		   $txt->{'ERROR'} = "upload_to_big";
		   goto "SKIPPED";
		}
	}
	
SKIPPED:

    $obj->update_member($db) if $obj->{'.g_post'} != 1;
    
    return \%POST;
}








####################################################################################
#
#                 >> Board Stats Update 
#
####################################################################################

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

    my $stats = {};

    push @{$iB::COOKIES_OUT}, $iB::CGI->cookie( -name   => $iB::INFO->{'COOKIE_ID'}.'LPid', -value => time, -expires => '+1d', -path => $iB::INFO->{'COOKIE_PATH'},
												-domain => $iB::INFO->{'COOKIE_DOMAIN'} );
												
	# Return if moderation is on..
	return if $obj->{preview};

    $Type eq 'New' ? eval { ++$obj->{'FORUM'}->{'FORUM_TOPICS'}; $stats->{'TOTAL_TOPICS'}  = '+1'; }
                   : eval { ++$obj->{'FORUM'}->{'FORUM_POSTS'};  $stats->{'TOTAL_REPLIES'} = '+1'; };

    if (length($obj->{'FORUM'}->{'L_TOPIC_TITLE'}) > 20) {
        $obj->{'FORUM'}->{'L_TOPIC_TITLE'}       = $std->htmlcut($obj->{'FORUM'}->{'L_TOPIC_TITLE'},22,29) . '...';
    }
    $obj->{'FORUM'}->{'FORUM_LAST_POST'}     = time;
    $obj->{'FORUM'}->{'FORUM_LAST_POSTER_N'} = $obj->{'.g_post'} == 0 ? $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 => { L_TOPIC_TITLE       =>  $obj->{'FORUM'}->{'L_TOPIC_TITLE'}      ,
                             L_TOPIC_ID          =>  $obj->{'FORUM'}->{'L_TOPIC_ID'}         ,
                             FORUM_LAST_POSTER   =>  $obj->{'FORUM'}->{'FORUM_LAST_POSTER'}  ,
                             FORUM_LAST_POSTER_N =>  $obj->{'FORUM'}->{'FORUM_LAST_POSTER_N'},
                             FORUM_LAST_POST     =>  $obj->{'FORUM'}->{'FORUM_LAST_POST'}    ,
                             FORUM_TOPICS        =>  $obj->{'FORUM'}->{'FORUM_TOPICS'}       ,
                             FORUM_POSTS         =>  $obj->{'FORUM'}->{'FORUM_POSTS'}
                           }
               ) || die $db->{'error'};
	
	# Save new stats
    $std->ib_stats($stats);
    
    if ($iB::INFO->{'USE_SSI'}) {
        require SSI::Parser;
        # Load new stats
       	my $s = $std->ib_stats;
       	
        SSI::Parser::parse( DB       => $db,
                            TEMPLATE => 'POST_TOTALS',
                            VALUES   => { "total topics"  => $s->{'TOTAL_TOPICS'},
                                          "total replies" => $s->{'TOTAL_REPLIES'},
                                          "total posts"   => $s->{'TOTAL_TOPICS'} + $s->{'TOTAL_REPLIES'} || 0
                                        }
                          );
                          
        SSI::Parser::parse( DB       => $db,
                            TEMPLATE => 'LAST_POSTED',
                            VALUES   => { "url to topic"  => qq[$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}],
                                          "topic title"   => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                                          "topic poster"  => $obj->{'FORUM'}->{'FORUM_LAST_POSTER_N'}
                                        }
                          );
	}
}


sub update_member {
    my ($obj, $db) = @_;
    $std->cgi_error("No member to update") unless $obj->{'MEMBER'}->{'MEMBER_ID'};
    return if $txt->{'ERROR'} ne '';
	return if $obj->{preview};
    return if $iB::IN{'preview'};
    return if $iB::IN{'CODE'} eq '09';
    $obj->{'MEMBER'}->{'MEMBER_POSTS'}++;
    $obj->{'MEMBER'}->{'LAST_POST'} = $obj->{'.forum_id'}.'-'.$obj->{'.topic_id'}.'-'.time;
    $mem->UpdateMember( DB       => $db,
                        MEMBER   => $obj->{'MEMBER'}
                      );
    $obj->{'LAST_TOPIC'}     = $obj->{'TOPIC'}->{'TOPIC_TITLE'};
}






####################################################################################
#
#                 >> Flood Control 
#
####################################################################################

sub check_last_post {
    my ($obj, $db) = @_;
    return unless $iB::INFO->{'FLOOD_CONTROL'};
    return if $iB::MEMBER_GROUP->{'AVOID_FLOOD'};
    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'flood_control',
                 EXTRA   => $iB::INFO->{'FLOOD_CONTROL'}
               ) if ( ($iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'LPid'} + $iB::INFO->{'FLOOD_CONTROL'}) > time );
}



####################################################################################
#
#                 >> Topic Subscriptions 
#
####################################################################################

sub check_email_replies {
    my $obj = shift;

    my $IN  = { DB      => "",
                TOPIC   => "",
                POST    => "",
                @_,
              };
           
    # Return if we are moderating all new posts/topics   
    return if $obj->{preview};
   
    my $db    = $IN->{'DB'};

    my $query = $iB::MEMBER->{'MEMBER_ID'} ?  " and MEMBER_ID ne '$obj->{'MEMBER'}->{'MEMBER_ID'}'" : '';

    my $subs = $db->query(  TABLE    => 'forum_subscriptions',
                            WHERE    => "FORUM_ID == $obj->{'.forum_id'} and TOPIC_ID == $obj->{'.topic_id'}$query",
                         );
                         

    return unless scalar @{$subs} > 0;

    my $the_poster = $iB::MEMBER->{'MEMBER_NAME'} || $iB::IN{'UserName'};

    my $with    = $mail->parse_template( ID      => 'SUBS',
                                         DB      => $db,
                                         VALUES  =>
                                          { 
                                            'POSTER_NAME' => $the_poster,
                                            'FORUM_NAME'  => $obj->{'FORUM'}->{'FORUM_NAME'},
                                            'TOPIC_TITLE' => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                                            'THE_POST'    => $IN->{'POST'}->{'POST'},
                                            'URL'         => qq[$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}]
                                           }
                                        );

    my $without = $mail->parse_template( ID      => 'SUBS',
                                         DB      => $db,
                                         VALUES  =>
                                          { 
                                            'POSTER_NAME' => $the_poster,
                                            'FORUM_NAME'  => $obj->{'FORUM'}->{'FORUM_NAME'},
                                            'TOPIC_TITLE' => $obj->{'TOPIC'}->{'TOPIC_TITLE'},
                                            'THE_POST'    => '',
                                            'URL'         => qq[$iB::INFO->{'BOARD_URL'}/ikonboard.$iB::INFO->{'CGI_EXT'}?act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}]
                                           }
                                        );

    my %seen;

    for my $Row (@{$subs}) {
        next unless ($Row->{'DATE_STARTED'} > time - ($Row->{'PRUNE'} * 3600 * 7));
        next unless $Row->{'EMAIL_ADDRESS'};
        #Remove multiple emails to one address
        next if exists $seen{ $Row->{'EMAIL_ADDRESS'} };
        $seen{ $Row->{'EMAIL_ADDRESS'} } = 1;
        my $message = $Row->{'rFULL'} ? $with : $without;
        $mail->Send( TO      => $Row->{'EMAIL_ADDRESS'},
                     FROM    => '',
                     SUBJECT => $Post::lang->{'email_title'},
                     MESSAGE => $message
                   );
        
        }
       
}




####################################################################################
#
#                 >> Misc Subroutines 
#
####################################################################################

sub Process {
    my ($obj, $db) = @_;
    $std->Error( DB => $db, LEVEL => '1', MESSAGE => 'Wha.....?') unless (defined $iB::IN{'CODE'}) and (defined $iB::IN{'f'});
    $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->{'.html'}     = '';
    require $iB::SKIN->{'DIR'} . '/PostView.pm' or die $!;
    #+-----------------------------------------------------------------------------------
    $obj->{'.is_guest'} = $iB::MEMBER->{'MEMBER_ID'} ?  0 : 1;
    $obj->{'.g_post'}   = $iB::MEMBER->{'MEMBER_ID'} ?  0 : 1;
    #+-----------------------------------------------------------------------------------
    $obj->LoadForum($db);
    $obj->LoadTopic($db) if defined $iB::IN{'t'};
    $obj->SetSession($db);
    #+-----------------------------------------------------------------------------------
    my $CodeNo = $std->CheckCodeNo($iB::IN{'CODE'});
    my %Mode = ( '00'     => \&NewPostForm,
                 '01'     => \&NewPost,
                 '02'     => \&ReplyPostForm,
                 '03'     => \&ReplyPost,
                 '06'     => \&ReplyQuoteForm,
                 '07'     => \&ReplyQuote,  
                 '08'     => \&EditForm,
                 '09'     => \&DoEdit
               );
    $Mode{$CodeNo} ? $Mode{$CodeNo}->($obj,$db) : PostError();
} 

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

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

    if ($obj->{'FORUM'}->{'FORUM_PROTECT'} eq 'group') {
        my @group_ids = split ",",$obj->{'FORUM'}->{'FORUM_PROTECT_T'};
        $obj->{'FORUM'}->{'FORUM_PROTECT_T'} = \@group_ids;
    }

    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'forum_off'
               ) unless $obj->{'FORUM'}->{'FORUM_STATUS'};
    $std->Error( DB      => $db,
                 LEVEL   => 2,
                 MESSAGE =>'forum_no_access'
               ) if $obj->{'FORUM'}->{'FORUM_PROTECT'} and $iB::MEMBER->{'MEMBER_ID'} eq '';

}

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

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

    $obj->{'TOPIC'} = $db->select( TABLE  => 'forum_topics',
                                   ID     => $obj->{'.forum_id'},
                                   KEY    => $obj->{'.topic_id'}
                                 ) || die $db->{'error'};
    
    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'locked_topic'
               ) unless $obj->{'TOPIC'}->{'TOPIC_STATE'} eq 'open' or $iB::MEMBER->{'MEMBER_GROUP'} == $iB::INFO->{'SUPAD_GROUP'};
    $std->Error( DB      => $db,
                 LEVEL   => 1,
                 MESSAGE => 'no_poll_reply'
               ) if $obj->{'TOPIC'}->{'POLL_STATE'}  eq 'closed';
}

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

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'}
                                 ) || die $db->{'error'};

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

}

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

sub SetSession {
    my ($obj, $db) = @_;
    
    # Set up the preview posting stuff.
    
    $obj->{preview} = $obj->{'FORUM'}->{'MODERATE'} ? 1 : 0;
    # If we can avoid the moderators queue..
    $obj->{preview} = 0 if $iB::MEMBER_GROUP->{'AVOID_Q'};

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

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

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

    $obj->check_last_post($db) unless $iB::IN{'CODE'} eq '08' or $iB::IN{'CODE'} eq '09';

    if ($iB::IN{'CODE'} eq '00' or $iB::IN{'CODE'} eq '01') {
        # Check for mem_group permission
        unless ($iB::MEMBER_GROUP->{'POST_NEW_TOPICS'}) {
            $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'no_starting');
        }
        # Check forum permissions
        if ($obj->{'FORUM'}->{'FORUM_START_THREADS'} ne '*') {
            unless (grep { $_ == $iB::MEMBER->{'MEMBER_GROUP'} } (split (/,/, $obj->{'FORUM'}->{'FORUM_START_THREADS'}) )) {
                $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'no_starting');
            }
        }
    }

    if ($iB::IN{'CODE'} eq '02' or $iB::IN{'CODE'} eq '03' or $iB::IN{'CODE'} eq '06'or $iB::IN{'CODE'} eq '07') {
        # Check if we can reply
        # 1: Is it a topic we started?
        if ($obj->{'TOPIC'}->{'TOPIC_STARTER'} eq $iB::MEMBER->{'MEMBER_ID'}) {
            $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'no_replies') unless $iB::MEMBER_GROUP->{'REPLY_OWN_TOPICS'};
        }
        # 2: Is it someone elses topic?
        if ($obj->{'TOPIC'}->{'TOPIC_STARTER'} ne $iB::MEMBER->{'MEMBER_ID'}) {
            $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'no_replies') unless $iB::MEMBER_GROUP->{'REPLY_OTHER_TOPICS'};
        }
        # 3: Is it allowed for us at all in the forum?      
        if ($obj->{'FORUM'}->{'FORUM_REPLY_THREADS'} ne '*') {
            unless (grep { $_ == $iB::MEMBER->{'MEMBER_GROUP'} } (split (/,/, $obj->{'FORUM'}->{'FORUM_REPLY_THREADS'}) )) {
                $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'no_replies');
            }
        }
        if ($obj->{'TOPIC'}->{'TOPIC_STATE'} ne 'open') {
            $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'locked_topic');
        }
    }

    if ($obj->{'FORUM'}->{'FORUM_PROTECT'}) {
        if (exists $iB::COOKIES->{ $iB::INFO->{'COOKIE_ID'}.'iBForum' . $obj->{'FORUM'}->{'FORUM_ID'} }) {
            return if $iB::COOKIES->{ $iB::INFO->{'COOKIE_ID'}.'iBForum' . $obj->{'FORUM'}->{'FORUM_ID'} } eq $obj->{'FORUM'}->{'FORUM_PROTECT'};
        }
        $output->redirect_screen( TEXT => "$Topic::lang->{'please_log_in'}", URL => "?act=SF;f=$iB::IN{'f'}");
        return 1;
    }


    if ($iB::IN{'CODE'} eq '01' || $iB::IN{'CODE'} eq '03' || $iB::IN{'CODE'} eq '07') {
        $std->Error( DB => $db, LEVEL=>'3', MESSAGE=>'guest_abuse') if (($iB::MEMBER->{'MEMBER_ID'} eq '') and ($iB::IN{'UserName'} eq ''));
    }
}

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

sub PostError  { my ($obj, $db) = @_; $std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'incorrect_use') }


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

1;
