/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.corejsf;

import java.io.IOException;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.faces.render.Renderer;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 *
 * @author Ivan
 */
public class TabbedPaneRenderer extends Renderer {

    //komponenta ima decu
    public boolean getRendersChildren() {
        return true;
    }

    //decode metod dohvata se vrednost hidden polja sa forme koje ima isti id kao nasa komponenta i cuva se u propertiju content nase komponente
    //takodje se actionEvent stavlja u red dogadjaja koji ce se obraditi u 5 fazi zivotnog ciklusa
    public void decode(FacesContext context, UIComponent component) {
        Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap();
        String clientId = component.getClientId(context);

        String content = (String) (requestParams.get(clientId));
        if (content != null && !content.equals("")) {
            UITabbedPane tabbedPane = (UITabbedPane) component;
            tabbedPane.setContent(content);
        }

        component.queueEvent(new ActionEvent(component));
    }

    public void encodeBegin(FacesContext context, UIComponent component)
            throws java.io.IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement("table", component);

        String styleClass = (String) component.getAttributes().get("styleClass");
        if (styleClass != null) {
            writer.writeAttribute("class", styleClass, null);
        }
        writer.write("\n"); // to make generated HTML easier to read

    }

    public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
        if (component.getChildCount() == 0) {
            return;
        }
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement("table", component);
        writer.startElement("tbody", component);
        writer.startElement("tr", component);

        for (SelectItem item : com.corejsf.util.Renderers.getSelectItems(component)) {
            encodeTab(context, writer, item, component);
        }
        writer.endElement("tr");
        writer.endElement("tbody");
        writer.endElement("table");

        writer.endElement("th");
        writer.endElement("tr");
        writer.endElement("thead");
        writer.write("\n");
    }
    public void encodeEnd(FacesContext context, UIComponent component)
         throws java.io.IOException {
      ResponseWriter writer = context.getResponseWriter();
      UITabbedPane tabbedPane = (UITabbedPane) component;
      String content = tabbedPane.getContent();

      writer.startElement("tbody", component);
      writer.startElement("tr", component);
      writer.startElement("td", component);

      if (content != null) {
         UIComponent facet = component.getFacet(content);
         if (facet != null) {
            if (facet.isRendered()) {
               facet.encodeBegin(context);
               if (facet.getRendersChildren())
                  facet.encodeChildren(context);
               facet.encodeEnd(context);
            }
         } else
            includePage(context, component);
      }

      writer.endElement("td");
      writer.endElement("tr");
      writer.endElement("tbody");

      // Close off the column, row, and table elements
      writer.endElement("table");

      encodeHiddenField(context, writer, component);
   }

   // The encodeHiddenField method is called at the end of encodeEnd().
   // See the decode method for an explanation of the field and its value.

   private void encodeHiddenField(FacesContext context, ResponseWriter writer,
         UIComponent component) throws java.io.IOException {
      // write hidden field whose name is the tabbedpane's client Id
      writer.startElement("input", component);
      writer.writeAttribute("type", "hidden", null);
      writer.writeAttribute("name", component.getClientId(context), null);
      writer.endElement("input");
   }

   // encodeTab, which is called by encodeChildren, encodes an HTML anchor
   // element with an onclick attribute which sets the value of the hidden
   // field encoded by encodeHiddenField and submits the tabbedpane's enclosing
   // form. See the decode method for more information about the hidden field.
   // encodeTab also writes out a class attribute for each tab corresponding
   // to either the tabClass attribute (for unselected tabs) or the
   // selectedTabClass attribute (for the selected tab).

   private void encodeTab(FacesContext context, ResponseWriter writer,
         SelectItem item, UIComponent component) throws java.io.IOException {
      String tabText = getLocalizedTabText(component, item.getLabel());
      String content = (String) item.getValue();

      writer.startElement("td", component);
      writer.startElement("a", component);
      writer.writeAttribute("href", "#", "href");

      String clientId = component.getClientId(context);
      String formId = com.corejsf.util.Renderers.getFormId(context, component);

      writer.writeAttribute("onclick",
      // write value for hidden field whose name is the tabbedpane's client Id

            "document.forms['" + formId + "']['" + clientId + "'].value='"
                  + content + "'; " +

                  // submit form in which the tabbedpane resides
                  "document.forms['" + formId + "'].submit(); ", null);

      UITabbedPane tabbedPane = (UITabbedPane) component;
      String selectedContent = tabbedPane.getContent(); 

      String tabClass = null;
      if (content.equals(selectedContent))
         tabClass = (String) component.getAttributes().get("selectedTabClass");
      else
         tabClass = (String) component.getAttributes().get("tabClass");

      if (tabClass != null)
         writer.writeAttribute("class", tabClass, null);

      writer.write(tabText);

      writer.endElement("a");
      writer.endElement("td");
      writer.write("\n"); // to make generated HTML easier to read
   }

   // Text for the tabs in the tabbedpane component can be specified as
   // a key in a resource bundle, or as the actual text that's displayed
   // in the tab. Given that text, the getLocalizedTabText method tries to
   // retrieve a value from the resource bundle specified with the
   // <corejsf:tabbedpane>'s resourceBundle attribute. If no value is found,
   // getLocalizedTabText just returns the string it was passed.

   private String getLocalizedTabText(UIComponent tabbedPane, String key) {
      String bundle = (String) tabbedPane.getAttributes().get("resourceBundle");
      String localizedText = null;

      if (bundle != null) {
         localizedText = com.corejsf.util.Messages.getString(bundle, key, null);
      }
      if (localizedText == null)
         localizedText = key;
      // The key parameter was not really a key in the resource bundle,
      // so just return the string as is
      return localizedText;
   }

   // includePage uses the servlet request dispatcher to include the page
   // corresponding to the selected tab.

   private void includePage(FacesContext fc, UIComponent component) {
	  ExternalContext ec = fc.getExternalContext();
      ServletContext sc = (ServletContext) ec.getContext();
      UITabbedPane tabbedPane = (UITabbedPane) component;
      String content = tabbedPane.getContent();
      
      ServletRequest request = (ServletRequest) ec.getRequest();
      ServletResponse response = (ServletResponse) ec.getResponse();
      try {
         sc.getRequestDispatcher(content).include(request, response);
      } catch (Exception e) {e.printStackTrace();}
     
   }
}

