<%perl>;
my %sites;
# XXX Should we exclude inactive sites?
my @sites = map { $sites{$_->get_id} = $_; $_}
  Bric::Biz::Site->list({ active => 1 });
my $perm_sel = [
    ['usrgrp'   => $usr_grp_pl],
    $is_user ? (
        ['all'            => $lang->maketext('All')],
        ['object'         => $lang->maketext('Object Groups')],
        ['workflow'       => $lang->maketext(ucfirst $wf_pl)],
        ['desk'           => $lang->maketext(ucfirst $dsk_pl)],
        (map { $sites{$_->get_id} = $_; # Cache for later.
               ['cat_site_' . $_->get_id =>
                $lang->maketext('[_1] Site Categories', $_->get_name)  ]
            } @sites),
        ['all_categories' => $lang->maketext("All " . ucfirst $cat_pl)],
    ) : (),
];

my (%perms, %start_desks);

$num ||= 1;

if ($is_user) {
    $m->comp('/widgets/wrappers/sharky/table_top.mc',
       caption => $lang->maketext('Filter by Permission Type'),
       search  => 1
    );
    $m->comp('/widgets/profile/select.mc',
             'disp' => 'Permission Type',
             'options' => $perm_sel,
             'value' => $perm_type,
             'js' => qq{onchange="location.href='} . $r->uri .
                     "?perm_type=' + " .
                     qq{escape(this.options[this.selectedIndex].value)"},
    );
    $m->comp('/widgets/profile/hidden.mc',
         'name' => 'perm_type',
         'value' => $perm_type,
    );
    
    $m->comp('/widgets/wrappers/sharky/table_bottom.mc');

    # $is_user means $perm_type is one of
    # object, workflow, desk, (category)

    foreach my $perm ($pkg->list({ usr_grp_id => $id }) ) {
        my $gid = $perm->get_obj_grp_id;
        next if $gid == ADMIN_GRP_ID;
        $perms{$gid} = $perm;
    }

    unless ($perm_type eq 'object') {
        foreach my $wf ($wf_pkg->list()) {
            $start_desks{$wf->get_head_desk_id()} = 1;
        }
    }
}

if ($perm_type eq 'object' || $perm_type eq 'all') {
    # We need grant to the members of this current user group permissions to
    # other groups.
    $m->comp("/widgets/wrappers/sharky/table_top.mc", number => $num++,
             caption => "Object Group Permissions");

    $m->comp($head_comp,
             $lang->maketext('Grant "[_1]" members permission to access the '
                             . "members of these groups.", $name));
    # Get any existing permissions.
    foreach my $perm ($pkg->list({ usr_grp_id => $id }) ) {
        my $gid = $perm->get_obj_grp_id;
        next if $gid == ADMIN_GRP_ID;
        $perms{$gid} = $perm;
    }

    my $odd_row = 1;
    foreach my $grp ($grp_pkg->list({ })) {
        my $gid = $grp->get_id;
        next if $gid == ADMIN_GRP_ID;

        $odd_row = !$odd_row;
        $m->comp($row_comp,
                 grp => $grp,
                 gid => $gid,
                 type => 'obj',
                 is_asset_grp => $chk_asset_grp->($grp),
                 publish => 1,
                 recall => 1,
                 perm => $perms{$gid},
                 odd_row => $odd_row);
    }
    $m->out(qq{</table>\n});
    $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
}

if ($perm_type eq 'workflow' || $perm_type eq 'all') {
    # We need to do it for workflows, desks, and categories, too.
    # Do the workflows, first.
    $m->comp("/widgets/wrappers/sharky/table_top.mc",
             number => $num++,
             caption => "$wf_disp Permissions");
    $m->comp($head_comp, $lang->maketext('Grant "[_1]" members permission to'
             ." access assets in these workflows.", $name));
    my $odd_row = 1;
    foreach my $wf ($wf_pkg->list) {
        # Skip workflows from deleted sites.
        my $site = $sites{$wf->get_site_id} or next;
        my $gid = $wf->get_asset_grp_id;
        my $grp = $asset_grp_pkg->lookup({ id => $gid });
        $odd_row = !$odd_row;
        # XXX We say it isn't an asset group because no higher than EDIT is
        # allowed for a workflow, even though it is actually an asset group.
        $m->comp($row_comp,
                 grp => $grp,
                 gid => $gid,
                 type => 'obj',
                 is_asset_grp => 0,
                 perm => $perms{$gid},
                 name => $wf->get_name . ' ('
                         . $sites{$wf->get_site_id}->get_name . ')',
                 odd_row => $odd_row
       );
    }
    $m->out(qq{</table>\n});
    $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
}

if ($perm_type eq 'desk' || $perm_type eq 'all') {
    # Now do the desks.
    $m->comp("/widgets/wrappers/sharky/table_top.mc", number => $num++,
             caption => "$dsk_disp Permissions");

    $m->comp($head_comp, $lang->maketext('Grant "[_1]" members permission to '
                                         . "access assets on these desks.",
                                         $name));

    my $odd_row = 1;
    foreach my $dsk ($dsk_pkg->list) {
        my $gid = $dsk->get_asset_grp;
        my $grp = $gid ? $asset_grp_pkg->lookup({ id => $gid }) : undef;
        $odd_row = !$odd_row;
        $m->comp($row_comp,
                 grp => $grp,
                 gid => $gid,
                 create  => $start_desks{$dsk->get_id},
                 recall  => $start_desks{$dsk->get_id},
                 publish => $dsk->can_publish,
                 type => 'obj',
                 perm => $perms{$gid},
                 is_asset_grp => 1,
                 name => $dsk->get_name,
                 odd_row => $odd_row);
    }
    $m->out(qq{</table>\n});
    $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
}

if ($perm_type eq 'all_categories' || $perm_type eq 'all') {
    # And finally, do it for all the categories in each site.
    for my $site (@sites) {
        $m->comp('.site_categories',
                 num           => $num++,
                 head_comp     => $head_comp,
                 row_comp      => $row_comp,
                 grp_name      => $name,
                 perms         => \%perms,
                 site          => $site);
    }
}

if ($perm_type =~ /^cat_site_(\d+)$/) {
    $m->comp('.site_categories',
             num           => $num++,
             head_comp     => $head_comp,
             row_comp      => $row_comp,
             grp_name      => $name,
             perms         => \%perms,
             site          => $sites{$1},
    );
}

if ($perm_type eq 'usrgrp' || $perm_type eq 'all') {
    # Now get the permissions on this group that are granted to user groups.
    $m->comp("/widgets/wrappers/sharky/table_top.mc",
             caption => "$usr_grp_disp Permissions",
             number => $num);

    $m->comp($head_comp, $lang->maketext("Grant the members of the following groups "
                                         . "permission to access the members of the "
                                         . '"[_1]" group.',$name));

    my $is_asset_grp = $chk_asset_grp->($grp);
    my $is_perm_grp  = $grp->get_permanent ? 1 : 0;
    my $odd_row = 1;

    # Get any existing permissions.
    foreach my $perm ($pkg->list({ obj_grp_id => $id }) ) {
        my $gid = $perm->get_usr_grp_id;
        next if $gid == ADMIN_GRP_ID;
        $perms{$gid} = $perm;
    }
    # Now get the rows for all user groups.
    foreach my $ugrp ($usr_grp_pkg->list) {
        my $gid = $ugrp->get_id;
        next if $gid == ADMIN_GRP_ID;
        
        $odd_row = !$odd_row;
        $m->comp($row_comp,
                 grp          => $ugrp,
                 gid          => $gid,
                 is_asset_grp => $is_asset_grp,
                 create       => $is_perm_grp || $is_asset_grp,
                 publish      => $is_asset_grp,
                 recall       => $is_asset_grp,
                 perm         => $perms{$gid},
                 odd_row      => $odd_row);
    }
    $m->out(qq{</table>\n});
    $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
}
</%perl>

%#--- Arguments ---#
<%args>
$grp
$num           => undef
$read_only     => undef
</%args>
%#--- Once ---#
<%once>;
my $vals_aref = [ [0 => 'NONE'], @{ Bric::Util::Priv->vals_aref } ];
my $vals_href = Bric::Util::Priv->vals_href;
$vals_href->{0} = 'NONE';
my $key = 'perm';
my $pkg = get_package_name($key);
my $usr_grp_key = 'user_grp';
my $usr_grp_disp = get_disp_name($usr_grp_key);
my $usr_grp_pkg = get_package_name($usr_grp_key);
my $usr_grp_pl = get_class_info($usr_grp_key)->get_plural_name;
my $wf_key = 'workflow';
my $wf_pkg = get_package_name($wf_key);
my $wf_disp = get_disp_name($wf_key);
my $wf_pl = lc get_class_info($wf_key)->get_plural_name;
my $dsk_key = 'desk';
my $dsk_pkg = get_package_name($dsk_key);
my $dsk_disp = get_disp_name($dsk_key);
my $dsk_pl = lc get_class_info($dsk_key)->get_plural_name;
my $cat_key = 'category';
my $cat_pkg = get_package_name($cat_key);
my $cat_disp = get_disp_name($cat_key);
my $cat_pl = lc get_class_info($cat_key)->get_plural_name;
my $cat_grp_key = 'asset_grp';
my $cat_grp_disp = get_disp_name($cat_grp_key);
my $cat_grp_pkg = get_package_name($cat_grp_key);
my $grp_key = 'grp';
my $grp_pkg = get_package_name($grp_key);
my $grp_disp = lc get_disp_name($grp_key);
my $grp_pl = lc get_class_info($grp_key)->get_plural_name;
my $asset_grp_pkg = get_package_name('asset_grp');
my $asset_grp_keys = { story_grp      => 1,
                       media_grp      => 1,
                       template_grp => 1 };
# Check to see if it's an asset group.
my $chk_asset_grp = sub {
    my $classes = shift->get_supported_classes;
    return 1 if $classes->{'Bric::Biz::Asset'}
      || $classes->{'Bric::Biz::Asset::Template'}
      || $classes->{'Bric::Biz::Asset::Business'}
      || $classes->{'Bric::Biz::Asset::Business::Story'}
      || $classes->{'Bric::Biz::Asset::Business::Media'}
      || $classes->{'Bric::Biz::Asset::Business::Media::Image'}
      || $classes->{'Bric::Biz::Asset::Business::Media::Audio'}
      || $classes->{'Bric::Biz::Asset::Business::Media::Video'};
    return 0;
};
</%once>

%#--- Init ---#
<%init>;
# Check permissions. The user must have EDIT permission to the group and
# at least READ permission to its members.
chk_authz($grp, EDIT);
my $id = $grp->get_id;
chk_authz(0, READ, 1, $id);

my $style = Bric::Util::Pref->lookup_val('Permissions Widget');
my $row_comp = ".${style}_row";
my $head_comp = ".${style}_head";
my $class_obj = $grp->my_class;
my $name = $grp->get_name;
$no_edit = $read_only;
my $curr_key = $class_obj->get_key_name;
my $is_user = $curr_key eq 'user_grp' ? 1 : 0;
my $perm_type = $ARGS{'perm_type'} || 'usrgrp';
</%init>

%#-- Shared Section --#
<%shared>;
my (%users, $no_edit);
</%shared>
<%def .radio_head>
% if ($_[0]) {
<div class="addnewitem"><% $_[0] %></div>
% } # if
<table class="listManager permissions">
    <tr>
        <th>Group</th>
% $m->out(qq{        <th class="radio">$_->[1]</th>\n}) for @$vals_aref;
    </tr>
</%def>

<%def .radio_row>
<%args>
$grp
$gid
$create => undef
$recall => undef
$publish => undef
$perm => undef
$name => undef
$type => 'usr'
$is_asset_grp => undef
$odd_row => 0
</%args>
<%init>;
$name ||= $grp->get_name;
my ($val, $pid) = (0, '');
if ($perm) {
    $val = $perm->get_value;
    $pid = $perm->get_id;
}
# Make sure the current user has at least READ permission to the group, and
# find out the maximum permission the current user has to the group  and to
# the objects in the group.
chk_authz($grp, READ, 1) or return;
my $max_perm = get_user_object->what_can(0, $gid);
return if $max_perm == DENY;

</%init>
<tr<% $odd_row ? ' class="odd"' : '' %>>
    <td><span class="label"><% $name %></span>
        <& '/widgets/profile/hidden.mc', value => $pid, name => "${type}_perm_id" &>
        <& '/widgets/profile/hidden.mc', value => $gid, name => "${type}_grp_id" &>
    </td>
% if ($no_edit) {
%     # It's read-only. Just show each permission.
%     foreach my $v (@$vals_aref) {
    <td class="radio"><% $v->[0] == $val ? 'Yes' : '&nbsp;' %></td>
%     } # foreach
% } else {
%     # They can edit it!
%     foreach my $v (@$vals_aref) {
%         if (!$max_perm || ($v->[0] != DENY && $v->[0] > $max_perm)) {
%             # Well, this permission for this group is read-only.
    <td class="radio"><% $v->[0] == $val ? 'Yes' : '&nbsp;' %></td>
%         } elsif ($v->[0] == CREATE && !$create && ($type eq 'usr' || !$grp->get_permanent)) {
%             # Create permission isn't allowed or is irrelevant.
    <td class="radio">&nbsp;</td>
%         } elsif ($v->[0] == RECALL && (!$recall || !$is_asset_grp)) {
%             # Recall permission isn't allowed or is irrelevant.
    <td class="radio">&nbsp;</td>
%         } elsif ($v->[0] == PUBLISH && (!$publish || !$is_asset_grp)) {
%             # Publish permission isn't allowed or is irrelevant.
    <td class="radio">&nbsp;</td>
%         } else {
%             # They can set this permission.
    <td class="radio">
        <input type="radio" value="<% $v->[0] %>" name="<% "$type|$gid" %>"<% $v->[0] == $val ? ' checked' : '' %> />
    </td>
%         } # if
%     } # foreach
% } # if
</tr>
</%def>

<%def .select_head>
<table border="1" cellpadding="2" cellspacing="0" width="580" style="border-style:solid; border-color:#cccc99;">
% if ($_[0]) {
    <tr>
    <td style="border-style:solid; border-color:#cccc99;" colspan="2"><% $_[0] %></td>
    </tr>
% } # if
    <tr class="medHeader">
        <th style="border-style:solid; border-color:#cccc99;">Group</th>
        <th style="border-style:solid; border-color:#cccc99;">Permission</th>
    </tr>
</%def>

<%def .select_row>
<%args>
$grp
$gid
$perm => undef
$name => undef
$create => undef
$publish => undef
$recall => undef
$is_asset_grp => undef
$type => 'usr'
</%args>
<%init>;
$name ||= $grp->get_name;
my ($val, $pid) = (0, '');
if ($perm) {
    $val = $perm->get_value;
    $pid = $perm->get_id;
}
# Make sure the current user has at least READ permission to the group, and
# find out the maximum permission the current user has to the group  and to
# the objects in the group.
chk_authz($grp, READ, 1) or return;
my $max_perm = get_user_object->what_can(0, $gid);
return if $max_perm == DENY;

my $opts = [@{$vals_aref}[0..$max_perm, 6]];
splice @$opts, PUBLISH, 1 unless $max_perm < PUBLISH || ($publish && $is_asset_grp);
splice @$opts, CREATE, 1 unless $max_perm < CREATE || $create || ($type ne 'usr' && $grp->get_permanent);
splice @$opts, RECALL, 1 unless $max_perm < RECALL || ($recall && $is_asset_grp);
</%init>
<tr>
    <td style="border-style:solid; border-color:#cccc99;" width="340"><span class="label"><% $name %></span>
        <& '/widgets/profile/hidden.mc', value => $pid, name => "${type}_perm_id" &>
        <& '/widgets/profile/hidden.mc', value => $gid, name => "${type}_grp_id" &>
    </td>
% if ($no_edit) {
    <td style="border-style:solid; border-color:#cccc99;" height="20"><% $vals_href->{$val} %></td>
% } else {
    <td style="border-style:solid; border-color:#cccc99;" height="20"><& '/widgets/profile/select.mc', name => "$type|$gid", value => $val,
           options => $opts, useTable => 0, readOnly => !$max_perm &>
    </td>
% } # if
</tr>
</%def>
<%def .site_categories>
<%args>
$site
$num
$row_comp
$head_comp
$grp_name
$perms
</%args>
<%perl>;
        $m->comp("/widgets/wrappers/sharky/table_top.mc",
                 number   => $num,
                 caption  => $lang->maketext('[_1] Site [_2] Permissions',
                                             $site->get_name, $cat_disp),
                 localize => 0);
        $m->comp($head_comp,
                 $lang->maketext('Grant "[_1]" members permission to access '
                                 . "assets in these categories.", $grp_name));

        my $site_id = $site->get_id;
        my $odd_row = 1;
        foreach my $cat_grp ($cat_grp_pkg->list({
                             name   => "Site $site_id Category Assets",
                             Order  => 'description',
                             all    => 1 }))
        {
            my $gid = $cat_grp->get_id;
            $odd_row = !$odd_row;
            $m->comp($row_comp,
                     grp => $cat_grp,
                     gid => $gid,
                     publish => 1,
                     recall => 1,
                     type => 'obj',
                     is_asset_grp => 1,
                     perm => $perms->{$gid},
                     name => $cat_grp->get_description,
                     odd_row => $odd_row
                 );
        }
        $m->out(qq{</table>\n});
        $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
</%perl>
</%def>
%#--- Log History ---#

