/*  Copyright (c) 2000 by Oracle Corporation. All Rights Reserved. */

package oracle.portal.provider.v1;

import java.io.PrintWriter;
import java.io.IOException;
import java.util.ResourceBundle;
import java.util.Locale;

import oracle.portal.provider.v1.resource.ProviderBundle;
import oracle.portal.provider.v1.http.ServletPortletRenderRequest;
import oracle.portal.utils.BiDiUtils;
import oracle.portal.utils.v1.ParameterMap;
import oracle.portal.utils.v1.SimpleParameterMap;
import oracle.webdb.utils.SimpleStringBuffer;

/**
 *  A PortletContainerRenderer is a utility class that renders the container
 *  for a portlet.
 * 
 *  The container that is renderered may vary depending on the SHOW mode that
 *  is being requested. For example, Edit, Edit Defaults. Help, About, and 
 *  Show Details are all rendered in "full screen" mode whereas the regular
 *  Show and Preview modes have variable size containers depending on the
 *  size of the portlet.
 */
public class DefaultContainerRenderer extends PortletContainerRenderer
{

    //Full screen mode border images
    private static final String TOP_IMAGE = "\"/images/FFFFFFsl.gif\"";
    private static final String TOP_BIDI_IMAGE = "\"/images/FFFFFFsr.gif\"";
    private static final String BOTTOM_IMAGE = "\"/images/FFFFFFbr.gif\"";
    private static final String BOTTOM_BIDI_IMAGE = "\"/images/FFFFFFbl.gif\"";
    
    private static final String TOP = "top";
    private static final String BOTTOM = "bottom";
    private static final String RIGHT = "right";
    private static final String LEFT = "left";

    /**
     *  Renders the header for the portlet SHOW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderShowHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        if (request.hasTitle())
        {
            renderPortletTitlebar(request, out, params);
        }

        if (request.hasBorder())
        {
            out.println("<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"2\""); 
            out.print(" CELLSPACING=\"0\" class=\"RegionBorder\">");
        }
        else
        {
            out.println("<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"2\""); 
            out.print(" CELLSPACING=\"0\" class=\"RegionNoBorder\">");
        }

        out.println("<TR><TD class=\"RegionHeaderColor\" WIDTH=\"100%\" ");
        out.print(BiDiUtils.getDirAttribute(request.getLocale()) + " >");
    }


    /**
     *  Renders the footer for the portlet SHOW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderShowFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        out.println("</TD></TR>");
        out.println("</TABLE>");
    }

    /**
     *  Renders the header for the portlet PREVIEW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderPreviewHeader(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        renderShowHeader(request, out, params);
    }


    /**
     *  Renders the footer for the portlet PREVIEW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderPreviewFooter(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        renderShowFooter(request, out, params);
    }

    /**
     *  Renders the header for the portlet SHOW_DETAILS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderDetailsHeader(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        // no header for DETAILS mode
    }


    /**
     *  Renders the footer for the portlet SHOW_DETAILS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderDetailsFooter(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        // no footer for DETAILS mode
    }


    /**
     *  Renders the header for the portlet EDIT mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderEditHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        boolean renderCustomize = true;
        Boolean renderCustomizeObj = 
            (Boolean)params.getParameterValue(PortletContainerRenderer.RENDER_CUSTOMIZE);

        if (renderCustomizeObj != null)
        {
            renderCustomize = renderCustomizeObj.booleanValue();
        }

        if (renderCustomize)
        {
            String helpURL = 
                (String)params.getParameterValue(PortletContainerRenderer.HELP_URL);
            String formName = 
                (String)params.getParameterValue(PortletContainerRenderer.EDIT_FORM_NAME);
            String actionParam = 
                (String)params.getParameterValue(PortletContainerRenderer.ACTION_PARAM_NAME);
            String title = 
                (String)params.getParameterValue(PortletContainerRenderer.PORTLET_TITLE);

            // default values if not provided
            if (formName == null)
            {
                formName = CUSTOMIZE_FORM_NAME;
            }

            if (actionParam == null)
            {
                actionParam = DEFAULT_ACTION_PARAM;
            }

            // default the portlet title if not specified
            if (title == null)
            {
                title = PortletRendererUtil.getModeTitle(request);
            }


            out.print("<FORM ACTION=\"");
            out.print(PortletRendererUtil.htmlFormActionLink(request,
                            PortletRendererUtil.PAGE_LINK));
            out.print("\" METHOD=\"POST\" NAME=\"");
            out.print(formName);
            out.println("\" ENCTYPE=\"application/x-www-form-urlencoded\">");

            out.println(PortletRendererUtil.emitHiddenField(actionParam, ""));
            out.println(PortletRendererUtil.htmlFormHiddenFields(request,
                                               PortletRendererUtil.PAGE_LINK));

            renderDesignFormBodyBegin(request, out, formName, title,
                                      actionParam, helpURL);
        }
    }

    /**
     *  Renders the footer for the portlet EDIT mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderEditFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        boolean renderCustomize = true;
        Boolean renderCustomizeObj = 
            (Boolean)params.getParameterValue(PortletContainerRenderer.RENDER_CUSTOMIZE);

        if (renderCustomizeObj != null)
        {
            renderCustomize = renderCustomizeObj.booleanValue();
        }

        if (renderCustomize)
        {
            renderDesignFormBodyEnd(request, out);
            out.println("</FORM>");
        }
    }

    /**
     *  Renders the header for the portlet EDIT_DEFAULTS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderEditDefaultsHeader(PortletRenderRequest request,
                                         PrintWriter out,
                                         ParameterMap params)
        throws PortletException, IOException
    {
        renderEditHeader(request, out, params);
    }


    /**
     *  Renders the footer for the portlet EDIT_DEFAULTS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderEditDefaultsFooter(PortletRenderRequest request,
                                         PrintWriter out,
                                         ParameterMap params)
        throws PortletException, IOException
    {
        renderEditFooter(request, out, params);
    }


    /**
     *  Renders the header for the portlet HELP mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderHelpHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderInformationFormHeader(request, out, params);
    }


    /**
     *  Renders the footer for the portlet HELP mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderHelpFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderInformationFormFooter(request, out, params);
    }


    /**
     *  Renders the header for the portlet HELP mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderAboutHeader(PortletRenderRequest request,
                                  PrintWriter out,
                                  ParameterMap params)
        throws PortletException, IOException
    {
        renderInformationFormHeader(request, out, params);
    }


    /**
     *  Renders the footer for the portlet HELP mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     */
    public void renderAboutFooter(PortletRenderRequest request,
                                  PrintWriter out,
                                  ParameterMap params)
        throws PortletException, IOException
    {
        renderInformationFormFooter(request, out, params);
    }


