/*  Copyright (c) 2000 by Oracle Corporation. All Rights Reserved. */
package oracle.portal.sample.v2.devguide.helloworld;

import oracle.portal.provider.v2.*;
import oracle.portal.provider.v2.http.*;
import oracle.portal.provider.v2.render.*;
import oracle.portal.utils.xml.v2.XMLUtil;
import oracle.portal.provider.v2.personalize.NameValuePersonalizationObject;
import oracle.portal.provider.v2.render.http.HttpPortletRendererUtil;
import oracle.portal.provider.v2.security.AccessControlException;
import oracle.portal.log.LogManager;
import oracle.portal.sample.v2.devguide.helloworld.resource.HelloWorldBundle;

import java.io.*;
import java.util.*;
import java.text.*;


public class HelloWorldRenderer extends PortletRenderer {

    private static final String COLLAPSED = "MINIMIZED";
    private static final String NOT_COLLAPSED = "NORMAL";

    public HelloWorldRenderer() {
    }

    public void render(PortletRenderRequest pr) 
        throws PortletException, AccessControlException 
    {
        long start = System.currentTimeMillis();
        LogManager.info("Entering HelloWorldRenderer.render()");
        
        switch (pr.getMode()) {
        case PortletRenderer.MODE_SHOW:
            renderShow(pr);
            break;
        case PortletRenderer.MODE_EDIT:
            renderEdit(pr);
            break;
        case PortletRenderer.MODE_EDIT_DEFAULTS:
            renderEditDefaults(pr);
            break;
        case PortletRenderer.MODE_SHOW_DETAILS:
            renderShowDetails(pr);
            break;
        case PortletRenderer.MODE_PREVIEW:
            renderPreview(pr);
            break;
        case PortletRenderer.MODE_HELP:
            renderHelp(pr);
            break;
        case PortletRenderer.MODE_ABOUT:
            renderAbout(pr);
            break;
        case PortletRenderer.MODE_LINK:
            renderLink(pr);
            break;
        default:
            throw new PortletException("HelloWorld render failed: Invalid " + 
                                       "render mode " + 
                                       pr.getMode());
        }
        
        LogManager.info("Leaving HelloWorldRenderer.render()");
        long runtime = System.currentTimeMillis() - start;
        LogManager.perf("Time in HelloWorldRenderer.render(): " + runtime);
    }

