/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/
package org.ofbiz.widget.renderer.macro;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.template.FreeMarkerWorker;
import org.ofbiz.webapp.control.RequestHandler;
import org.ofbiz.webapp.taglib.ContentUrlTag;
import org.ofbiz.widget.WidgetWorker;
import org.ofbiz.widget.model.ModelTree;
import org.ofbiz.widget.model.ModelWidget;
import org.ofbiz.widget.renderer.ScreenRenderer;
import org.ofbiz.widget.renderer.ScreenStringRenderer;
import org.ofbiz.widget.renderer.TreeStringRenderer;

import freemarker.core.Environment;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * Widget Library - Tree Renderer implementation based on Freemarker macros
 * 
 */
public class MacroTreeRenderer implements TreeStringRenderer {

    public static final String module = MacroTreeRenderer.class.getName();
    private Template macroLibrary;
    private Environment environment;


    public MacroTreeRenderer(String macroLibraryPath, Appendable writer) throws TemplateException, IOException {
        this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
        Map<String, Object> input = UtilMisc.toMap("key", null);
        this.environment = FreeMarkerWorker.renderTemplate(this.macroLibrary, input, writer);
    }

    private void executeMacro(String macro) throws IOException {
        try {
            Reader templateReader = new StringReader(macro);
            // FIXME: I am using a Date as an hack to provide a unique name for the template...
            Template template = new Template((new java.util.Date()).toString(), templateReader,
                    FreeMarkerWorker.getDefaultOfbizConfig());
            templateReader.close();
            this.environment.include(template);
        } catch (TemplateException e) {
            Debug.logError(e, "Error rendering tree thru ftl", module);
        } catch (IOException e) {
            Debug.logError(e, "Error rendering tree thru ftl", module);
        }
    }
 