    /**
     *  Utility method for rendering the About/Help form.  This method should be
     *  used in conjunction with renderInformationFormFooter() to work correctly.
     *  This routine emits the proper html FORM tag, appropriate hidden fields,
     *  the standard look/feel for the Form container, and the customize form
     *  'Close' button.
     */
    protected void renderInformationFormHeader(PortletRenderRequest request,
                                               PrintWriter out,
                                               ParameterMap params)
        throws PortletException, IOException
    {
        String title = 
            (String)params.getParameterValue(PortletContainerRenderer.PORTLET_TITLE);
        String formName = 
            (String)params.getParameterValue(PortletContainerRenderer.EDIT_FORM_NAME);
        String actionParam = 
            (String)params.getParameterValue(PortletContainerRenderer.ACTION_PARAM_NAME);
        String helpURL = 
            (String)params.getParameterValue(PortletContainerRenderer.HELP_URL);

        // validate required parameters are available
        if (formName == null)
        {
            formName = CUSTOMIZE_FORM_NAME;
        }

        if (actionParam == null)
        {
            actionParam = DEFAULT_ACTION_PARAM;
        }

        // default the portlet title if not specified
        if (title == null)
        {
            title = PortletRendererUtil.getModeTitle(request);
        }

        out.println("<FORM>");
        renderDesignFormBodyBegin(request, out, formName,
                                  title, actionParam, helpURL);
    }