    private void renderShow(PortletRenderRequest pr) 
        throws PortletException, AccessControlException
    {
        RenderContext rc = pr.getRenderContext();
        String preferredType = pr.getPreferredContentType();
        try 
        {
            String user = pr.getUser().getName();
            PrintWriter out = pr.getWriter(preferredType);
            ProviderSession session = pr.getSession();
            Locale l = pr.getLocale();
            LogManager.debug("HelloWorldRenderer.renderShow() - locale = " + 
                             l.toString());

            if (session != null)
            {
                // increment session count with each request so when cache is 
                // updated it reflects the correct number & it is evident that 
                // the cache has changed.
                int i = 0;
                Integer old = ((Integer) session.getAttribute(
                            PortletRendererUtil.portletParameter(pr, "count")));
                if (old != null) {
                    i = old.intValue();
                }
                Integer newCount = new Integer(i + 1);
                session.setAttribute(
                    PortletRendererUtil.portletParameter(pr, "count"), newCount);
            }
            else
            {
                LogManager.debug("HelloWorldRenderer.renderShow() " +
                                 "- session not found");
            }
            
            // Use cached version of title until user changes values through  
            // customization or the portlet is collapsed/expanded
            String version = HttpPortletRendererUtil.getCachedVersion(pr);
            if (version != null && session != null)
            {
                // we are being asked to validate our version
                Boolean hasChangedParam = 
                    ((Boolean)session.getAttribute(
                       PortletRendererUtil.portletParameter(pr, "hasChanged")));

                boolean hasChanged = (hasChangedParam == null) ? true : 
                                     hasChangedParam.booleanValue();
                boolean isCacheCollapsed = version.equals(COLLAPSED) ? true : false;
               
                if (!hasChanged && (rc.isCollapsed() == isCacheCollapsed))
                {
                    // reuse the existing version
                    HttpPortletRendererUtil.useCachedVersion(pr);
                    return;
                }
            }

            //  Remove any indication this portlet has changed
            if (session != null)
            {
                String qp = PortletRendererUtil.portletParameter(pr, 
                                                                 "hasChanged");
                session.setAttribute(qp, Boolean.FALSE);
            }

            // Get the greeting and customized title
            NameValuePersonalizationObject data = 
                (NameValuePersonalizationObject)PortletRendererUtil.getEditData(pr);
            ResourceBundle b = 
                pr.getPortletDefinition().getResourceBundle(pr.getLocale());
            MessageFormat message = 
                new MessageFormat(b.getString(HelloWorldBundle.DEFAULT_MSG));

            String title = data.getPortletTitle();

            Object[] greetingArgs = {(user != null) ? user : "" };

            MessageFormat updated = 
                        new MessageFormat(b.getString(HelloWorldBundle.LAST_UPDATED));
            Object[] updateArgs = {new Date()};

            // determine whether an HTML render or an mobile render
            if (preferredType.startsWith(PortletRenderer.TYPE_HTML))
            {
                // Writes container -- handles rendering the border if necessary
                PortletRendererUtil.renderPortletHeader(pr, out, title);
                if (!rc.isCollapsed())
                {
                    out.println(message.format(greetingArgs));

                    if (session == null)
                    {
                        out.print("<P>");
                        out.println(b.getString(HelloWorldBundle.SESSION_TERMINATED));
                        out.print("</P>");
                    }
                    out.println("<p><p><p><p><font size=\"-2\"><i>");
                    out.println(updated.format(updateArgs));
                    out.println("</p></p></p></p></font>");
                }
                // Ends the container
                PortletRendererUtil.renderPortletFooter(pr, out);
            } 
            else if (preferredType.startsWith(PortletRenderer.TYPE_MOBILE)) 
            {
                out.println("<SimpleText>");
                out.println("    <SimpleTextItem>" + 
                            XMLUtil.escapeXMLText(message.format(greetingArgs)) + 
                            "</SimpleTextItem>");
                out.println("    <SimpleBreak/>");
                out.println("    <SimpleTextItem>Last updated on " + 
                            XMLUtil.escapeXMLText(updated.format(updateArgs)) + 
                            "</SimpleTextItem>");
                out.println("</SimpleText>");
            } 
            else 
            {
                throw new PortletException("Unsupported content-type: " + 
                                           preferredType);
            }

            // Tell the Portal to cache this result
            // Since the collapsed status of the portlet is maintained 
            // between sessions, we need to know what state is in the cache. 
            // Other part of cache key - the count - is maintained in the 
            // session so it is not included here
            String cacheKey = rc.isCollapsed() ? COLLAPSED : NOT_COLLAPSED;
            HttpPortletRendererUtil.setCachedVersion(pr, cacheKey, 
                                                     HttpCommonConstants.USER_LEVEL);
            
        } 
        catch (IllegalArgumentException ie) 
        {
            logAndThrowException(ie.getMessage(), ie);
        } 
        catch (java.io.IOException ioe) 
        {
            logAndThrowException(ioe.getMessage(), ioe);
        }
    }

    private void renderLink(PortletRenderRequest pr) 
        throws PortletException, AccessControlException 
    {
        try 
        {
            PrintWriter out = pr.getWriter(pr.getPreferredContentType());
            
            // Get the customized greeting and title
            NameValuePersonalizationObject data =
                (NameValuePersonalizationObject) PortletRendererUtil.getEditData(pr);

            // determine whether an HTML render or an mobile render
            if (pr.getPreferredContentType().startsWith(PortletRenderer.TYPE_HTML)) 
            {
                // Writes container -- handles rendering the border if necessary
                out.println("<a href=\"" + pr.getRenderContext().getPageURL() + 
                            "\">" + data.getPortletTitle() + "</a>");
            } 
            else if (pr.getPreferredContentType().startsWith(PortletRenderer.TYPE_MOBILE)) 
            {
                String title = data.getPortletShortTitle();

                // shortTitles may be empty -- if it is use the title
                if (title == null || title.length() == 0)
                    title = data.getPortletTitle();

                // now output the response
                out.println("<SimpleHref target=\"" + 
                            XMLUtil.escapeXMLAttribute(pr.getRenderContext().getPageURL()) 
                            + "\">");
                out.println(XMLUtil.escapeXMLText(title));
                out.println("</SimpleHref>");
            } 
            else 
            {
                throw new PortletException("Unsupported content-type: " + 
                                           pr.getPreferredContentType());
            }
        } 
        catch (IllegalArgumentException ie) 
        {
            logAndThrowException(ie.getMessage(), ie);
        }
        catch (java.io.IOException ioe) 
        {
            logAndThrowException(ioe.getMessage(), ioe);
        }
    }