    /**
     * Renders the beginning boundary comment string.
     * @param writer The writer to write to
     * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc.
     * @param modelWidget The widget
     */
    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
        StringWriter sr = new StringWriter();
        sr.append("<@formatBoundaryComment ");
        sr.append(" boundaryType=\"");
        sr.append("Begin");
        sr.append("\" widgetType=\"");
        sr.append(widgetType);
        sr.append("\" widgetName=\"");
        sr.append(modelWidget.getBoundaryCommentName());
        sr.append("\" />");
        executeMacro(sr.toString());
    }
    
    /**
     * Renders the ending boundary comment string.
     * @param writer The writer to write to
     * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc.
     * @param modelWidget The widget
     */
    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
        StringWriter sr = new StringWriter();
        sr.append("<@formatBoundaryComment ");
        sr.append(" boundaryType=\"");
        sr.append("End");
        sr.append("\" widgetType=\"");
        sr.append(widgetType);
        sr.append("\" widgetName=\"");
        sr.append(modelWidget.getBoundaryCommentName());
        sr.append("\" />");
        executeMacro(sr.toString());
    }
    
    public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException {
        String currentNodeTrailPiped = null;
        List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
        
        String style = "";
        if (node.isRootNode()) {
            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
                renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree());
            }
            style = "basic-tree";
        }
 
        StringWriter sr = new StringWriter();
        sr.append("<@renderNodeBegin ");
        sr.append(" style=\"");
        sr.append(style);
        sr.append("\" />");
        executeMacro(sr.toString());

        String pkName = node.getPkName(context);
        String entityId = null;
        String entryName = node.getEntryName();
        if (UtilValidate.isNotEmpty(entryName)) {
            Map<String, String> map = UtilGenerics.checkMap(context.get(entryName));
            entityId = map.get(pkName);
        } else {
            entityId = (String) context.get(pkName);
        }
        boolean hasChildren = node.hasChildren(context);

        // check to see if this node needs to be expanded.
        if (hasChildren && node.isExpandCollapse()) {
            // FIXME: Using a widget model in this way is an ugly hack.
            ModelTree.ModelNode.Link expandCollapseLink = null;
            String targetEntityId = null;
            List<String> targetNodeTrail = UtilGenerics.toList(context.get("targetNodeTrail"));
            if (depth < targetNodeTrail.size()) {
                targetEntityId = targetNodeTrail.get(depth);
            }

            int openDepth = node.getModelTree().getOpenDepth();
            if (depth >= openDepth && (targetEntityId == null || !targetEntityId.equals(entityId))) {
                // Not on the trail
                if (node.showPeers(depth, context)) {
                    context.put("processChildren", Boolean.FALSE);
                    //expandCollapseLink.setText("&nbsp;+&nbsp;");
                    currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
                    StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
                    String trailName = node.getModelTree().getTrailName(context);
                    if (target.indexOf("?") < 0) {
                        target.append("?");
                    } else {
                        target.append("&");
                    }
                    target.append(trailName).append("=").append(currentNodeTrailPiped);
                    expandCollapseLink = new ModelTree.ModelNode.Link("collapsed", target.toString(), " ");
                }
            } else {
                context.put("processChildren", Boolean.TRUE);
                //expandCollapseLink.setText("&nbsp;-&nbsp;");
                String lastContentId = currentNodeTrail.remove(currentNodeTrail.size() - 1);
                currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
                if (currentNodeTrailPiped == null) {
                    currentNodeTrailPiped = "";
                }
                StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
                String trailName = node.getModelTree().getTrailName(context);
                if (target.indexOf("?") < 0) {
                    target.append("?");
                } else {
                    target.append("&");
                }
                target.append(trailName).append("=").append(currentNodeTrailPiped);
                expandCollapseLink = new ModelTree.ModelNode.Link("expanded", target.toString(), " ");
                // add it so it can be remove in renderNodeEnd
                currentNodeTrail.add(lastContentId);
            }
            if (expandCollapseLink != null) {
                renderLink(writer, context, expandCollapseLink);
            }
        } else if (!hasChildren) {
            context.put("processChildren", Boolean.FALSE);
            ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link("leafnode", "", " ");
            renderLink(writer, context, expandCollapseLink);
        }
    }

    public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
        Boolean processChildren = (Boolean) context.get("processChildren");
        StringWriter sr = new StringWriter();
        sr.append("<@renderNodeEnd ");
        sr.append(" processChildren=");
        sr.append(Boolean.toString(processChildren.booleanValue()));
        sr.append(" isRootNode=");
        sr.append(Boolean.toString(node.isRootNode()));
        sr.append(" />");
        executeMacro(sr.toString());
        if (node.isRootNode()) {
            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
                renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree());
            }
        }
    }

    public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
        Boolean processChildren = (Boolean) context.get("processChildren");
        if (processChildren.booleanValue()) {            
            StringWriter sr = new StringWriter();
            sr.append("<@renderLastElement ");
            sr.append("style=\"");
            sr.append("basic-tree");
            sr.append("\" />");
            executeMacro(sr.toString());
        }
    }

    public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException {
        String id = label.getId(context); 
        String style = label.getStyle(context);
        String labelText = label.getText(context);

        StringWriter sr = new StringWriter();
        sr.append("<@renderLabel ");
        sr.append("id=\"");
        sr.append(id);
        sr.append("\" style=\"");
        sr.append(style);
        sr.append("\" labelText=\"");
        sr.append(labelText);        
        sr.append("\" />");
        executeMacro(sr.toString());        
    }

    public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException {
        String target = link.getTarget(context);
        StringBuilder linkUrl = new StringBuilder();
        HttpServletResponse response = (HttpServletResponse) context.get("response");
        HttpServletRequest request = (HttpServletRequest) context.get("request");
        
        if (UtilValidate.isNotEmpty(target)) {
            WidgetWorker.buildHyperlinkUrl(linkUrl, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
                    link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);            
        }        
        
        String id = link.getId(context);
        String style = link.getStyle(context);
        String name = link.getName(context);
        String title = link.getTitle(context);
        String targetWindow = link.getTargetWindow(context);
        String linkText = link.getText(context);
        
        String imgStr = "";
        ModelTree.ModelNode.Image img = link.getImage();
        if (img != null) {
            StringWriter sw = new StringWriter();
            renderImage(sw, context, img);
            imgStr = sw.toString();
        }
        
        StringWriter sr = new StringWriter();
        sr.append("<@renderLink ");
        sr.append("id=\"");
        sr.append(id);
        sr.append("\" style=\"");
        sr.append(style);
        sr.append("\" name=\"");
        sr.append(name);
        sr.append("\" title=\"");
        sr.append(title);
        sr.append("\" targetWindow=\"");
        sr.append(targetWindow);  
        sr.append("\" linkUrl=\"");
        sr.append(linkUrl);     
        sr.append("\" linkText=\"");
        sr.append(linkText);           
        sr.append("\" imgStr=\"");
        sr.append(imgStr.replaceAll("\"", "\\\\\""));
        sr.append("\" />");
        executeMacro(sr.toString());
    }
  
    public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException {
        if (image == null) {
            return ;            
        }
        HttpServletResponse response = (HttpServletResponse) context.get("response");
        HttpServletRequest request = (HttpServletRequest) context.get("request");
        
        String urlMode = image.getUrlMode();
        String src = image.getSrc(context);
        String id = image.getId(context);
        String style = image.getStyle(context);
        String wid = image.getWidth(context);
        String hgt = image.getHeight(context);
        String border = image.getBorder(context);
        String alt = ""; //TODO add alt to tree images image.getAlt(context);
 
        boolean fullPath = false;
        boolean secure = false;
        boolean encode = false;
        String urlString = "";
        
        if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
            if (request != null && response != null) {
                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
                urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
            } else {
                urlString = src;
            }
        } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
            if (request != null && response != null) {
                StringBuilder newURL = new StringBuilder();
                ContentUrlTag.appendContentPrefix(request, newURL);
                newURL.append(src);
                urlString = newURL.toString();
            }
        } else {
            urlString = src;
        }
        StringWriter sr = new StringWriter();
        sr.append("<@renderImage ");
        sr.append("src=\"");
        sr.append(src);
        sr.append("\" id=\"");
        sr.append(id);
        sr.append("\" style=\"");
        sr.append(style);
        sr.append("\" wid=\"");
        sr.append(wid);
        sr.append("\" hgt=\"");
        sr.append(hgt);
        sr.append("\" border=\"");
        sr.append(border);
        sr.append("\" alt=\"");
        sr.append(alt);
        sr.append("\" urlString=\"");
        sr.append(urlString);
        sr.append("\" />");
        executeMacro(sr.toString());        
    }

    public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context) {
        ScreenRenderer screenRenderer = (ScreenRenderer)context.get("screens");
        if (screenRenderer != null) {
            return screenRenderer.getScreenStringRenderer();
        } 
        return null;
    }
}
