/* Copyright (c) 2001, Oracle Corporation. All rights reserved. */

package oracle.portal.provider.v2.event;

import oracle.portal.provider.v2.PortletException;
import oracle.portal.provider.v2.PortletDefinition;
import oracle.portal.provider.v2.render.PortletRenderer;
import oracle.portal.provider.v2.render.PortletRenderRequest;
import oracle.portal.provider.v2.url.UrlUtils;
import oracle.portal.utils.NameValue;
import oracle.webdb.utils.SimpleStringBuffer;

/**
 * Contains utility methods and constants for events.
 */
public class EventUtils
{
    /**
     * prefix used for url parameters that correspond to
     * portlet event parameters.
     */
    private static final String EVENT_PARAMETER_PREFIX = "_event_";

    /**
     * prefix used for url parameters that correspond to
     * portlet event names.
     */
    private static final String EVENT_NAME_PREFIX = "_eventName_";

    /**
     * Returns the url parameter name to use for the input
     * event parameter name.
     *
     * When rendering event parameters in html links or forms
     * the url parameter names should always be generated by this method.
     *
     * @param name event parameter name.
     * @return equivalent url parameter name.
     */
    public static String eventParameter(String name)
    {
        return EVENT_PARAMETER_PREFIX + name;
    }

    /**
     * Returns the url parameter name to use for the input event name.
     *
     * When rendering an event name in html links or forms
     * the url parameter name should always be generated by this method.
     *
     * @param name event name.
     * @return equivalent url parameter name.
     */
    public static String eventName(String name)
    {
        return EVENT_NAME_PREFIX + name;
    }

    /**
     * Create a parameterized link for a portlet event.
     *
     * Note the input event parameter names should be the base
     * name not an equivalent url parameter name obtained from
     * eventParameter(String name).
     *
     * Consequently if you want to render a link that both
     * contains event parameters and additional private portlet
     * parameters you will have to construct it manually using
     * the parameterizeLink method.
     *
     * @param pr              the render request.
     *
     * @param eventName       the event name.
     *
     * @param eventParameters an array of NameValue objects representing
     *                        the event parameter names and associated values.
     *                        Names cannot be NULL.
     *
     * @param encodeParams    flag indicating whether the parameter names and
     *                        values should be URL encoded using the multibyte
     *                        URL encoder.
     *
     * @param replaceParams   flag indicating whether parameters contained in
     *                        the params array should replace existing
     *                        parameters of the same name.
     *                        true = replace or overwrite existing parameters.
     *                        false = simply add parameters.
     */
    public static String constructEventLink(PortletRenderRequest pr,
                                            String eventName,
                                            NameValue[] eventParameters,
                                            boolean encodeParams,
                                            boolean replaceParams)
        throws PortletException
    {
        try
        {
            // must convert event name and event parameters
            // into url parameters

            NameValue[] urlParameters;
            if (eventParameters == null)
            {
                urlParameters = new NameValue[1];

                // add event name
                urlParameters[0] = new NameValue( eventName(eventName), "" );
            }
            else
            {
                urlParameters = new NameValue[eventParameters.length+1];

                // add event parameters
                int i;
                for ( i=0; i<eventParameters.length; i++)
                {
                    String name  = eventParameters[i].getName();
                    String value = eventParameters[i].getValue();
                    if (name != null)
                    {
                      urlParameters[i] = new NameValue( eventParameter(name), value );
                    }
                }

                // add event name
                urlParameters[i] = new NameValue( eventName(eventName), "" );
            }

            // return complete url
            return UrlUtils.constructLink(
                             pr,
                             UrlUtils.EVENT_LINK,
                             urlParameters,
                             encodeParams,
                             replaceParams);
        }
        catch (Exception e)
        {
            throw new PortletException(e);
        }
    }

