<?page
title=><?_ml .title _ml?>
head<=
<?_code return $LJ::COMMON_CODE{'autoradio_check'}; _code?>
<style>
    option.disabled { color: GrayText; }
</style>
<=head
body<=

<?_code
{
    # this file used to be modify_do.bml, but modify.bml died, so we moved this
    # functionality to modify.bml, but we don't want the translators to have to
    # retranslate all of the phrases, so we're still using /modify_do.bml scope
    BML::set_language_scope("/modify_do.bml");

    use strict;
    use vars qw(%GET %POST);

    return LJ::server_down_html() if $LJ::SERVER_DOWN;

    LJ::set_active_crumb('modify');

    my $remote = LJ::get_remote();
    return LJ::bad_input("You must be logged in to modify your journal")
        unless $remote;

    my $authas = $GET{'authas'} || $remote->{'user'};
    my $u = LJ::get_authas_user($authas);
    return LJ::bad_input("You could not be authenticated as the specified user.")
        unless $u;

    return $LJ::MSG_READONLY_USER if LJ::get_cap($remote, "readonly");

    ### user is now authenticated ###

    my $dbr = LJ::get_db_reader();
    my $sth;

    my $capstyles = LJ::get_cap($u, "styles");
    
    LJ::load_user_props($u, "opt_usesharedpic",
                        "s1_lastn_style", "s1_calendar_style",
                        "s1_day_style", "s1_friends_style",
                        "stylesys", "journaldomain");

    # if a POST, update their info
    if (LJ::did_post()) {

        return "<?badinput?>" unless LJ::text_in(\%POST);

        # database error reporting
        my $dberr = sub {
            return "<?h1 $ML{'Error'} h1?><?p $ML{'error.dberror'} <b>@_[0]</b> p?>";
        };

        my $dbh = LJ::get_db_writer();

        # setup what we're gonna update in the user table:
        my %update = ();

        # what userprops we'll be setting.
        my %uprop;

        # journal domains
        my $dom_cap = LJ::get_cap($u, 'userdomain');
        if ((exists $POST{'journaldomain'} && $u->{'journaldomain'} ne $POST{'journaldomain'}) || 
            (! $dom_cap && $POST{'journaldomain_del'})) 
        {
            $POST{'journaldomain'} =~ s!^(http://)?(www\.)?!!;
            my $dom = lc($POST{'journaldomain'});
            if (($dom_cap && ! $dom) || (! $dom_cap && $POST{'journaldomain_del'})) {
                $dbh->do("DELETE FROM domains WHERE userid=?", undef, $u->{'userid'});
            } else {
                $dbh->do("INSERT INTO domains VALUES (?, ?)", undef, $dom, $u->{'userid'});
                if ($dbh->err) {
                    my $otherid = $dbh->selectrow_array("SELECT userid FROM domains WHERE domain=?",
                                                        undef, $dom);
                    return LJ::bad_input($ML{'.error.dupdomainalias'}) if $otherid != $u->{'userid'};
                }
                if ($u->{'journaldomain'}) {
                    $dbh->do("DELETE FROM domains WHERE userid=? AND domain <> ?",
                             undef, $u->{'userid'}, $dom);
                }
            }

            # set journaldomain prop if it's been changed
            $uprop{'journaldomain'} = $dom
                unless $POST{'journaldomain'} eq $u->{'journaldomain'};
        }

        # validate moodthemeid
        # mood theme, make sure they're allowed to use it
        my $moodthemeid = $POST{'moodthemeid'}+0;
        if ($moodthemeid) {
            my ($mownerid, $mpublic) = $dbr->selectrow_array("SELECT ownerid, is_public FROM moodthemes ".
                                                             "WHERE moodthemeid=?", undef, $moodthemeid);
            $moodthemeid = 0 unless $mpublic eq 'Y' || $mownerid == $u->{'userid'};
        }
        $update{'moodthemeid'} = $moodthemeid;
        $update{'opt_forcemoodtheme'} = $POST{'opt_forcemoodtheme'} ? "Y" : "N";
        

        # all of these options should only be processed for S1 users
        if ($u->{'stylesys'} != 2) {

            # color themes
            $update{'themeid'} = $POST{'themetype'} eq "custom" ? 0 : $POST{'themeid'};
        
            if ($POST{'themetype'} eq "custom") {
                my $dig = Digest::MD5::md5_hex(join(",", map { $POST{"theme_cust:$_"} }
                                                    map { $_->[0] } @LJ::S1::themecoltypes));
                if ($dig ne $POST{'themecolors_dig'}) {
                    my %cols;
                    foreach my $col (@LJ::S1::themecoltypes) {
                        my $val = $POST{"theme_cust:$col->[0]"};
                        next if length($val) > 20;
                        next unless ($val =~ /^\#[a-f0-9]{6,6}$/i ||
                                     $val !~ /[^\s\w]/);
                        $cols{$col->[0]} = $val;
                    }

                    return $ML{"error.nodb"} unless $u->writer;
                    $u->do("INSERT IGNORE INTO s1usercache (userid) VALUES (?)", undef, $u->{'userid'});
                    $u->do("UPDATE s1usercache SET color_stor=? WHERE userid=?", undef,
                           Storable::nfreeze(\%cols), $u->{'userid'});
                    LJ::MemCache::delete([$u->{'userid'}, "s1uc:$u->{'userid'}"]);

                    $dbh->do("DELETE FROM themecustom WHERE user=?", undef, $u->{'user'})
                        if $dbh->selectrow_array("SELECT user FROM themecustom ".
                                                 "WHERE user=? LIMIT 1", undef, $u->{'user'});
                }
            }

            # update 'overrides' table
            if ($POST{'overrides'} !~ /\S/) {
                LJ::S1::clear_overrides($u);
                $update{'useoverrides'} = "N";

            } else {

                my $oldoverrides = "";
                if ($u->{'useoverrides'} eq "Y") {
                    $oldoverrides = LJ::S1::get_overrides($u);
                }

                # This allows users to keep their current illegal overrides,
                # but they may not create new ones nor edit the ones they already have.
                # They may only delete or keep illegal overrides.
                my %overrides = ();
                my %newoverrides = ();
                LJ::parse_vars(\$oldoverrides,\%overrides);
                LJ::parse_vars(\$POST{'overrides'},\%newoverrides);
            
                # head overrides should only have valid head elements in them
                foreach my $a (qw(GLOBAL LASTN FRIENDS CALENDAR DAY)) {
                    my $sec = "${a}_HEAD";
                    next unless $newoverrides{$sec} ne $overrides{$sec};

                    my $testtag = sub {
                        my $tag = lc(shift);
                        return "<$tag" if ($tag eq "title" || $tag eq "base" ||
                                           $tag eq "style" || $tag eq "link" ||
                                           $tag eq "meta" || $tag  eq "xx");
                        return "<xx-$tag";
                    };
                    $newoverrides{$sec} =~ s/\<(\w+)/$testtag->($1)/eig;
                    $newoverrides{$sec} =~ s/\<\/head/\<\/xx-head/ig;
                }

                # load all the properties to see which ones are overridable
                my @vars;
                LJ::load_objects_from_file("vars.dat", \@vars);
                foreach my $v (@vars) {
                    my $ov = $v->{'props'}->{'override'}; 
                    if ($ov eq "yes" || $ov eq "only" || $capstyles) {
                        my $name = $v->{'name'};
                        if (defined $newoverrides{$name}) {
                            $overrides{$name} = $newoverrides{$name};
                        }
                    }
                }

                # make the new override code we'll put in the database
                my $overr='';
                foreach (keys %overrides) {
                    if ($newoverrides{$_}) {
                        if ($overrides{$_} =~ /\n/) {
                            $overr .= "$_<=\n".$overrides{$_}."\n<=$_\n\n";
                        } else {
                            $overr .= "$_=>".$overrides{$_}."\n\n";
                        }
                    }
                }
            
                # no value, delete overrides
                if ($overr !~ /\S/) {
                    LJ::S1::clear_overrides($u);
                    $update{'useoverrides'} = "N";

                # have a value, update overrides
                } else {
                    LJ::S1::save_overrides($u, $overr);
                    $update{'useoverrides'} = "Y";
                }
            }

            # friends view shared pic option for s1
            $uprop{'opt_usesharedpic'} = $POST{'opt_usesharedpic'} ? "1" : "0";

            # set all the styles
            {
                my @picked = ();
                foreach my $view (@LJ::views) {
                    my $sid = $POST{"s1_${view}_style"}+0;
                    if ($sid) {
                        $uprop{"s1_${view}_style"} = $sid;
                        push @picked, $sid;
                    }
                }

                # verify they haven't forged the style numbers
                unless ($capstyles) {

                    # just load whole structure since it should be cached
                    my $pubstyles = LJ::S1::get_public_styles();
                    my $userstyles = LJ::S1::get_user_styles($u);

                    foreach (@picked) {
                        my $type = $userstyles->{$_}->{'type'};
                        return LJ::bad_input($ML{'.error.stylenotavailable'})
                            unless exists $pubstyles->{$_} || 
                                   exists $userstyles->{$_} &&
                                          ($capstyles || $_ == $u->{"s1_${type}_style"});
                    }
                }
            }
        }


        # update 'user' table
        foreach (keys %update) {
            delete $update{$_} if $u->{$_} eq $update{$_};
        }
        LJ::update_user($u, \%update) if %update;

        # change any of the userprops ?
        foreach my $uprop (keys %uprop) {
            next if $POST{$uprop} eq $u->{$uprop};
            LJ::set_userprop($u, $uprop, $uprop{$uprop});
        }

        # tell the user all is well
        return "<?h1 $ML{'.success.head'} h1?><?p ".BML::ml(".success.text", {'url' => LJ::journal_base($u) . "/" })." p?>";
    }

    # not submitting a post, show edit form
    my $ret;

    # user switcher
    $ret .= "<form action='modify.bml' method='get'>\n";
    $ret .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} });
    $ret .= "</form>\n\n";

    ### journal style
    $ret .= "<?h1 $ML{'.journaloptions.head'} h1?>\n<?p $ML{'.journaloptions.about'} p?>\n\n";

    ###
    ### LAYOUT OPTIONS
    ###

    $ret .= "<form method='post' action='modify.bml?authas=$authas'>\n";

    # using S1, need to take style input
    if ($u->{'stylesys'} != 2)
    {
        my $and = $capstyles ? "" : $ML{'.pagelayoutstyle.warning'};
        $ret .= "<?h2 $ML{'.pagelayoutstyle.head'} h2?><?p $ML{'.pagelayoutstyle.about'}  $and p?>\n";
        $ret .= "<table style='margin-left: 30px; margin-bottom: 20px;'>\n";
        $ret .= "<tr bgcolor='#d0d0d0'><td></td><td>$ML{'.availablestyles.head'}</td></tr>\n";

        my $pubstyles = LJ::S1::get_public_styles();
        my %pubstyles = ();
        foreach (sort { $a->{'styledes'} cmp $b->{'styledes'} } values %$pubstyles) {
            push @{$pubstyles{$_->{'type'}}}, $_;
        }

        my $userstyles = LJ::S1::get_user_styles($u);
        my %userstyles = ();
        foreach (sort { $a->{'styledes'} cmp $b->{'styledes'} } values %$userstyles) {
            push @{$userstyles{$_->{'type'}}}, $_;
        }

        foreach my $view (@LJ::views) {

            $ret .= "<tr><td bgcolor='#d0d0d0'>$LJ::viewinfo{$view}->{'des'}</td><td>";
            
            my @list = map { $_->{'styleid'}, $_->{'styledes'} } 
                       @{$pubstyles{$view} || []};

            if (@{$userstyles{$view} || []}) {

                my @user_list = map { $_->{'styleid'}, $_->{'styledes'} }
                                grep { $capstyles || $u->{"s1_${view}_style"} == $_->{'styleid'} }
                                @{$userstyles{$view} || []};
                push @list, { value    => "",
                              text     => "--- $ML{'.availablestyles.userstyles'} ---",
                              disabled => 1 }, @user_list
                    if @user_list;

                my @disabled_list = 
                                map { { value    => $_->{'styleid'},
                                        text     => $_->{'styledes'},
                                        disabled => 1 } }
                                grep { ! $capstyles && $u->{"s1_${view}_style"} != $_->{'styleid'} }
                                @{$userstyles{$view} || []};
                push @list, { value    => '',
                              text     => "--- $ML{'.availablestyles.disabledstyles'} ---",
                              disabled => 1 }, @disabled_list
                    if @disabled_list;
            }

            $ret .= LJ::html_select({ 'name' => "s1_${view}_style",
                                      'selected' => $u->{"s1_${view}_style"} }, @list);

            $ret .= "</td></tr>\n";
        }
        $ret .= "</table>\n\n";
        
        ###
        ### COLOR THEME OPTIONS
        ###

        $ret .= "<?h2 $ML{'.colortheme.head'} h2?><?p $ML{'.colortheme.about'} p?>\n";
        $ret .= "<div style='margin-left: 30px; margin-bottom: 20px;'>\n";

        $ret .= LJ::html_check({ 'type' => 'radio', 'name' => 'themetype', 
                                 'value' => 'default', 'selected' => $u->{'themeid'} > 0 });
        $ret .= "<b>$ML{'.colortheme.defaulttheme'}</b>: ";

        my @list;
        $sth = $dbr->prepare("SELECT themeid, name FROM themelist ORDER BY name");
        $sth->execute;
        while ($_ = $sth->fetchrow_hashref) {
            push @list, ($_->{'themeid'}, $_->{'name'});
        }
        $ret .= LJ::html_select({ 'name' => 'themeid', 'selected' => $u->{'themeid'} }, @list) . "<br />\n";
        $ret .= LJ::html_check({ 'type' => 'radio', 'name' => 'themetype', 'id' => 'themetype:custom',
                                 'value' => 'custom', 'selected' => $u->{'themeid'} == 0 }) . "\n";
        $ret .= "<b>$ML{'.colortheme.customcolors'}</b>:";
        
        $ret .= "<table border='1' align='center' cellpadding='2'>\n";
        $ret .= "<tr valign='top' bgcolor='#d0d0d0'><td align='right'><b>$ML{'.colortheme.area.head'}</b></td><td><b>$ML{'.colortheme.color.head1'}</b><br /><font size='-1'>$ML{'.colortheme.color.head2'}</font></td></tr>\n";
            
        # get the user's custom colors
        my %custcolors = ();

        if ($u->{'themeid'} == 0) {
            my $dbcr = LJ::get_cluster_reader($u);
            my $stor = $dbcr->selectrow_array("SELECT color_stor FROM s1usercache WHERE userid=?",
                                              undef, $u->{'userid'});
            if ($stor) {
                %custcolors = %{ Storable::thaw($stor) };
            } else {
                # ancient table.
                $sth = $dbr->prepare("SELECT coltype, color FROM themecustom WHERE user=?");
                $sth->execute($u->{'user'});
                $custcolors{$_->{'coltype'}} = $_->{'color'} while $_ = $sth->fetchrow_hashref;
            }
        } else {
            $sth = $dbr->prepare("SELECT coltype, color FROM themedata WHERE themeid=?");
            $sth->execute($u->{'themeid'});
            $custcolors{$_->{'coltype'}} = $_->{'color'} while $_ = $sth->fetchrow_hashref;
        }
            
        my $dig;
        foreach my $col (@LJ::S1::themecoltypes) {
            $ret .= "<tr><td align='right'>$col->[1]</td><td>";
            $ret .= LJ::html_text({ 'name' => "theme_cust:$col->[0]", 'size' => '20',
                                    'maxlength' => '30', 'value' => $custcolors{$col->[0]},
                                    'onchange' => "checkRadioButton('themetype:custom');" });
            $ret .= "</td></tr>\n";
            $dig .= $col->[0];
        }
        $dig = Digest::MD5::md5_hex($dig);
        $ret .= LJ::html_hidden("themecolors_dig", $dig) unless $u->{'themeid'};
            
        $ret .= "</table></div>\n\n";
        
        ###
        ### FRIENDS VIEW OPTIONS
        ###

        $ret .= "<?h2 $ML{'.friends.head'} h2?><?p $ML{'.friends.about'} p?>";
        $ret .= "<table style='margin-left: 30px; margin-bottom: 20px;' cellspacing='0'>\n";

        $ret .= "<tr valign='middle'><td>";
        $ret .= LJ::html_check({ 'type' => 'check', 'name' => 'opt_usesharedpic', 'selected' => $u->{'opt_usesharedpic'} });
        $ret .= "</td><td><b>$ML{'.friends.opt.usesharedpic.head'}</b></td></tr>\n";
        $ret .= "<tr><td>&nbsp;</td><td>$ML{'.friends.opt.usesharedpic.about'}</td></tr>\n";

        $ret .= "</table>\n\n";
            
        ###
        ### STYLE OVERRIDES
        ###

        # first, load the overrides if they use 'em:
        my $overrides = "";
        if ($u->{'useoverrides'} eq "Y") {
            $overrides = LJ::S1::get_overrides($u);
            LJ::text_out(\$overrides);
        }

        $ret .= "<div style='margin-bottom: 20px'>\n";
        $ret .= "<?h1 $ML{'.overrides.head'} h1?><?p $ML{'.overrides.about'} p?>\n";
        $ret .= "<?p <font size='+1'><b>$ML{'.overrides.warning'}</b></font> p?>\n";
        $ret .= "<?p $ML{'.overrides.note'} p?>\n";
        $ret .= "<?standout <b>$ML{'.overrides.box.head'}</b><br />";
        $ret .= LJ::html_textarea({ 'name' => 'overrides', 'cols' => '60', 'rows' => '15',
                                    'wrap' => 'off', 'value' => $overrides }) . " standout?>";
        $ret .= "</div>\n\n";
    }

    ###
    ### MOOD THEME OPTIONS
    ###

    $ret .= "<?h2 $ML{'.moodicons.head'} h2?><?p $ML{'.moodicons.about'} p?>\n";

    $sth = $dbr->prepare("SELECT moodthemeid, name FROM moodthemes WHERE is_public='Y'");
    $sth->execute;
    my @themes = ({ 'moodthemeid' => 0, 'name' => '(None)' });
    push @themes, $_ while ($_ = $sth->fetchrow_hashref);

    ### user's private themes
    {	
        my @theme_user;
        $sth = $dbr->prepare("SELECT moodthemeid, name FROM moodthemes WHERE ownerid=? AND is_public='N'");
        $sth->execute($u->{'userid'});
        push @theme_user, $_ while ($_ = $sth->fetchrow_hashref);
        if (@theme_user) {
            push @themes, { 'moodthemeid' => 0, 'name' => "--- $ML{'.moodicons.personal'} ---" };
            push @themes, @theme_user;
        }
    }

    $ret .= "<div style='margin-left: 30px; margin-bottom: 20px;'><b>$ML{'.moodicons.select'} </b>\n";
    $ret .= LJ::html_select({ 'name' => 'moodthemeid', 'selected' => $u->{'moodthemeid'} },
                              map { $_->{'moodthemeid'}, $_->{'name'} } @themes) . "\n";

    $ret .= "(<a href='$LJ::SITEROOT/moodlist.bml' target='moods'>$ML{'.moodicons.preview'}</a>)\n";
    $ret .= "<br />" . LJ::html_check({ 'type' => 'check', 'name' => 'opt_forcemoodtheme',
                                        'id' => 'opt_forcemoodtheme',
                                        'selected' => $u->{'opt_forcemoodtheme'} eq 'Y' }) . "\n";
    $ret .= "<label for='opt_forcemoodtheme'>$ML{'.moodicons.opt.forcefriends.about'}</label></div>\n\n";

    ###
    ### JOURNAL DOMAIN OPTIONS
    ###

    my $has_cap = LJ::get_cap($u, 'userdomain');
    my $has_dom = $u->{journaldomain} ? 1 : 0;
    if ($LJ::OTHER_VHOSTS && ($has_cap || $has_dom)) {
        $ret .= "<?h2 $ML{'.domainalias.head'} h2?><?p $ML{'.domainalias.about'} p?>\n";

        $ret .= "<div style='margin: 20px 0 20px 30px'>";
        $ret .= "<table><tr><td align='left'><b>$ML{'.domainalias.domainname'}</b></td><td>";
        $ret .= LJ::html_text({ 'name' => 'journaldomain', 'size' => '30',
                                'maxlength' => '80', 'value' => $u->{'journaldomain'},
                                'disabled' => ! $has_cap });
        $ret .= LJ::html_submit('journaldomain_del' => "Remove") unless $has_cap;
        $ret .= "</td></tr>";
        $ret .= "<tr><td>&nbsp;</td><td>$ML{'.domainalias.example'}</td></tr></table>";
        $ret .= "<?p " . BML::ml(".domainalias.helptext", {'sitename' => $LJ::SITENAME})." p?></div>\n\n";
    }

    ### ending submit block
    $ret .= "<?h1 $ML{'.done.head'} h1?><?p $ML{'.done.text'} p?>\n";
    $ret .= "<?standout " . LJ::html_submit(undef, $ML{'.done.btn.savechanges'}) . " standout?>\n";
    $ret .= "</form>\n";

    return $ret;

}
_code?>

<=body
page?><?_c <LJDEP>
link: htdocs/moodlist.bml, htdocs/developer/index.bml, htdocs/developer/varlist.bml, htdocs/styles/create.bml
post: htdocs/modify_do.bml
</LJDEP> _c?>
