<?_code # -*-bml-*-
{
    use strict;
    use vars qw(%POST %GET $title $body $js);

    my $dbh = LJ::get_db_writer();

    my $remote = LJ::get_remote();
    return "<?h1 Login Required h1?><?p Before you customize your journal, you must first <a href='/login.bml'>login</a>. p?>"
        unless $remote;

    my @journals = ($remote->{'user'});
    push @journals, LJ::get_shared_journals($remote);
    my $journal = $GET{'journal'} || $remote->{'user'};
    unless (grep { $_ eq $journal } @journals) {  return BML::redirect("/customize/");  }

    my $u = $remote;
    $u = LJ::load_user($journal) unless $journal eq $remote->{'user'};
    my $userid = $u->{'userid'};

    LJ::load_user_props($u, "stylesys", "s2_style");

    $body = "";
    $title = "Customize";
    $js = "";

    my $err = sub {
        $title = "Error";
        $body = shift;
        return;
    };

    my ($style, $layer);
    my $save_arg;
    my $save_redir;

    # when given 'w' argument, load user's current style, and edit the user layer.
    # this is the mode redirected to from /customize/ (the simple customization UI)
    if ($GET{'w'} eq "user" && $u->{'stylesys'} == 2) 
    {
        $style = LJ::S2::load_style($u->{'s2_style'});
        return $err->("Style not found.") unless $style && $style->{'userid'} == $u->{'userid'};
        $layer = LJ::S2::load_layer($dbh, $style->{'layer'}->{'user'});

        # if the b2lid of this layer has been remapped to a new layerid
        # then update the b2lid mapping for this layer
        my $b2lid = $layer->{b2lid};
        if ($b2lid && $LJ::S2LID_REMAP{$b2lid}) {
            LJ::S2::b2lid_remap($u, $style->{'layer'}->{'user'}, $b2lid);
            $layer->{b2lid} = $LJ::S2LID_REMAP{$b2lid};
        }

        $save_arg = "w=user&journal=$journal";
        $save_redir = "/customize/?journal=$journal";
    }

    return BML::redirect("/customize/") unless $layer;
    return $err->("Layer belongs to another user.") unless $layer->{'userid'} == $u->{'userid'};
    return $err->("Layer isn't of type user or theme.") 
        unless $layer->{'type'} eq "user" || $layer->{'type'} eq "theme";
        
    my $lyr_layout = LJ::S2::load_layer($dbh, $layer->{'b2lid'});
    return $err->("Layout layer for this $layer->{'type'} layer not found.") 
        unless $lyr_layout;
    my $lyr_core = LJ::S2::load_layer($dbh, $lyr_layout->{'b2lid'});
    return $err->("Core layer for layout not found.") 
        unless $lyr_core;

    $lyr_layout->{'uniq'} = $dbh->selectrow_array("SELECT value FROM s2info WHERE s2lid=? AND infokey=?",
                                                  undef, $lyr_layout->{'s2lid'}, "redist_uniq");

    my ($lid_i18nc, $lid_theme, $lid_i18n);
    $lid_i18nc = $style->{'layer'}->{'i18nc'};
    $lid_theme = $style->{'layer'}->{'theme'};
    $lid_i18n = $style->{'layer'}->{'i18n'};

    my $layerid = $layer->{'s2lid'};

    my @layers;
    push @layers, ([ 'core' => $lyr_core->{'s2lid'} ],
                    [ 'i18nc' => $lid_i18nc ],
                    [ 'layout' => $lyr_layout->{'s2lid'} ],
                    [ 'i18n' => $lid_i18n ]);
    if ($layer->{'type'} eq "user" && $lid_theme) {
        push @layers, [ 'theme' => $lid_theme ];
    }
    push @layers, [ $layer->{'type'} => $layer->{'s2lid'} ];

    my @layerids = grep { $_ } map { $_->[1] } @layers;
    LJ::S2::load_layers(@layerids);
    
    my %layerinfo;

    # load the language and layout choices for core.
    LJ::S2::load_layer_info(\%layerinfo, \@layerids);

    # action path
    if (LJ::did_post()) {
        # prevent spoofing:
        return BML::redirect("/customize") 
            unless $POST{'userid'} == $u->{'userid'};

        my %override;
        foreach my $prop (S2::get_properties($lyr_layout->{'s2lid'}))
        {
            $prop = S2::get_property($lyr_core->{'s2lid'}, $prop)
                unless ref $prop;
            next unless ref $prop;
            next if $prop->{'noui'};
            my $name = $prop->{'name'};
            next unless $POST{"$name:override"};
            next unless LJ::S2::can_use_prop($u, $lyr_layout->{'uniq'}, $name);
            $override{$name} = [ $prop, $POST{"${name}_value"} ];
        }
        
        if (LJ::S2::layer_compile_user($layer, \%override)) {
            return BML::redirect($save_redir) if $save_redir;
            $body = "Saved.";
            return;
        } else {
            my $error = LJ::last_error();
            $body = "Error saving layer:<pre>$error</pre>";
        }
        return;
    }

    $body .= "<form method='post' action='layer.bml?$save_arg'>";
    $body .= LJ::html_hidden("userid", $u->{'userid'});

    my %prop;  # name -> hashref, deleted when added to a category
    my @propnames;
    foreach my $prop (S2::get_properties($lyr_layout->{'s2lid'})) {
        unless (ref $prop) {
            $prop = S2::get_property($lyr_core->{'s2lid'}, $prop);
            next unless ref $prop;
        }
        $prop{$prop->{'name'}} = $prop;
        push @propnames, $prop->{'name'};
    }
    
    my @groups = S2::get_property_groups($lyr_layout->{'s2lid'});
    my $misc_group;
    my %groupprops;  # gname -> [ propname ]
    my %propgroup;   # pname -> gname;

    foreach my $gname (@groups) {
        if ($gname eq "misc" || $gname eq "other") { $misc_group = $gname; }
        foreach my $pname (S2::get_property_group_props($lyr_layout->{'s2lid'}, $gname)) {
            my $prop = $prop{$pname};
            next if ! $prop || $propgroup{$pname};
            $propgroup{$pname} = $gname;
            push @{$groupprops{$gname}}, $pname;
        }
    }
    # put unsorted props into an existing or new unsorted/misc group
    if (@groups) {
        my @unsorted;
        foreach my $pname (@propnames) {
            my $prop = $prop{$pname};
            next if ! $prop || $propgroup{$pname};
            push @unsorted, $pname;
        }
        if (@unsorted) {
            unless ($misc_group) {
                $misc_group = "misc";
                push @groups, "misc";
            }
            push @{$groupprops{$misc_group}}, @unsorted;
        }
    }

    my $group_name = sub {
        my $gname = shift;
        foreach my $lid ($lid_i18n, $lyr_layout->{'s2lid'}, $lid_i18nc, $lyr_core->{'s2lid'}) {
            next unless $lid;
            my $name = S2::get_property_group_name($lid, $gname);
            return LJ::ehtml($name) if $name;
        }
        return "Misc" if $gname eq "misc";
        return $gname;
    };

    my $prop_js = "";
    my $output_prop = sub {
        my $name = shift;
        my $prop = $prop{$name};
        return if ! $prop || $prop->{'noui'};

        my $name = $prop->{'name'};
        my $type = $prop->{'type'};
        
        my $can_use = LJ::S2::can_use_prop($u, $lyr_layout->{'uniq'}, $name);

        # figure out existing value (if there was no user/theme layer)
        my $existing;
        foreach my $lid (reverse @layerids) {
            next if $lid == $layerid; 
            $existing = S2::get_set($lid, $name);
            last if defined $existing;
        }

        if (ref $existing eq "HASH") { $existing = $existing->{'as_string'}; }

        if ($type eq "bool") {
            $prop->{'values'} ||= "1|Yes|0|No";
        }

        my %values = split(/\|/, $prop->{'values'});
        my $existing_display = defined $values{$existing} ? 
            $values{$existing} : $existing;

        $existing_display = LJ::eall($existing_display);

        my $override = S2::get_set($layerid, $name);
        my $had_override = defined $override;
        $override = $existing unless defined $override;

        if (ref $override eq "HASH") { $override = $override->{'as_string'}; }

        $body .= "<?h1 " . LJ::eall($prop->{'des'}) . " h1?>";
        {
            my $t = "";
            $t .= LJ::eall($prop->{'note'}) if $prop->{'note'};
            $t .= "<?help " . $LJ::HELPPURL{"s2opt_$name"} . " help?>" if $LJ::HELPURL{"s2opt_$name"};
            $body .= "<?p $t p?>" if $t;
        }
        $body .= "<div class='inset'>\n";
        $body .= LJ::html_check({ 'name' => "$name:override", 'id' => "$name:override",
                                  'selected' => $had_override, 'disabled' => ! $can_use,
                                  'onchange' => "toggleOverride('$name');" });
        my $offhelp = ! $can_use ? LJ::help_icon('s2propoff', ' ') : "";
        $body .= "<label for='$name:override'> Override default</label>$offhelp<br />\n";
        $body .= "<dl class='hidedt'>\n<dt>Default:</dt>\n<dd id='$name:default_value' style='font-family: monospace'>\n";
        if ($type eq "int" || $type eq "string") {
            if ($existing_display ne "") {
                $body .= $existing_display;
            } else {
                $body .= "<i>(nothing)</i>";
            }
        } elsif ($type eq "Color") {
            $body .= "<span style=\"border: 1px solid #000000; padding-left: 2em; ".
                "background-color: $existing;\">&nbsp;</span> <tt>$existing_display</tt>";
        } elsif ($type eq "bool") {
            $body .= $existing_display;
        }
        $body .= "</dd>\n<dt>Override:</dt>\n<dd id='$name:user_value'>\n";
        if ($prop->{'values'}) {
            $body .= LJ::html_select({ 'name' => "${name}_value",
                                       'disabled' => ! $can_use,
                                       'selected' => $override },
                                     split(/\|/, $prop->{'values'}));
        } elsif ($type eq "int") {
            $body .= LJ::html_text({ 'name' => "${name}_value",
                                     'disabled' => ! $can_use,
                                     'value' => $override,
                                     'maxlength' => 5,
                                     'size' => 7 });
        } elsif ($type eq "string") {
            my ($rows, $cols) = ($prop->{'rows'} + 0,
                                 $prop->{'cols'} + 0);
            if ($rows > 0 && $cols > 0) {
                $body .= LJ::html_textarea({ 'name' => "${name}_value",
                                     'disabled' => ! $can_use,
                                     'value' => $override,
                                     'onfocus' => "toggleOverride('$name');",
                                     'rows' => $rows,
                                     'cols' => $cols });
            } else {
                my ($size, $maxlength) = ($prop->{'size'} || 30,
                                            $prop->{'maxlength'} || 255);
                $body .= LJ::html_text({ 'name' => "${name}_value",
                                     'disabled' => ! $can_use,
                                     'value' => $override,
                                     'maxlength' => $maxlength,
                                     'size' => $size });
            }
        } elsif ($type eq "Color") {
            $body .= LJ::html_color({ 'name' => "${name}_value",
                                      'disabled' => ! $can_use,
                                      'default' => $override,
                                      'des' => $prop->{'des'} });
        }
        $body .= "</dd></dl>\n</div>\n";
        $prop_js .= "toggleOverride('$name');\n";
    };

    if (@groups) {
        $body .= "<div id='propgroupstab'>";
        my $num = 0;
        foreach my $gname (@groups) {
            my $name = $group_name->($gname);
            $num++;
            my $class = $num == 1 ? "propgrouptabsel" : "propgrouptab";
            $js .= "    propgroups[$num] = \"$gname\";\n";
            $body .= "<span class='$class' id='pgroup_tab_$gname'><a href='#pgroup$gname' onclick=\"return showPropGroup('$gname')\">$name</a></span>\n";
        }
        $body .= "</div>";
        $body .= "<div id='propgroupsbody'>";
   

        foreach my $gname (@groups) {
            $body .= "<a name='pgroup$gname'></a>\n";
            $body .= "<div id='pgroup_body_$gname'>\n";
            foreach my $pname (@{$groupprops{$gname}}) {
                $output_prop->($pname);
            }
            $body .= "</div>";
        }
        $body .= "</div>\n";

        $body .= "<script language='JavaScript'>showPropGroup('$groups[0]');</script>\n";

    } else {
        foreach my $pname (@propnames) {
            $output_prop->($pname);
        }
    }

    $body .= "<script type='text/javascript' language='JavaScript'><!--\n$prop_js// --></script>";
    
    $body .= "<?h1 Finished? h1?><?p When done, click the save button below. p?><center>";
    $body .= LJ::html_submit('action:save', "Save");
    $body .= "</center>";
    
    $body .= "</form>";

    return;

}
_code?><?page
title=><?_code return $title; _code?>
body=><?_code return $body; _code?>
head<=
<script language="JavaScript" src="<?_code return $LJ::JSPREFIX; _code?>/colorpicker.js"></script>
<script language="JavaScript">
    colPic_set_imgprefix("<?_code return $LJ::IMGPREFIX; _code?>");

    var propgroups = new Array();
    function showPropGroup (name) {
        if (! document.getElementById) { return true; }
        for (var i=0; i<propgroups.length; i++) {
            var gname = propgroups[i];
            var tab = document.getElementById("pgroup_tab_" + gname);
            if (tab && tab.setAttribute) {
                tab.setAttribute("class", (gname == name) ? "propgrouptabsel" : "propgrouptab");
            }
            var div = document.getElementById("pgroup_body_" + gname);
            if (div) {
                div.style.display = (gname == name) ? "block" : "none";
            }
        }
        return false;
    }
    function toggleOverride (name) {
        if (!name) return true;
        if (!document.getElementById) return true;
        var ocheck = document.getElementById(name + ':override');
        if (!ocheck) return true;

        var def_vals = document.getElementById(name + ':default_value');
        if (!def_vals) return true;
        var usr_vals = document.getElementById(name + ':user_value');
        if (!usr_vals) return true;

        var disp_def = ocheck.checked ? 'none'  : 'block';
        var disp_usr = ocheck.checked ? 'block' : 'none';

        def_vals.style.display = disp_def;
        usr_vals.style.display = disp_usr;
    }