    /**
     * Builds parameterized parameters for a portlet event.
     *
     * Note the input event parameter names should be the base
     * name not an equivalent url parameter name obtained from
     * eventParameter(String name).
     *
     * Consequently if you want to render a link that both
     * contains event parameters and additional private portlet
     * parameters you will have to construct it manually using
     * the parameterizeLink method.
     *
     * @param pr              the render request.
     *
     * @param eventName       the event name.
     *
     * @param eventParameters an array of NameValue objects representing
     *                        the event parameter names and associated values.
     *                        Names cannot be NULL.
     * @return parameterized name value pairs
     */
    private static NameValue[] buildEventParameters(
                                            PortletRenderRequest pr,
                                            String eventName,
                                            NameValue[] eventParameters)
        throws PortletException
    {
        try
        {
            // must convert event name and event parameters
            // into url parameters

            NameValue[] urlParameters;
            if (eventParameters == null)
            {
                urlParameters = new NameValue[1];

                // add event name
                urlParameters[0] = new NameValue( eventName(eventName), "" );
            }
            else
            {
                urlParameters = new NameValue[eventParameters.length+1];

                // add event parameters
                int i;
                for ( i=0; i<eventParameters.length; i++)
                {
                    String name  = eventParameters[i].getName();
                    String value = eventParameters[i].getValue();
                    if (name != null)
                    {
                      urlParameters[i] = new NameValue( eventParameter(name), value );
                    }
                }

                // add event name
                urlParameters[i] = new NameValue( eventName(eventName), "" );
            }

            // return the parameterized parameters
            return urlParameters;
        }
        catch (Exception e)
        {
            throw new PortletException(e);
        }
    }

    /**
     * Helper method for rendering event image links.
     *
     * @param pr            portlet render request.
     * @param image         name of the image to use.
     * @param name          event name.
     * @param parameters    event parameter name/values.
     * @param encodeParams  encode parameter name/values?
     * @param replaceParams replace base url parameters of same name?
     *
     *  @deprecated use EventUtils.eventImageLink(PortletRenderRequest,
     *      String, String, String, NameValue[], boolean, boolean)
     */
    public static String eventImageLink(PortletRenderRequest pr,
                                        String image,
                                        String name,
                                        NameValue[] params,
                                        boolean encodeParams,
                                        boolean replaceParams)
        throws PortletException
    {
        return eventImageLink(pr, image, "", name, params, 
                              encodeParams, replaceParams);
    }

    /**
     * Helper method for rendering event image links.
     *
     * @param pr            portlet render request.
     * @param image         name of the image to use.
     * @param imageAltText  Text description of the image, used by JAWS
     *                      so blind person can know what the image does.
     *                      can be null, empty or a string
     * @param name          event name.
     * @param parameters    event parameter name/values.
     * @param encodeParams  encode parameter name/values?
     * @param replaceParams replace base url parameters of same name?
     */
    public static String eventImageLink(PortletRenderRequest pr,
                                        String image,
                                        String imageAltText,
                                        String name,
                                        NameValue[] params,
                                        boolean encodeParams,
                                        boolean replaceParams)
        throws PortletException
    {
        String theLink;
        NameValue[] urlParameters = buildEventParameters(
                                            pr,
                                            name,
                                            params);

        SimpleStringBuffer imageAttr = new SimpleStringBuffer(80);

        imageAttr.append( "<IMG border=\"0\" SRC=\"" )
                 .append( image )
                 .append("\"");
        if (imageAltText != null && imageAltText.length() > 0 )
        {
            imageAttr.append(" ALT=\"")
                     .append(imageAltText)
                     .append("\"");
        } 
        imageAttr.append( ">" );

        try
        {
            theLink = UrlUtils.constructHTMLLink( 
                                  pr, UrlUtils.EVENT_LINK, 
                                  imageAttr.toString(),
                                  "",
                                  urlParameters, 
                                  encodeParams, replaceParams );
        }
        catch (Exception e)
        {
            throw new PortletException(e);
        }
        
        return theLink;    
    }
}
