<?_code
{
    use strict;
    use vars qw(%GET %POST %ML);

    # $_[1] is a pre-request scratch area
    # put variables here so that we can access them later
    # outside of this _code block
    my $title    = \$_[1]->{'title'};
    my $head     = \$_[1]->{'head'};
    my $body     = \$_[1]->{'body'};
    my $bodyopts = \$_[1]->{'bodyopts'};

    $$title = $ML{'.title'};

    # server down?
    if ($LJ::SERVER_DOWN) {
        $$body = LJ::server_down_html();
        return;
    }

    LJ::set_active_crumb("update");

    # invalid text input?
    unless (LJ::text_in(\%POST)) {
        BML::set_status(403); # 403 Forbidden
        $$body = "<?badinput?>";
        return;
    }

    # get remote and see if they can post right now
    my $remote = LJ::get_remote();

    # Errors that are unlikely to change between starting
    # to compose an entry and submitting it.
    if ($remote) {
        if ($remote->underage) {
            return BML::redirect("$LJ::SITEROOT/agecheck/?s=1");
        }

        if ($remote->identity) {
            BML::set_status(403); # 403 Forbidden
            $$title = "Sorry";
            $$body = "Non-$LJ::SITENAME users can't post, as they don't actually have journals here.  You can leave comments in other journals, though.";
            return;
        }

        if (! LJ::get_cap($remote, "can_post")) {
            BML::set_status(403); # 403 Forbidden
            $$title = "Can't Post";
            $$body = $LJ::MSG_NO_POST || $ML{'.error.cantpost'};
            return;
        }

        if (LJ::get_cap($remote, "disable_can_post")) {
            unless (LJ::run_hook("update.bml_disable_can_post", {
                title => $title, body => $body,
            })) {
                #BML::set_status(403); # 403 Forbidden
                $$title = $ML{'.error.disabled.title'};
                $$body = $ML{'.error.disabled'};
            }
            return;
        }
    }

    my %res = ();

    # see if we need to do any transformations
    LJ::run_hooks("transform_update_$POST{transform}", \%GET, \%POST) if $POST{transform};

    # Set up form default values:
    my @time = localtime(time);
    my ($year, $mon, $mday, $hour, $min) = ($time[5] + 1900, 
                                            sprintf("%02d", $time[4] + 1), 
                                            sprintf("%02d", $time[3]), 
                                            $time[2], 
                                            sprintf("%02d", $time[1]));
    my $subject = $POST{'subject'} || $GET{'subject'};
    my $event   = $POST{'event'}   || $GET{'event'};

    ### define some bools with common logic ###
    my $did_post = LJ::did_post() && !$POST{transform};                           # transforms aren't posts
    my $user_is_remote = $remote && $remote->{'user'} eq $POST{'user'};           # user is remote
    my $auth_as_remote = $remote && (! $GET{'altlogin'} || $user_is_remote);      # auth as remote
    my $auth_missing = $POST{'user'} &&
                       ! $POST{'password'} &&
                       ! $user_is_remote &&
                       ! $POST{'response'};                                       # user w/o password
    
    # which authentication option do we display by default?
    my $altlogin_display = 'none';
    my $remotelogin_display = 'none';
    if ($auth_as_remote) {
        $remotelogin_display = 'table-row';
    } else {
        $altlogin_display = 'table-row';
    }

    # Check for errors, store in hash to render later
    my $errors; my $onload = "shift_contents(); ";
    my $showform = $POST{'showform'} || $auth_missing;                            # show entry form
    my $preview = $POST{'action:preview'};

    # are we spellchecking before we post?
    my $did_spellcheck; my $spellcheck_html;
    if ($LJ::SPELLER && $POST{'action:spellcheck'}) {
        $did_spellcheck++;
        my $s = new LJ::SpellCheck { 'spellcommand' => $LJ::SPELLER,
                                     'color' => '<?hotcolor?>', };
        my $event = LJ::ehtml($event);
        $spellcheck_html = $s->check_html(\$event);
        $spellcheck_html = "<?inerr $ML{'entryform.spellcheck.noerrors'} inerr?>" unless $spellcheck_html ne "";
        $onload .= "pageload(0); "; # js fill-in off

        my $date = LJ::html_datetime_decode({ 'name' => "date_ymd", }, \%POST);
        ($year, $mon, $mday) = split( /\D/, $date);
        $hour = $POST{'hour'};
        $min  = $POST{'min'};
    } else {
        $onload .= "pageload(1); "; # js fill-in on

        my @time = localtime(time);
        $year = $time[5] + 1900;
        $mon = sprintf("%02d", $time[4] + 1);
        $mday = sprintf("%02d", $time[3]);
        $hour = $time[2];
        $min = sprintf("%02d", $time[1]);
    }

    # richtext
    # 'switched_rte_on' is only set when the user first enables rte.  We do this in a POST
    #    so any pre-existing text in the event and subject fields aren't lost when going to RTE.
    # 'rich' is used to keep RTE mode enabled between pages, such as spellchecks.
    # The $GET{'rich'} is simply for user bookmarking / faq linking convenience.
    my $enabled_rte = $POST{'switched_rte_on'};
    my $richtext = 1 if $GET{rich} || $POST{rich} ||
                        ($enabled_rte && ! $spellcheck_html && ! $preview);
    $$bodyopts .= "onunload=\"save_entry();\" " if $richtext;

    my $print_entry_form = sub {
        my $opts = shift;

        # authentication box
        my $auth = '';

        if ($remote) { # so lynx won't show this
            $auth .= "<tr valign='top' id='remotelogin' style='display: $remotelogin_display'><th>$ML{'.auth.poster'}</th><td><span id='remotelogin_content'>";
            $auth .= BML::ml(".loggedinas", {'user' => $remote->{'user'}, 'altget' => "?altlogin=1" });
            $auth .= "</span></td></tr>\n";
        }

        # table with username/password fields
        $auth .= "<tr id='altlogin_username' style='display: $altlogin_display;' valign='top'>\n";
        $auth .= "<th>" . BML::ml('Username') . ":</th>";
        $auth .= "<td>" . LJ::html_text({ 'name' => 'user', 'size' => '15', 'maxlength' => '15',
                                          'value' => $POST{'user'} || $GET{'user'} });
        $auth .= "</td></tr>\n";
        $auth .= "<tr id='altlogin_password' style='display: $altlogin_display;' valign='top'>";
        $auth .= "<th>" . BML::ml('Password') . ":</th>";
        $auth .= "<td>" . LJ::html_text({ 'type' => 'password', 'name' => 'password',
                                          'size' => '15', 'maxlength' => '30' });
        # posted with a user, but no password
        if ($did_post && $auth_missing) {
            $auth .= "<br /><?inerr $ML{'.error.nopass'} inerr?>";
        }
        $auth .= "</td></tr>";
        
        # if they submit the form and are spellchecking, remember
        # their settings from the GET requests
        my $getextra;
        $getextra .= "altlogin=1&" if $GET{'altlogin'};
        $getextra .= "rich=1&" if $richtext;
        chop $getextra;
        $getextra = "?$getextra" if $getextra;

        my $entry = {
            'mode' => "update",
            'auth_as_remote' => $auth_as_remote,
            'subject' => $subject,
            'event' => $event,
            'datetime' => "$year-$mon-$mday $hour:$min",
            'usejournal' => $POST{'usejournal'} || $GET{'usejournal'},
            'auth' => $auth,
            'remote' => $remote,
            'spellcheck_html' => $spellcheck_html,
            'clientversion' => "WebUpdate/2.0.0",
            'richtext' => 1,
            'richtext_on' => $richtext,
        };

        if ($did_post) {
            $entry->{$_} = $POST{$_} foreach keys %POST;
        }

        if (LJ::isu($remote) && (!$did_post || $did_spellcheck) && $remote->readonly) {
            $$body .= "<div id='readonly'><?warningbar ";

            if ($LJ::HELPURL{'readonly'}) {
                $$body .= BML::ml('.rowarn', {
                    'a_open' => "<a href='$LJ::HELPURL{readonly}'>",
                    'a_close' => "</a>"}
                                 );
            } else {
                $$body .= BML::ml('.rowarn', {
                    'a_open' => '',
                    'a_close' => ''}
                                 );
            }

            $$body .= " warningbar?><br /></div>";
        }

        $$body .= "<div style='width: 80%'><form method='post' action='update.bml$getextra' id='updateForm' name='updateForm'>";

        if ($opts->{require_tos}){ 
            $$body .= LJ::tosagree_html('update', $POST{agree_tos}, $errors->{require_tos});
        }

        $$body .= LJ::entry_form($entry, \$$head, \$onload, $errors);
        $$body .= "</form></div>";

        $$bodyopts .= "onload=\"$onload\" onresize=\"shift_contents();\" ";

        return;
    };

    if ($did_post && !$did_spellcheck && !$showform && !$enabled_rte && !$preview ) {

        # what's our authentication scheme for subsequent protocol actions?
        my $flags = {};
        my ($u, $user);

        if ($POST{'user'} &&                            # user argument given
            ! $user_is_remote &&                        # user != remote 
            (!$remote || $GET{'altlogin'})) {           # user has clicked alt auth
            
            $user = $POST{'user'};
            $u = LJ::load_user($user);

            # Verify entered password, if it is present. 
            my $ok;
            if ($POST{response}) {
                $ok = LJ::challenge_check_login($u, $POST{chal}, $POST{response});
            } else {  # js disabled, fallback to plaintext
                $ok = LJ::auth_okay($u, $POST{password});
            }
            $flags = { 'noauth' => 1, 'u' => $u } if $ok;

        } elsif ($remote && LJ::check_referer()) {   # assume remote if we have it
            $flags = { 'noauth' => 1, 'u' => $remote };
            $user = $remote->{'user'};
            $u = $remote;
        }

        if ($u && ! $u->tosagree_verify) {
            if ($POST{agree_tos}) {
                my $err = "";
                unless ($u->tosagree_set(\$err)) {
                    # error
                    BML::set_status(403); # 403 Forbidden
                    $errors->{require_tos} = $err;
                    $print_entry_form->({ require_tos => 1 });
                    return;
                }
                # successfully set
            } else {
                BML::set_status(403); # 403 Forbidden
                $errors->{require_tos} = $ML{'tos.error'};
                $print_entry_form->({ require_tos => 1 });
                return;
            }
        }

        # Check if the account they're posting to is read-only
        my $uj = $POST{'usejournal'} ? LJ::load_user($POST{'usejournal'}) : $u;
        if ($uj && $uj->readonly) {
            # Tell the user they can't post since read only
            BML::set_status(403); # 403 Forbidden
            $$body .= "<?errorbar ";
            $$body .= "<strong>$ML{'.error.update'}</strong> ";
            $$body .= $LJ::MSG_READONLY_USER;
            $$body .= " errorbar?><br />";

            $print_entry_form->();
            return
        }

        # do a login action
        my $login_message;
        {
            # build a clientversion string
            my $clientversion = "Web/2.0.0";
            $clientversion .= 's' if $did_spellcheck;
            
            # build a request object
            my %req = ( 'mode' => 'login',
                        'ver' => $LJ::PROTOCOL_VER,
                        'clientversion' => $clientversion,
                        'user' => $user,
                        );
            
            my %res;
            LJ::do_request(\%req, \%res, $flags);
            
            # error logging in ?
            unless ($res{'success'} eq 'OK') {
                $errors->{'auth'} = $ML{'.error.login'} . " " . LJ::ehtml($res{'errmsg'});
            }
            
            # server login message for user?
            $login_message = LJ::auto_linkify(LJ::ehtml($res{'message'}))
                if $res{'message'};
        }
        # any messages from the server?
        if ($login_message) {
            $$body .= "<?p <strong>$ML{'.loggingin'}</strong> $ML{'.servermsg'} p?><div style='margin-left: 40px'><b>$login_message</b></div>";
        }

        my %req = ( 'mode' => 'postevent',
                    'ver' => $LJ::PROTOCOL_VER,
                    'user' => $user,
                    'password' => $POST{'password'},
                    'usejournal' => $POST{'usejournal'},
                    );

        LJ::entry_form_decode(\%req, \%POST);
        if ($req{'event'} eq "") { 
            $errors->{'entry'} = "Must provide entry text"; 
        }

        my %res;
        LJ::do_request(\%req, \%res, $flags);

        if (!$errors) {
            # examine response
            my $update_message;
            if ($res{'success'} eq "OK" && $res{'message'}) {
                $update_message = LJ::auto_linkify(LJ::ehtml($res{'message'}));
            }
            
            # report results
            $$body .= "<?p <strong>$ML{'.updating'}</strong> ";
            
            if ($res{'success'} ne 'OK') {
                # update failed?
                BML::set_status(403); # 403 Forbidden
                $$body .= "<br /><?errorbar <strong>$ML{'.error.update'}</strong> ";
                $$body .= LJ::ehtml($res{'errmsg'}) . " errorbar?>";
                $$body .= "<br /> p?>";
            } else {
                # short bail if this was posted moderated or some other special case (no itemid but a message)
                if (!defined $res{itemid} && $res{message}) {
                    BML::set_status(403); # 403 Forbidden
                    $$body .= "<br />$res{message} p?>";
                    return;
                }

                # update success
                my $ju;
                if ($POST{'usejournal'}) {
                    $ju = LJ::load_user($POST{'usejournal'});  # posting as community
                } elsif ($user) {
                    $ju = LJ::load_user($user);                # posting not as user from form
                } else {
                    $ju = $remote;                             # posting as remote
                };
                $$body .= BML::ml(".update.success", { 'uri' => LJ::journal_base($ju) . "/" });
                my $juser = $ju->{'user'};
                my ($itemid, $anum) = ($res{'itemid'}, $res{'anum'});
                my $itemlink = LJ::item_link($ju, $itemid, $anum);
                $itemid = $itemid * 256 + $anum;
                $$body .= " p?><?p $ML{'.success.links'} p?><ul>" .
                    "<li><a href=\"$itemlink\">$ML{'.success.links.view'}</a></li>" .
                        "<li><a href=\"/editjournal.bml?journal=$juser&itemid=$itemid\">$ML{'.success.links.edit'}</a></li>" . 
                            "<li><a href=\"/tools/memadd.bml?journal=$juser&itemid=$itemid\">$ML{'.success.links.memories'}</a></li>" .
			        "<li><a href=\"/edittags.bml?journal=$juser&itemid=$itemid\">$ML{'.success.links.tags'}</a></li>" .
				    "</ul>";
                return;
            }
        }
    }

    $print_entry_form->();
    return;
}

_code?><?page
title=>   <?_code return $_[1]->{'title'}; _code?>
body=>    <?_code return $_[1]->{'body'}; _code?>
bodyopts=><?_code return $_[1]->{'bodyopts'}; _code?>
head<=

<?entryformcss?>
<?_code
{
    my $ret = $_[1]->{'head'};
    $ret .= "<script language='JavaScript' type='text/javascript' src='$LJ::JSPREFIX/entry.js'></script>";
    $ret .= (! $LJ::REQ_HEAD_HAS{'chalresp_js'}++) ? $LJ::COMMON_CODE{'chalresp_js'} : ""; 
    return $ret;
}
_code?>

<=head
page?><?_c <LJDEP>
lib: LJ::SpellCheck
link: htdocs/users, htdocs/download/index.bml, htdocs/moodlist.bml
link: htdocs/update.bml, htdocs/lostinfo.bml, htdocs/support/faqbrowse.bml
link: htdocs/allpics.bml
post: htdocs/update.bml
</LJDEP> _c?>