    /**
     *  Utility method for completing the rendering of the Help/About 
     *  information form. This method should be used in conjunction with 
     *  renderInformationFormHeader() to work correctly.  This routine emits the 
     *  proper html tags to close the FORM including the standard look/feel for 
     *  the Form container.
     *
     *  @param request the portlet render request.
     *  @param writer the response writer used to output the customize form 
     *  header.
     */
    protected void renderInformationFormFooter(PortletRenderRequest request,
                                               PrintWriter out,
                                               ParameterMap params)
        throws PortletException, IOException
    {
        renderDesignFormBodyEnd(request, out);
        out.println("</FORM>");
    }

    /**
     *  Utility method for rendering the Design forms.  This method should be
     *  used in conjunction with renderDessignFormFooter() to work correctly.
     *  This routine emits the proper html FORM tag, appropriate hidden fields,
     *  the standard look/feel for the Form container, and the appropriate form
     *  buttons (based on the rendermode).
     *
     *  @param request the portlet render request.
     *  @param writer the response writer used to output the customize form 
     *  header.
     *  @param formName the name used in the <FORM> tag's NAME attribute.  This 
     *  must be none null so appropriate javascript can be generated to set the
     *  <i>actionParam</i> value.
     *  @param title the to display in the header (titlebar)
     *  @param actionParam the name of the hidden field that will hold the value
     *  that indicates which button was clicked.  The value is 'OK' if the OK 
     *  button was clicked.  The value is 'APPLY' if the APPLY button is clicked
     *  @param helpURL  a URL to this customize form's help screen.  If null the
     *  help link is not displayed.
     */
    protected void renderDesignFormBodyBegin(PortletRenderRequest request,
                                             PrintWriter out,
                                             String formName,
                                             String title,
                                             String actionParam,
                                             String helpURL)
        throws IOException
    {
        ResourceBundle res = request.getProviderResource();
        Locale l = request.getLocale();

        // start container
        out.println("<CENTER>");
        out.println("<TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\"" + 
                    " WIDTH =\"90%\">");

        // Put Javascript to set button value
        // Needed so developers can set display value in appropriate language
        out.println("<SCRIPT LANGUAGE=\"JavaScript1.1\">");
        out.println("<!-- Comment out script for old browsers");
        out.println("function doSubmit(action) {");

        out.print("   document.");
        out.print(formName);
        out.print(".");
        out.print(actionParam);
        out.println(".value=action");

        out.print("   document.");
        out.print(formName);
        out.println(".submit()");
        
        out.println("}");
        out.println("//-->");
        out.println("</SCRIPT>");

        // draw title
        out.println("<TR><TD>");
        out.println("<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLPADDING=\"0\" " + 
                    "CELLSPACING=\"0\">");
        out.println("<TR>");
        out.println("<TD width=\"3%\" class=\"OraBgColorDark\">&nbsp;</TD>");

        if (helpURL != null)
        {
            out.print("<TD width=\"90%\" class=\"OraBgColorDark\">");
            out.print("<FONT class=\"OraGlobalPageTitle\">");
            out.print(title);
            out.println("</FONT></TD>");

            out.print("<TD width=\"6%\" valign=\"MIDDLE\"");
            out.print("class=\"OraBgColorDark\">" + 
                      "<A href=\"javascript:show_context_help('");
            out.print(helpURL);
            out.print("')\"><IMG src=\"/images/helps.gif\" alt=\"Help\" ");
            out.println("border=\"0\"></A></TD>");
        }
        else
        {
            out.print("<TD width=\"96%\" class=\"OraBgColorDark\">");
            out.print("<FONT class=\"OraGlobalPageTitle\">");
            out.print(title);
            out.println("</FONT></TD>");
        }
        out.println("<TD class=\"OraBgColorDark\">&nbsp;</TD>");
        out.println("</TR>");
        out.println("</TABLE>");
        out.println("</TD></TR>");

        // draw header
        out.println("<TR><TD>");
        out.println("<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\"" + 
                    " width=\"100%\">");
        out.println("<TR>");
        out.println("<TD rowspan=\"2\" valign=\"TOP\">");
        out.println("<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");
        out.println("<TR>");
        out.println("<TD valign=\"TOP\" class=\"OraBgColorDark\"><IMG src="
                    + getBorderImage(l, TOP) +
                    " valign=\"TOP\" border=\"0\"></TD>");
        out.println("</TR>");
        out.println("</TABLE>");
        
        out.println("</TD>");
        out.println("<TD rowspan=\"2\" valign=\"TOP\">" +
                    "<IMG src=images/compedit.gif%5C valign=\"TOP\" " +
                    "border=\"0\"></TD>");
        out.println("<TD align=\""+ BiDiUtils.getAlignment(l, RIGHT) +
                    "\" valign=\"TOP\" width=\"100%\">");
        out.println("<TABLE border=\"0\" cellpadding=\"1\" cellspacing=\"4\">");
        out.println("<TR>");

        // draw buttons
        if (request.getMode() == PortletRenderer.MODE_EDIT || 
            request.getMode() == PortletRenderer.MODE_EDIT_DEFAULTS) 
        {
            out.print("<TD BGCOLOR=\"#999999\"><INPUT TYPE=\"button\" ");
            out.print("NAME=\"p_request\" VALUE=\"");
            out.print(res.getString(ProviderBundle.APPLY_LABEL));
            out.println("\" onClick=\"javascript:doSubmit('APPLY')\"></TD>");

            out.print("<TD BGCOLOR=\"#999999\"><INPUT TYPE=\"button\" ");
            out.print("NAME=\"p_request\" VALUE=\"");
            out.print(res.getString(ProviderBundle.OK_LABEL));
            out.println("\" onClick=\"javascript:doSubmit('OK')\"></TD>");

            out.print("<TD BGCOLOR=\"#999999\"><INPUT TYPE=\"button\" ");
            out.print("NAME=\"p_request\" VALUE=\"");
            out.print(res.getString(ProviderBundle.CANCEL_LABEL));
            out.print("\" onClick=\"javascript:window.location='");
            out.print(request.getBackURL());
            out.println("'\"></TD>");
        }
        else
        {
            out.print("<TD BGCOLOR=\"#999999\"><INPUT TYPE=\"button\" ");
            out.print("NAME=\"p_request\" VALUE=\"");
            out.print(res.getString(ProviderBundle.CLOSE_LABEL));
            out.print("\" onClick=\"javascript:window.location='");
            out.print(request.getBackURL());
            out.println("'\"></TD>");
        }

        out.println("</TR>");
        out.println("</TABLE>");
        out.println("</TD>");
        out.println("</TR>");
        out.println("</TABLE>");
        out.println("</TD></TR>");

        // end container
        out.println("</TABLE>");
        out.println("</CENTER>");

        // start Table for design form/display
        out.println("<CENTER>");
        out.println("<TABLE  WIDTH=\"90%\" BORDER=\"0\" CELLPADDING=\"0\" " + 
                    "CELLSPACING=\"0\">");
        out.println("<TR><TD><BLOCKQUOTE><BLOCKQUOTE>");
        out.println("<TABLE>");
    }

