/**
 * License Agreement.
 *
 *  JBoss RichFaces - Ajax4jsf Component Library
 *
 * Copyright (C) 2007  Exadel, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */

package org.richfaces.component;

import java.util.Iterator;

import javax.faces.component.ActionSource;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.ajax4jsf.component.AjaxActionComponent;
import org.ajax4jsf.component.AjaxComponent;
import org.ajax4jsf.event.AjaxSource;

import com.sun.org.apache.xpath.internal.operations.Bool;

/**
 * JSF component class
 */
public abstract class UISimpleTogglePanel extends AjaxActionComponent implements AjaxComponent, AjaxSource, ActionSource
//public abstract class UISimpleTogglePanel extends  UIInput implements AjaxComponent, AjaxSource, ActionSource
{

	public static final String COMPONENT_FAMILY = "javax.faces.Command";
    public static final String SERVER_SWITCH_TYPE = "server";
    public static final String CLIENT_SWITCH_TYPE = "client";
    public static final String AJAX_SWITCH_TYPE = "ajax";
    public static final boolean COLLAPSED = false;
    public static final boolean EXPANDED = true;
    
    private transient Boolean openedSet = null;

    private transient Boolean wasOpened = null; 

    protected boolean isWasOpened() {
    	if (wasOpened == null) {
    		if (CLIENT_SWITCH_TYPE.equals(getSwitchType())) {
    			wasOpened = Boolean.TRUE;
    		} else {
        		wasOpened = isOpened();
    		}
    	}
    	
    	return wasOpened;
    }
    
    public abstract void setSwitchType(String switchType);

    public abstract String getSwitchType();

    public void setOpened(boolean opened) {
    	setValue(new Boolean(opened).toString());
    }

    public boolean isOpened() {
    	Object value = getValue();
    	if (value instanceof Boolean) {
    		return ((Boolean)value).booleanValue();
    	} else if (value instanceof String) {
			String s = (String) value;
			return Boolean.parseBoolean(s);
		}
    	return true;
    }

    public boolean getRendersChildren() {
        return true;
    }

    /**
     * @throws NullPointerException {@inheritDoc}
     */
    public void processDecodes(FacesContext context) {

        if (context == null) {
            throw new NullPointerException();
        }

        // Skip processing if our rendered flag is false
        if (!isRendered()) {
            return;
        }

        if (isWasOpened()) {
            // Process all facets and children of this component
            Iterator<UIComponent> kids = getFacetsAndChildren();
            while (kids.hasNext()) {
                UIComponent kid = kids.next();
                kid.processDecodes(context);
            }
        }
        
        // Process this component itself
        try {
            decode(context);
        } catch (RuntimeException e) {
            context.renderResponse();
            throw e;
        }

    }


    /**
     * @throws NullPointerException {@inheritDoc}
     */
    public void processValidators(FacesContext context) {

        if (context == null) {
            throw new NullPointerException();
        }

        // Skip processing if our rendered flag is false
        if (!isRendered()) {
            return;
        }

        if (isWasOpened()) {
	        // Process all the facets and children of this component
        	Iterator<UIComponent> kids = getFacetsAndChildren();
	        while (kids.hasNext()) {
	            UIComponent kid = kids.next();
	            kid.processValidators(context);
	        }
        }
    }


    /**
     * @throws NullPointerException {@inheritDoc}
     */
    public void processUpdates(FacesContext context) {

        if (context == null) {
            throw new NullPointerException();
        }

        // Skip processing if our rendered flag is false
        if (!isRendered()) {
            return;
        }
        
        updateModel();

        if (isWasOpened()) {
	        // Process all facets and children of this component
        	Iterator<UIComponent> kids = getFacetsAndChildren();
	        while (kids.hasNext()) {
	            UIComponent kid = kids.next();
	            kid.processUpdates(context);
	        }
        }
    }
    
    private void updateModel () {
    	if (openedSet != null) {
    		setOpened(openedSet);
    	}
    }

	/**
	 * @return the openedSet
	 */
	public boolean isOpenedSet() {
		return openedSet;
	}

	/**
	 * @param openedSet the openedSet to set
	 */
	public void setOpenedSet(boolean openedSet) {
		this.openedSet = openedSet;
	}
    
/*
 * public void setValueBinding(String arg0, ValueBinding arg1) { if
 * ("opened".equals(arg0)) super.setValueBinding("value", arg1);
 * super.setValueBinding(arg0, arg1); }
 * 
 * public ValueBinding getValueBinding(String arg0) { if ("opened".equals(arg0))
 * return super.getValueBinding("value"); return super.getValueBinding(arg0); }
 */    
    //public void broadcast(FacesEvent facesEvent) throws AbortProcessingException {
    //   super.broadcast(facesEvent);
    //    FacesContext facesContext = FacesContext.getCurrentInstance();
    //    if (AjaxRendererUtils.isAjaxRequest(facesContext) && this.getSwitchType().equals(AJAX_SWITCH_TYPE)) {
    //        AjaxRendererUtils.addRegionByName(facesContext,
    //                this,
    //                this.getId());
    //    }
    //}
}
