/*
 * Created on 10-Feb-2005
 */
package org.bodington.servlet.facilities;

import java.awt.Color;
import java.io.PrintWriter;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.ServletException;

import org.apache.log4j.Logger;
import org.bodington.server.BuildingContext;
import org.bodington.server.BuildingServerException;
import org.bodington.server.BuildingSession;
import org.bodington.server.BuildingSessionManagerImpl;
import org.bodington.server.realm.Group;
import org.bodington.server.realm.PassPhrase;
import org.bodington.server.realm.Permission;
import org.bodington.server.realm.User;
import org.bodington.server.resources.Resource;
import org.bodington.servlet.Request;
import org.bodington.util.BodingtonURL;

/**
 * Class used for display the current permissions of a resource.
 * @author buckett
 */
public class AclDisplayFacility
{
    
    private static Logger log = Logger.getLogger(AclDisplayFacility.class);
   
    
    /**
     * Display a table of permissions for the current resource.
     * We don't need to do any check as only people with VIEW access to the
     * resource will be able to see this page.
     * @param out The PrintWriter where the HTML is written.
     * @throws ServletException If we can't get the current resource.
     */
    public static void outputAclTable(PrintWriter out, Request request) throws ServletException
    {
        Set set;
        Enumeration permissions;
        Color highlightColor1, highlightColor2;
        Resource resource = request.getResource();
        try
        {
            AclResource aclResource = new AclResource(resource, resource
                .checkPermission(Permission.ADMINISTER)
                || resource.checkPermission(Permission.SYSADMIN));
            if (BuildingContext.getContext().getResource().checkPermission(Permission.MANAGE))
            {
                set = aclResource.getResults();
            }
            else 
            {
                set = aclResource.getResults((User)BuildingContext.getContext().getUser());
            }
            
            BuildingSession session = BuildingSessionManagerImpl.getSession(BuildingContext.getContext().getResource());
            highlightColor1 = session.getPropertyColor("style_navigation_menu_highlight_colour_1");
            highlightColor2 = session.getPropertyColor("style_navigation_menu_highlight_colour_2");

        }
        catch (BuildingServerException e)
        {
            throw new ServletException(e);
        }
        out.println("<table>");
        out.println("<tr>");
        out.println("<th>Name</th>");
        out.println("<th>Groups</th>");
        out.println("<th colspan=\"10\" style=\"text-align: center;\">Permissions</th>");
       out.println("</tr>");

       
        Iterator rows =  set.iterator();
        
        
        boolean doHighlighting = !(highlightColor1 == null || highlightColor2 == null);
        int row = 0;
        while (rows.hasNext())
        {
            if (row % 10 == 0)
            {
                outputPermissionsHeader(out);
            }
            
            AclResourcePermission resourcePermission  = (AclResourcePermission)rows.next();
            if (doHighlighting)
            {
                out.println("<tr style=\"background-color: " + Utils.toCSSColor((row %2 == 0)?highlightColor1:highlightColor2) + "\">");
            }
            else 
            {
                out.println("<tr>");
            }
            
            
            out.print("<td>");
            if (resourcePermission.getUser() != null)
            {
                out.print(resourcePermission.getUser().getName());
                try
                {
                    PassPhrase pass = PassPhrase.findPassPhrase(resourcePermission.getUser());
                    if (pass != null)
                    {
                        out.print("<br/>");
                        out.print("<span style=\"font-size: 50%\">(");
                        out.print(pass.getUserName());
                        out.print(")</span>");
                    }
                }
                catch (BuildingServerException bse)
                {
                    ;
                }
            }
            
            out.println("</td>");
            
            out.print("<td>");
            Iterator groups = resourcePermission.getGroups();
            if (groups.hasNext()) {
                out.print(formatGroup((Group)groups.next(),  request));
                
                while(groups.hasNext())
                {
                    out.print(", ");
                    out.print(formatGroup((Group)groups.next(), request));
                }
            }
            out.println("</td>");
            
            permissions = Permission.permissions();
            while(permissions.hasMoreElements())
            {
                out.print("<td>");
                outputPermission(request, out, resourcePermission.hasPermission((Permission)permissions.nextElement()));
                out.println("</td>");
            }
            
            out.print("</tr>");

            row++;
        }
        
        out.println("</table>");
        
    }
    
    private static void outputPermission(Request request, PrintWriter out, boolean hasPermission)
    {
        out.write("<img src=\"");
		out.write(request.getContextPath());
		out.write("/icons/");
		out.write((hasPermission)?"smalltick.gif":"smallcross.gif");
		out.write("\" alt=\""+ ((hasPermission)?"Tick":"Cross") +"\"/>");
    }
    
    /**
     * Outputs the permissions header.
     * @param out
     */
    private static void outputPermissionsHeader(PrintWriter out)
    {
        out.println("<tr style=\"font-size: 50%;\">");
        out.println("<th colspan=\"2\"></th>");
        
        Enumeration permissions;
        permissions = Permission.permissions();
        
        while(permissions.hasMoreElements())
        {
               out.print("<th>");
               out.print(permissions.nextElement());
               out.println("</th>");
           }
           out.println("</tr>");
    }

    /**
     * Format the group information in a HTML link. Display the URL for adhoc and owners 
     * groups and use the group name in all other cases.
     * @param group The group to display.
     * @return A HTML String linking to the group.
     */
    private static String formatGroup(Group group, Request request)
    {
        BodingtonURL url = new BodingtonURL( request );
        try
        {
            String groupURL = url.getResourceUrl(group.getResource())+ "bs_template_accessgroup.html?group_id="+ group.getPrimaryKey();
            String groupName;
            if (group.isLocalGroup())
            {
                groupName = group.getResource().getFullName() + group.getLocalName();
            }
            else
            {
                groupName = group.getName();
            }
            return "<a target=\"_new\" href=\""+groupURL+ "\">"+ groupName+"</a>";
        }
        catch (BuildingServerException bse)
        {
            log.warn("Problem trying to load group information.", bse);
        }
        
        return "";
        
    }

}