    private void logAndThrowException(String msg, Throwable t) throws PortletException {
        LogManager.throwing(msg, t);
        throw new PortletException(msg);
    }


    private void renderEdit(PortletRenderRequest pr) throws PortletException, AccessControlException {
        try {
            PrintWriter out = pr.getWriter("text/html");

            String action = pr.getParameter("hw_action");
            LogManager.debug("HelloWorldRenderer.renderEdit - action parameter value = " + action);

            NameValuePersonalizationObject data = 
                (NameValuePersonalizationObject) PortletRendererUtil.getEditData(pr);
            ProviderSession session = pr.getSession();
            Locale l = pr.getLocale();

            // Cancel automatically redirects to the page -- so will only receive 'OK' or 'APPLY'
            if (action != null) 
            {
                String title = pr.getParameter("hw_title");
                String sTitle = pr.getParameter("hw_stitle");
                data.setPortletTitle(title);
                data.setPortletShortTitle(sTitle);
                PortletRendererUtil.submitEditData(pr, data);

                // write into session indication that cache is now invalid
                if(session != null)
                {
                    session.setAttribute(PortletRendererUtil.portletParameter(pr, "hasChanged"), Boolean.TRUE);
                }

                if (action.equalsIgnoreCase("OK")) 
                {
                    LogManager.debug("HelloWorldRenderer.renderEdit() - edit action = OK");
                    HttpPortletRendererUtil.sendRedirect(pr, pr.getRenderContext().getBackURL());
                    return;
                } 
                else if (action.equalsIgnoreCase("APPLY")) 
                {
                    LogManager.debug("HelloWorldRenderer.renderEdit() - edit action = OK");
                    HttpPortletRendererUtil.sendRedirect(pr, pr.getRenderContext().getPageURL());
                    return;
                }
            } 
            else 
            {
               ResourceBundle b = 
                pr.getPortletDefinition().getResourceBundle(l);
               PortletRendererUtil.renderCustomizeFormHeader(pr, out, null, "hw_action", null, null);
               
                out.println("<TABLE BORDER=\"0\">");
                out.println("   <TR>");
                out.println("        <TD WIDTH=\"25%\">");
                out.println("            <P ALIGN=\"RIGHT\">");
                out.print(b.getString(HelloWorldBundle.TITLE));
                out.println("        </TD>");
                out.println("        <TD WIDTH=\"75%\">");
                out.println("            <INPUT TYPE=\"TEXT\" NAME=\"hw_title\" VALUE=\"");
                out.println(data.getPortletTitle() + "\" SIZE=\"20\" >");
                out.println("        </TD>");
                out.println("   </TR>");
                out.println("   <TR>");
                out.println("        <TD WIDTH=\"25%\">");
                out.println("            <P ALIGN=\"RIGHT\">");
                out.print(b.getString(HelloWorldBundle.SHORT_TITLE));
                out.println("        </TD>");
                out.println("        <TD WIDTH=\"75%\">");
                out.println("            <INPUT TYPE=\"TEXT\" NAME=\"hw_stitle\" VALUE=\"");
                out.println(data.getPortletShortTitle() + "\" SIZE=\"20\" MAXLENGTH=\"20\" >");
                out.println("       </TD>");
                out.println("   </TR>");
                out.println("</TABLE>");
                PortletRendererUtil.renderCustomizeFormFooter(pr, out);
            }

        } catch (IllegalArgumentException ie) {
            logAndThrowException(ie.getMessage(), ie);
        } catch (java.io.IOException ioe) {
            logAndThrowException(ioe.getMessage(), ioe);
        }
    }

    private void renderEditDefaults(PortletRenderRequest pr) throws PortletException, AccessControlException {
        renderEdit(pr);
    }