    /**
     *  Utility method for completing the rendering of the Design form.
     *
     *  This method should be used in conjunction with renderDesignFormHeader()
     *  to work correctly. This routine emits the proper html tags to close
     *  the FORM including the standard look/feel for the Form container.
     *
     *  @param request the portlet render request.
     *  @param out the writer used to emit the html.
     */
    protected void renderDesignFormBodyEnd(PortletRenderRequest request,
                                           PrintWriter out)
        throws IOException
    {
        Locale l = request.getLocale();
        
        // complete the form table
        out.println("</TABLE>");
        out.println("</BLOCKQUOTE></BLOCKQUOTE></TD></TR>");
        out.println("</TABLE>");
        out.println("</CENTER>");

        // now write the footer
        out.println("<CENTER>");
        out.println("<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\" ");
        out.print("width=\"90%\">");
        out.println("<TR>");
        out.println("<TD><IMG src=\"/images/pobtrans.gif\" width=\"1\" "); 
        out.print("height=\"8\"></TD>");
        out.println("</TR>");
        out.println("<TR>");
        out.println("<TD>");

        // begin new style design form
        out.println("<TABLE width=\"100%\" border=\"0\" cellpadding=\"0\" "); 
        out.print("cellspacing=\"0\">");
        out.println("<TR>");
        out.println("<TD align=\""+ BiDiUtils.getAlignment(l, RIGHT) +"\">");
        out.println("<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");
        out.println("<TR>");
        out.println("<TD align=\""+ BiDiUtils.getAlignment(l, RIGHT) + "\" "\""); 
        out.print("class=\"OraBgColorDark\"><IMG src=");
        out.print(getBorderImage(l, BOTTOM));
	out.print("></TD>");
        out.println("</TR>");
        out.println("</TABLE>");
        out.println("</TD>");
        out.println("</TR>");
        out.println("<TR>");
        out.println("<TD height=\"14\" class=\"OraBgColorDark\">&nbsp;</TD>");
        // end new style design form

        out.println("</TR>");
        out.println("</TABLE>");
        out.println("</TD>");
        out.println("</TR>");
        out.println("</TABLE>");
        out.println("</CENTER>");
    }


