package webfleet.regserv.jsfbean.renderer;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UISelectOne;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.faces.model.SelectItemGroup;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.renderkit.JSFAttr;
import org.apache.myfaces.renderkit.RendererUtils;
import org.apache.myfaces.renderkit.html.HTML;
import org.apache.myfaces.renderkit.html.HtmlRadioRendererBase;
import org.apache.myfaces.renderkit.html.HtmlRendererUtils;

/**
 * 
 * @author nkrause
 */
public class HtmlRadioRendererExtendedBase extends HtmlRadioRendererBase {
	
    private static final Log log = LogFactory.getLog(HtmlRadioRendererBase.class);

    private static final String PAGE_DIRECTION = "pageDirection";
    private static final String LINE_DIRECTION = "lineDirection";
	
    public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
    {
        RendererUtils.checkParamValidity(facesContext, uiComponent, UISelectOne.class);

        UISelectOne selectOne = (UISelectOne)uiComponent;

        String layout = getLayout(selectOne);

        boolean pageDirectionLayout = false; // Defaults to LINE_DIRECTION
        if (layout != null)
        {
            if (layout.equals(PAGE_DIRECTION))
            {
                pageDirectionLayout = true;
            }
            else if (layout.equals(LINE_DIRECTION))
            {
                pageDirectionLayout = false;
            }
            else
            {
                log.error("Wrong layout attribute for component " + selectOne.getClientId(facesContext) + ": " + layout);
            }
        }

        ResponseWriter writer = facesContext.getResponseWriter();

        writer.startElement(HTML.TABLE_ELEM, selectOne);
        HtmlRendererUtils.renderHTMLAttributes(writer, selectOne,
                                               HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
        HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);

        if (!pageDirectionLayout) writer.startElement(HTML.TR_ELEM, selectOne);

        Converter converter;
        List selectItemList = RendererUtils.getSelectItemList(selectOne);
        converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, selectOne);

        Object currentValue = RendererUtils.getObjectValue(selectOne);
        
        currentValue = RendererUtils.getConvertedStringValue(facesContext, selectOne, converter, currentValue);
        int counter = 0;
        for (Iterator it = selectItemList.iterator(); it.hasNext(); )
        {
        	
            SelectItem selectItem = (SelectItem)it.next();

            renderGroupOrItemRadio(facesContext, selectOne,
            		selectItem, currentValue,
            		converter, pageDirectionLayout, counter);

            if (pageDirectionLayout) writer.endElement(HTML.TR_ELEM);
            
            counter++;
        }

        if (!pageDirectionLayout) writer.endElement(HTML.TR_ELEM);
        writer.endElement(HTML.TABLE_ELEM);
    }
	
	
	
	/**
	 * 
	 */
	protected void renderGroupOrItemRadio(FacesContext facesContext,
    		UIComponent uiComponent, SelectItem selectItem,
    		Object currentValue,
    		Converter converter, boolean pageDirectionLayout, int counter) throws IOException{

    	ResponseWriter writer = facesContext.getResponseWriter();

    	boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);

    	// TODO : Check here for getSubmittedValue. Look at RendererUtils.getValue
    	// this is useless object creation
//    	Object itemValue = selectItem.getValue();

    	UISelectOne selectOne = (UISelectOne)uiComponent;

        if (isSelectItemGroup) {
        	if (pageDirectionLayout)
                writer.startElement(HTML.TR_ELEM, selectOne);

        	writer.startElement(HTML.TD_ELEM, selectOne);
        	writer.write(selectItem.getLabel());
        	writer.endElement(HTML.TD_ELEM);

        	if (pageDirectionLayout) {
	        	writer.endElement(HTML.TR_ELEM);
	        	writer.startElement(HTML.TR_ELEM, selectOne);
        	}
        	writer.startElement(HTML.TD_ELEM, selectOne);

        	writer.startElement(HTML.TABLE_ELEM, selectOne);
        	writer.writeAttribute(HTML.BORDER_ATTR, "0", null);

        	SelectItemGroup group = (SelectItemGroup) selectItem;
        	SelectItem[] selectItems = group.getSelectItems();

        	for (int i=0; i<selectItems.length; i++) {
        		renderGroupOrItemRadio(facesContext, selectOne, selectItems[i], currentValue, converter, pageDirectionLayout);
        	}

        	writer.endElement(HTML.TD_ELEM);
        	writer.endElement(HTML.TR_ELEM);
        	writer.endElement(HTML.TABLE_ELEM);
        	writer.endElement(HTML.TD_ELEM);

        	if (pageDirectionLayout)
                writer.endElement(HTML.TR_ELEM);

        } else {
	        writer.write("\t\t");
	        if (pageDirectionLayout)
	            writer.startElement(HTML.TR_ELEM, selectOne);
	        writer.startElement(HTML.TD_ELEM, selectOne);
	        writer.startElement(HTML.LABEL_ELEM, selectOne);
	        
	        String clientId = uiComponent.getClientId(facesContext)+"_"+counter;
	        
	        writer.writeAttribute(HTML.FOR_ATTR,clientId,null);
		
	
	        String itemStrValue = RendererUtils.getConvertedStringValue(facesContext, selectOne, converter, selectItem.getValue());
	        boolean itemDisabled = selectItem.isDisabled();
	
	        boolean itemChecked = itemStrValue.equals(currentValue);
	
	        String labelClass = null;
	        boolean componentDisabled = isDisabled(facesContext, selectOne);
	
	        if (componentDisabled || itemDisabled) {
	            labelClass = (String) selectOne.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
	        } else {
	            labelClass = (String) selectOne.getAttributes().get(JSFAttr.ENABLED_CLASS_ATTR);
	        }
	        if (labelClass != null) {
	            writer.writeAttribute("class", labelClass, "labelClass");
	        }
	
	        renderRadio(facesContext, selectOne, itemStrValue, selectItem.getLabel(), itemDisabled, itemChecked, clientId);
	        
	        writer.endElement(HTML.LABEL_ELEM);
	        writer.endElement(HTML.TD_ELEM);
	        if (pageDirectionLayout)
	            writer.endElement(HTML.TR_ELEM);
        }
    }	

	/**
	 * 
	 * @param facesContext
	 * @param uiComponent
	 * @param value
	 * @param label
	 * @param disabled
	 * @param checked
	 * @param renderId
	 * @throws IOException
	 */
    protected void renderRadio(FacesContext facesContext, UIInput uiComponent,
			String value, String label, boolean disabled, boolean checked,
			String renderId) throws IOException {
		String clientId = uiComponent.getClientId(facesContext);

		ResponseWriter writer = facesContext.getResponseWriter();

		writer.startElement(HTML.INPUT_ELEM, uiComponent);
		writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
		writer.writeAttribute(HTML.NAME_ATTR, clientId, null);

		if (disabled) {
			writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
		}

		if (renderId!=null) {
			writer.writeAttribute(HTML.ID_ATTR, renderId, null);
		}

		if (checked) {
			writer.writeAttribute(HTML.CHECKED_ATTR, HTML.CHECKED_ATTR, null);
		}

		if ((value != null) && (value.length() > 0)) {
			writer.writeAttribute(HTML.VALUE_ATTR, value, null);
		}

		HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
				HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
		if (isDisabled(facesContext, uiComponent)) {
			writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
		}

		writer.endElement(HTML.INPUT_ELEM);

		if ((label != null) && (label.length() > 0)) {
			writer.write(HTML.NBSP_ENTITY);
			writer.writeText(label, null);
		}
	}
	     
}