    private void renderShowDetails(PortletRenderRequest pr) throws PortletException, AccessControlException {
        try {
            ProviderSession session = pr.getSession();
            PrintWriter out = pr.getWriter("text/html");

            if (session == null)
            {
                out.println("<CENTER>");
                out.println("<B>");
                out.println("Your provider session has been terminated, " + 
                            "please log out and back in again");
                out.println("</B>");
                out.println("</CENTER>");
                return;
            }
        
            String user = pr.getUser().getName();  
            Locale l = pr.getLocale();
            Integer count = null;

            // See if a "clear count was submitted"
            if (pr.getParameter("details_action") != null) 
            {
                // Clear the session count
                count = new Integer(0);
                session.setAttribute(PortletRendererUtil.portletParameter(pr, "count"), count);
                HttpPortletRendererUtil.sendRedirect(pr, pr.getRenderContext().getBackURL());
            } else 
            {
                // Get count of number of time the portlet has been rendered (in show mode)
                count = ((Integer) session.getAttribute(PortletRendererUtil.portletParameter(pr, "count")));
            }

            // Get other strings from the resource bundle
            ResourceBundle b = pr.getPortletDefinition().getResourceBundle(l);

            if (b == null) logAndThrowException("Unable to locate the HelloWorld resource messages.", null);
            MessageFormat countMsg = new MessageFormat(b.getString(HelloWorldBundle.SESSION_MSG));
            MessageFormat lang = new MessageFormat(b.getString(HelloWorldBundle.LANGUAGE_MSG));

            Object[] countArgs = { count };
            Object[] langArgs = {l.getDisplayLanguage(l)};

            out.println("<center><h3>");
            out.println(lang.format(langArgs) + "<br>");
            out.println(countMsg.format(countArgs) + "</h3>");

            renderClearForm(pr, out, b);
            out.println("</center>");

        } catch (IllegalArgumentException ie) {
            logAndThrowException(ie.getMessage(), ie);
        } catch (java.io.IOException ioe) {
            logAndThrowException(ioe.getMessage(), ioe);
        }
    }

    private void renderClearForm(PortletRenderRequest pr, PrintWriter out, ResourceBundle b) {
        // emit the form tag
        out.print("<form name=\"details_form\" action=\"");
        out.print(PortletRendererUtil.htmlFormActionLink(pr, PortletRendererUtil.PAGE_LINK));
        out.println("\" >");

        // emit hidden fields
        out.println(PortletRendererUtil.htmlFormHiddenFields(pr, PortletRendererUtil.PAGE_LINK));
        out.println("<INPUT TYPE=\"hidden\" name=\"details_action\" \" value=\"\" />");

        // emit javascript to avoid language/value issues
        out.println("<SCRIPT LANGUAGE=\"JavaScript1.1\">");
        out.println("<!-- Comment out script for old browsers");
        out.println("function doSubmit(action) {");
        out.println("   document.details_form.details_action.value=action");
        out.println("   document.details_form.submit()");
        out.println("}");
        out.println("//-->");
        out.println("</SCRIPT>");

        // output the button
        out.println("<INPUT TYPE=\"button\" NAME=\"clear\" VALUE=\"" + b.getString(HelloWorldBundle.CLEAR_MSG) + "\" onClick=\"javascript:doSubmit('CLEAR')\">");

        out.println("</form>");

    }

    private void renderPreview(PortletRenderRequest pr) throws PortletException, AccessControlException 
    {
        renderShow(pr);
    }

    private void renderHelp(PortletRenderRequest pr) throws PortletException, AccessControlException {
        try {
            PrintWriter out = pr.getWriter("text/html");
            Locale l = pr.getLocale();

            // Get other strings from the resource bundle
            ResourceBundle b = pr.getPortletDefinition().getResourceBundle(l);
            if (b == null) logAndThrowException("Unable to locate the HelloWorld resource messages.", null);

            PortletRendererUtil.renderInformationFormHeader(pr, out, null, b.getString(HelloWorldBundle.HELP_TITLE), null, null);

            out.println("<center>");
	    out.println(b.getString(HelloWorldBundle.HELP_CONTENT));
	    out.println("</center>");

            PortletRendererUtil.renderInformationFormFooter(pr, out);
        } catch (Exception e) {
            throw new PortletException(e);
        }
    }

    private void renderAbout(PortletRenderRequest pr) throws PortletException, AccessControlException {
        try {
            PrintWriter out = pr.getWriter("text/html");
            Locale l = pr.getLocale();

            // Get other strings from the resource bundle
            ResourceBundle b = pr.getPortletDefinition().getResourceBundle(l);
            if (b == null) logAndThrowException("Unable to locate the HelloWorld resource messages.", null);

            PortletRendererUtil.renderInformationFormHeader(pr, out, null, b.getString(HelloWorldBundle.ABOUT_TITLE), null, null);
            out.println(pr.getParameter("_title"));
	    out.println("<center>");
            out.println(b.getString(HelloWorldBundle.ABOUT_CONTENT));
	    out.println("</center>");

            PortletRendererUtil.renderInformationFormFooter(pr, out);
        } catch (Exception e) {
            throw new PortletException(e);
        }
    }

}