    /**
     *  Renders a portlet's titlebar. Portlets are responsible for rendering
     *  their container.  This method renders the standard portlet titlebar
     *  using information from the request and Portlet meta-data. Typically,
     *  clients will not use this method.  Rather they wil rely on
     *  renderPortletBegin() to render the entire container including the
     *  titlebar.  If however, renderPortletBegin is not used, this method is
     *  provided for convenience.
     *
     *  @param request the portlet render request
     *  @param title the label that should be displayed as the title.  If 
     *  <b>null</b> then the method will render the static title retrieved via 
     *  Portlet.getTitle();
     */
    protected void renderPortletTitlebar(PortletRenderRequest request,
                                         PrintWriter out,
                                         ParameterMap params)
        throws PortletException, IOException
    {
        int renderMode = request.getMode();
        Portlet p = request.getPortlet();

        String title = 
            (String)params.getParameterValue(PortletContainerRenderer.PORTLET_TITLE);
        if (title == null)
        {
            try
            {
                title = PortletRendererUtil.getTitle(request);
            }
            catch (AccessControlException e)
            {
                throw new PortletException(e);
            }
        }

        out.print("<TABLE BORDER=\"0\" class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_COLOR);
        out.println("\" CELLSPACING=\"0\" CELLPADDING=\"0\" WIDTH=\"100%\">");

        out.print("<TR class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_COLOR);
        out.println("\">");

        out.print("<TD class=\"");
        out.print(PortletRenderer.LEFT_CURVE);
        out.print("\" valign=\"top\" width=\"10\" ");
        out.println("height=\"10\" NOWRAP>   </TD>");

        if (p.hasShowDetails() && !(renderMode == PortletRenderer.MODE_PREVIEW))
        {
            renderTitle(request,
                        title,
                        out,
                        p,
                        getAnchorRef(request,
                                     p,
                                     PortletRenderer.MODE_SHOW_DETAILS,
                                     title));
        }
        else
        {
            renderTitle(request, title, out, p, null);
        }

        if (renderMode == PortletRenderer.MODE_PREVIEW)
        {
            renderDummyActions(out, p, request);
        }
        else
        {
            renderActions(out, p, request, title);
        }

        out.print("</TD><TD class=\"");
        out.print(PortletRenderer.RIGHT_CURVE);
        out.println("\" width=\"10\" NOWRAP>  </TD></TR>");
        out.println("</TABLE>");
    }

    protected void renderTitle(PortletRenderRequest request,
                                    String title,
                                    PrintWriter out,
                                    Portlet p,
                                    String href)
        throws java.io.IOException
    {
        String endAnchor;
        if (href == null) 
        {
            href = "";
            endAnchor = "";
        } 
        else
        {
            endAnchor = "</a>";
        }

        out.print("<TD class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_COLOR);
        out.print("\" NOWRAP=\"\" valign=\"top\" width=\"100%\">");
        out.print(href);
        out.print("<font class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_TEXT);
        out.print("\">");
        out.print(title);
        out.print(" </font>");
        out.print(endAnchor);
        out.println("   </TD>");
    }

    protected void renderActions(PrintWriter out,
                                      Portlet p,
                                      PortletRenderRequest request,
                                      String title)
        throws java.io.IOException
    {
        out.print("<TD class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_COLOR);
        out.println("\" NOWRAP=\"\" valign=\"top\"> ");

        ResourceBundle res = request.getProviderResource();

        if (p.hasShowEdit())
        {
            boolean showCustomize = false;
            if (p instanceof PortletXtra3)
            {
                // determine if user should be able to see customize link based
                // in new authentication level based methods

                // only show the customize link if the user's authentication level
                // is greater than or equal to the minimum authentication level
                // specified by the portlet.
                PortletXtra3 p3 = (PortletXtra3)p;
                int userAuthLevel = request.getUser().getAuthenticationLevel();
                showCustomize = (userAuthLevel >= p3.getMinEditAuthLevel());
            }
            else
            {
                // portlet does not support the newer interface required for the
                // check above so use the old, deprecated method
                showCustomize = (!request.getUser().isPublicUser() ||
                                 p.getShowEditToPublic());
            }

            if (showCustomize)
            {
                renderAction(out, p, request, PortletRenderer.MODE_EDIT, 
                             res.getString(ProviderBundle.CUSTOMIZE_LABEL), 
                             title);
            }
        }

        if (p.hasHelp()) 
        {
            renderAction(out, p, request, PortletRenderer.MODE_HELP,
                         res.getString(ProviderBundle.HELP_LABEL), title);
        }


        if (p.hasAbout()) 
        {
            renderAction(out, p, request, PortletRenderer.MODE_ABOUT, 
                         res.getString(ProviderBundle.ABOUT_LABEL), title);
        }
    }

    protected void renderAction(PrintWriter out,
                                Portlet p,
                                PortletRenderRequest request,
                                int action,
                                String label,
                                String title)
        throws java.io.IOException
    {
        out.print(getAnchorRef(request, p, action, title));
        out.print("<font class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_LINK);
        out.print("\">");
        out.print(label);
        out.println("</font></a> ");
    }

    protected void renderDummyActions(PrintWriter out,
                                      Portlet p,
                                      PortletRenderRequest request)
        throws java.io.IOException
    {
        out.print("<TD class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_COLOR);
        out.println("\" NOWRAP=\"\" valign=\"top\"> ");

        ResourceBundle res = request.getProviderResource();

        if (p.hasShowEdit()) 
        {
            renderDummyAction(out, 
                              res.getString(ProviderBundle.CUSTOMIZE_LABEL));
        }

        if (p.hasHelp()) 
        {
            renderDummyAction(out, res.getString(ProviderBundle.HELP_LABEL));
        }

        if (p.hasAbout()) 
        {
            renderDummyAction(out, res.getString(ProviderBundle.ABOUT_LABEL));
        }
    }

    protected void renderDummyAction(PrintWriter out, String label)
        throws java.io.IOException
    {
        out.print("<font class=\"");
        out.print(PortletRenderer.PORTLET_HEADER_LINK);
        out.print("\">");
        out.print(label);
        out.println("</font> ");
    }

    protected String getAnchorRef(PortletRenderRequest request,
                                  Portlet p,
                                  int mode,
                                  String title)
        throws java.io.IOException
    {
        String ref = request.getDesignURL();
        SimpleStringBuffer newRef = new SimpleStringBuffer(100);

        // Portal 3.0.6.3.3 incorrectly passes the mode in the URL (as Edit) -- 
        // to work around this prepend our parameters.  When no longer need work
        // around remove this code and uncomment out the below.

        int i = ref.indexOf("?");

        newRef.append("<a href=\"");
        if (i != -1)
        {
            newRef.append(ref.substring(0, i + 1));
            newRef.append("_mode=");
            newRef.append(mode);
            newRef.append("&_title=");
            newRef.append(PortletRendererUtil.encodeParameter(title, request));
            newRef.append("&");
            newRef.append(ref.substring(i+1));
        }
        else
        {
            newRef.append(ref);
            newRef.append("?_mode=");
            newRef.append(mode);
            newRef.append("&_title=");
            newRef.append(PortletRendererUtil.encodeParameter(title, request));
        }
        newRef.append("\">");
        return newRef.toString() ;
    }

    static private String getBorderImage(Locale l, String vAlignment)
    {
        if(BiDiUtils.isBiDi(l))
        {
            if(vAlignment.equals(TOP))
            {
                return TOP_BIDI_IMAGE;
            }
            else
            {
                return BOTTOM_BIDI_IMAGE;
            }
        }
        else
        {
            if(vAlignment.equals(TOP))
            {
                return TOP_IMAGE;
            }
            else
            {
                return BOTTOM_IMAGE;
            }
        }
    }
}


