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

package oracle.portal.provider.v1;

import java.io.PrintWriter;
import java.io.IOException;

import oracle.portal.utils.v1.ParameterMap;
import oracle.portal.utils.v1.SimpleParameterMap;

import oracle.portal.provider.v1.http.PerformanceLoggerAccessor;
import oracle.portal.provider.v1.http.PerformanceLogger;

/**
 *  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 abstract class PortletContainerRenderer 
{
    /**
     * Portlet title.
     * Usually this is the customizable title in SHOW mode and a mode
     * specific title describing the mode
     */
    public static final String PORTLET_TITLE = "_portletTitle";

    /**
     * Used to determine the render mode the title should be rendered for.
     * If this parameter is not passed, the render mode will be determined from
     * the PortletRenderRequest.
     * This parameter is included for backwards compatibility with 
     * PortletRendererUtil.renderPortletHeader()
     */
    public static final String RENDER_MODE = "_renderMode";

    /**
     * Used to determine whether customize header should be rendered
     * by the container renderer
     */
    public static final String RENDER_CUSTOMIZE = "_renderCustomize";

    /**
     * Name of the edit form to be used when renderering edit/edit defaults
     * headers/footers
     */
    public static final String EDIT_FORM_NAME = "_editFormName";

    /**
     * Name of the edit form to be used when renderering edit/edit defaults
     * headers/footers
     */
    public static final String ACTION_PARAM_NAME = "_actionParamName";

    /**
     * A URL that can be used to render a help link in full-screen modes.
     * eg use this to render a help link in EDIT or EDIT DEFAULTS mode.
     * This is NOT the URL that is used to access the portlets HELP mode.
     */
    public static final String HELP_URL = "_helpURL";

    /**
     * Default form name.
     * This value is used for the customize form name if a value is not supplid
     * in the parameter map
     */
    public static final String CUSTOMIZE_FORM_NAME = "custform";

    /**
     * Default action parameter name.
     * This value is used for the name of the hidden field that will capture the
     * form action (button pressed) if a value is not supplied by the caller
     * in the parameter map
     */
    public static final String DEFAULT_ACTION_PARAM = "action";

    /**
     * PrintWriter that should be used to render the output.
     * The value of this parameter is the PrintWriter object that should be
     * used to render the portlet header or footer.
     * If this parameter is not specified, the PrintWriter from the
     * PortletRenderRequest.getWriter() will be used.
     * If you are calling RenderPortletHeader or RenderPortletFooter from 
     * a JSP, it is important that you use the same Writer to render all the
     * JSP content - either the JSPWriter or PortletRenderRequest.getWriter().
     * Mixing writers can cause output to be displayed out of sequence due to
     * buffering in the JSPWriter.
     */
    public static final String PRINT_WRITER = "_printWriter";


    /** Renders a portlet header
     * 
     * The container that is rendered should be dependent on the mode that is
     * being renderered
     *
     * @param pr PortletRenderRequest for this rendering.
     * @param params Parameters for rendering the container
     */
    public void renderPortletHeader(PortletRenderRequest request,
                                    ParameterMap params)
        throws PortletException
    {
        // Don't render headers / footers for mobile devices
        if(!request.getContentType().equals(PortletRenderer.TYPE_HTML))
        {
            return;
        }

        // Start logging the the header render time here if there is a 
        // performance logger associated with the render request.
        PerformanceLogger logger = null;
        if (request instanceof PerformanceLoggerAccessor)
        {
            PerformanceLoggerAccessor pla = (PerformanceLoggerAccessor)request;
            logger = pla.getPerformanceLogger();
            logger.startRenderHeader();
        }

        PrintWriter writer = null;
        int renderMode = request.getMode();
        try
        {
            if (params == null)
            {
                // params was sent in as null - create a parameter map so we
                // don't have to keep checking for null in all subroutines.
                params = new SimpleParameterMap();
                writer = request.getWriter();
            }
            else
            {
                writer = (PrintWriter)params.getParameterValue(PRINT_WRITER);
                if (writer == null)
                {
                    // PrintWriter was not passed, so use the PortletRenderRequest
                    writer = request.getWriter();
                }

                Integer renderModeObj = (Integer)params.getParameterValue(RENDER_MODE);
                if (renderModeObj != null)
                {
                    renderMode = renderModeObj.intValue();
                }
            }
        
            switch (renderMode)
            {
            case PortletRenderer.MODE_SHOW:
                renderShowHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_PREVIEW:
                renderPreviewHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_ABOUT:
                renderAboutHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_HELP:
                renderHelpHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT:
                renderEditHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT_DEFAULTS:
                renderEditDefaultsHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_SHOW_DETAILS:
                renderDetailsHeader(request, writer, params);
                break;
            }
        }
        catch (Exception e)
        {
            throw new PortletException(e);
        }

        // If the request has an associated performance logger, stop the timer
        // that was started at the beginning of this method.
        if (request instanceof PerformanceLoggerAccessor)
        {
            logger.finishRenderHeader();
        }
    }

    /** Renders a portlet footer.
     *
     * The container that is rendered should be dependent on the mode that is
     * being renderered
     *
     * @param request PortletRenderRequest for this rendering
     * @param params Parameters for rendering the container
     */
    public void renderPortletFooter(PortletRenderRequest request,
                                    ParameterMap params)
        throws PortletException
    {
        // Don't render headers / footers for mobile devices
        if(!request.getContentType().equals(PortletRenderer.TYPE_HTML))
        {
            return;
        }

        // Start logging the the footer render time here if there is a 
        // performance logger associated with the render request.
        PerformanceLogger logger = null;
        if (request instanceof PerformanceLoggerAccessor)
        {
            PerformanceLoggerAccessor pla = (PerformanceLoggerAccessor)request;
            logger = pla.getPerformanceLogger();
            logger.startRenderFooter();
        }

        PrintWriter writer = null;
        int renderMode = request.getMode();
        try
        {
            if (params == null)
            {
                // params was sent in as null - create a parameter map so we
                // don't have to keep checking for null in all subroutines.
                params = new SimpleParameterMap();
                writer = request.getWriter();
            }
            else
            {
                writer = (PrintWriter)params.getParameterValue(PRINT_WRITER);
                if (writer == null)
                {
                    // PrintWriter was not passed, so use the PortletRenderRequest
                    writer = request.getWriter();
                }

                Integer renderModeObj = (Integer)params.getParameterValue(RENDER_MODE);
                if (renderModeObj != null)
                {
                    renderMode = renderModeObj.intValue();
                }
            }

            switch (renderMode)
            {
            case PortletRenderer.MODE_SHOW:
                renderShowFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_PREVIEW:
                renderPreviewFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_ABOUT:
                renderAboutFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_HELP:
                renderHelpFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT:
                renderEditFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT_DEFAULTS:
                renderEditDefaultsFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_SHOW_DETAILS:
                renderDetailsHeader(request, writer, params);
                break;
            }
        }
        catch(Exception e)
        {
            throw new PortletException(e);
        }

        // If the request has an associated performance logger, stop the timer
        // that was started at the beginning of this method.
        if (request instanceof PerformanceLoggerAccessor)
        {
            logger.finishRenderFooter();
        }
    }



    /**
     *  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
    {
        // override this method to create your show header
    }


    /**
     *  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
    {
        // override this method to create your SHOW footer here
    }

    /**
     *  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
    {
        // override this method to create your preview header here.
        // Preview is usually the same as SHOW but links are not active
    }


    /**
     *  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
    {
        // override this method to create your preview footer
        // Preview is usually the same as SHOW but links are not active
    }

    /**
     *  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
    {
        // override this method to create your header for show details
    }


    /**
     *  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
    {
        // override this method to create your footer for show details
    }


    /**
     *  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
    {
        // override this method to create your edit header
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     *  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
    {
        // override this method to create your edit footer
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     *  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
    {
        // override this method to create your edit defaults header
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     *  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
    {
        // override this method to create your edit defaults footer
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     *  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
    {
        // override this method to create your help header
        // HELP and ABOUT usually use the same container
    }


    /**
     *  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
    {
        // override this method to create your help footer
        // HELP and ABOUT usually use the same container
    }


    /**
     *  Renders the header for the portlet ABOUT 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
    {
        // override this method to create your about header
        // HELP and ABOUT usually use the same container
    }


    /**
     *  Renders the footer for the portlet ABOUT 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
    {
        // override this method to create your about footer
        // HELP and ABOUT usually use the same container
    }



}