<?_code return $js; _code?>
</script>


<style type='text/css'>
 #propgroupstab {
    font-size: 1.2em;
    font-weight: bold;
    font-decoration: none;
    border-bottom: 2px solid black;
    margin: 0; padding: 0;
 }
 #propgroupsbody {
    border-left: 2px solid black;
    border-right: 2px solid black;
    border-bottom: 2px solid black;
    margin: 0; padding: 0.5em;
 }

 span.propgrouptabsel, span.propgrouptab {
   margin: 0 0.2em 0 0.8em;
   padding: 0.25em;
   border-top: 2px solid black;
   border-left: 2px solid black;
   border-right: 2px solid black;
}

 span.propgrouptab {
   background: #ddd;
   color: black;
 }
 span.propgrouptab a {
    text-decoration: none;
    color: black;
 } 

 span.propgrouptabsel {
   color: #ddd;
   background: black;
 }
 span.propgrouptabsel a {
    text-decoration: none;
    color: #ddd;
 } 
 div.inset {
    margin-left: 2em;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
 }
 dl.hidedt {
    margin: 0;
    padding: 0;
 }
 dl.hidedt dt { font-weight: bold; }
 noscript { display: inline; }
</style>
<script type='text/javascript' language='JavaScript'>
    // Only hide if we do the JS-switchy thing
    if (document.getElementById)
        document.write("<style type='text/css'>" +
                       "dl.hidedt dd { margin: 0; padding: 0; }" +
                       "dl.hidedt dt { display: none; }" +
                       "noscript { display: none; }" +
                       "</style>");
</script>

<=head
page?>
