/**
 * 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
 */

/*
 * Created on 03.07.2006
 */
package org.richfaces.component;

import javax.faces.FacesException;
import javax.faces.component.ActionSource;
import javax.faces.component.UIComponent;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;

import org.ajax4jsf.component.AjaxActionComponent;
import org.ajax4jsf.component.AjaxComponent;
import org.ajax4jsf.event.AjaxSource;
import org.ajax4jsf.renderkit.AjaxRendererUtils;
import org.ajax4jsf.renderkit.RendererUtils;

/**
 * @author igels
 *
 */

//extends UIAjaxCommandLink {
public abstract class UIToggleControl extends AjaxActionComponent implements AjaxComponent, AjaxSource, ActionSource {
	
	public static final String COMPONENT_FAMILY = "javax.faces.Command";
	
	//private String _switchToState;
	
    //xxx by nick - denis - move to config
	//private String _panelId;

	//xxx by nick - denis - A4J architecture fault: AjaxActionComponent should hold all action & immediate properties
	//private MethodBinding actionListener = null;
    //private boolean immediate = false;
    //private boolean immediateSet = false;
    
    //xxx by nick - denis - move to config
    
    
    public abstract void setPanelId(String  panelId);
    public abstract String getPanelId();
    public abstract void setSwitchToState(String  switchToState);
    public abstract String getSwitchToState();
    public abstract String getFor();
    public abstract void setFor(String  f);
  
    

	
	
	public boolean getRendersChildren() {
    	return true;
    }
	
	public UITogglePanel  getPanel()
    throws FacesException {
       UIComponent control=this;       
       String target = ((UIToggleControl) control).getFor();       
		
       if (null != target) {
    	 
         UIComponent targetComponent = RendererUtils.getInstance().findComponentFor(control, target);
         if (null != targetComponent) {
           return (UITogglePanel)targetComponent;
         } else {        	 
        	 throw new FacesException( "Parent panel for control (id=" 
        			 + getClientId(getFacesContext()) + ") has not been found.");         }
       } else {
   		
		  while((control = control.getParent())!= null) {
			if (control instanceof UITogglePanel) {
				return (UITogglePanel) control;				
			}
		  }
		  throw new FacesException( "Parent panel for control (id=" + getClientId(getFacesContext()) + ") has not been found.");
       }
     }

    
    //xxx by nick - denis - "for" can be relative etc. Do we really need it here?
	public Object getReRender(){
		return getPanelId();
	}

    //xxx by nick - denis - what do you think about setupReRender usage?
/*	protected void setupReRender() {
		super.setupReRender();
		
		FacesContext context = FacesContext.getCurrentInstance();
		UITogglePanel togglePanel = getPanel();
		AjaxRendererUtils.addRegionByName(context, togglePanel, togglePanel.getId());
	}
*/	
	public void setReRender(Object targetId) {
	}

	public String getFamily() {
		return COMPONENT_FAMILY;
	}


	
	//xxx by nick - denis - remove FacesContext param when all todos will be ready
	/*
	  
	 public UITogglePanel getPanel(FacesContext context) {
		String panelId = getPanelId();
		UIComponent panel = null;
		if(panelId == null) {
			panel = this;
			while (panel != null && !(panel instanceof UITogglePanel)) {
				panel = panel.getParent();
			}
			
			if(panel == null) {
				//xxx by nick - denis - please replace all RuntimeException with more concrete FacesException				
				throw new FacesException("Parent panel for control (id=" + getClientId(context) + ") has not been found.");
			}

			//xxx by nick - denis - remove this! you are shadowing possible "for" value binding by such code
			setPanelId(panel.getClientId(context));
		
		} else {
			//xxxx by nick - nick - potential compatibility break?
			panel = RendererUtils.getInstance().findComponentFor(context, this, panelId);
			if(panel == null) {
				//xxx by nick - denis - please replace all RuntimeException with more concrete FacesException
				throw new FacesException("Panel with id=" + panelId + " has not been found.");
			}
		}
		return (UITogglePanel)panel;
	}
	*/

	//xxx by nick - denis - unnecessary recursion was here... remove this method please
// 	private UIComponent getParentPanel(UIComponent component) {
//		UIComponent parent = component.getParent();
//		if(parent == null) {
//			return null;
//		}
//		if(parent instanceof UITogglePanel) {
//			return parent;
//		}
//		return getParentPanel(parent);
//	}
 

 	
    //xxx by nick - denis - should be removed after moving to config
/*	
	public String getFor() {
    	if (getPanelId() != null) {
    	    return getPanelId();
    	}
    	ValueBinding vb = getValueBinding("for");
    	if (vb != null) {
    	    return ((String) vb.getValue(getFacesContext()));
    	} else {
    	    return (null);
    	}
    }

    public void setFor(String panelId) {
    	setPanelId(panelId);
    }
*/    
/*
    public Object saveState(FacesContext context) {
        Object values[] = new Object[7];
        values[0] = super.saveState(context);
        values[1] = getPanelId();
        values[2] = getSwitchToState();

        values[3] = saveAttachedState(context, actionListener);
        values[4] = immediate ? Boolean.TRUE : Boolean.FALSE;
        values[5] = immediateSet ? Boolean.TRUE : Boolean.FALSE;
        values[6] = getValue();

        return (values);
    }

    public void restoreState(FacesContext context, Object state) {
        Object values[] = (Object[]) state;
        super.restoreState(context, values[0]);
        _panelId = (String) values[1];
        _switchToState = (String) values[2];

        actionListener = (MethodBinding) restoreAttachedState(context, values[3]);
        immediate = ((Boolean) values[4]).booleanValue();
        immediateSet = ((Boolean) values[5]).booleanValue();
        value = values[6];
    }
*/

/*	
	public String getSwitchTo() {
		return getSwitchToState();
	}

	public void setSwitchTo(String state) {
		setSwitchToState(state);
	}
*/
	
//xxxx by nick - denis - don't we have action?
//	public MethodBinding getAction() {		
//		return null;
//	}

//	public void setAction(MethodBinding action) {
//		
//	}

/*	
    public MethodBinding getActionListener() {
        return this.actionListener;
	}

	public void setActionListener(MethodBinding actionListener) {
		this.actionListener = actionListener;
	}
*/	

/*	
    public boolean isImmediate() {
    	if (this.immediateSet) {
    		return this.immediate;
    	}
    	ValueBinding vb = getValueBinding("immediate");
    	if (vb != null) {
    		return Boolean.TRUE.equals(vb.getValue(getFacesContext()));
    	} else {
    		return this.immediate;
    	}
    }

    public void setImmediate(boolean immediate) {
    	if (immediate != this.immediate) {
    		this.immediate = immediate;
    	}
    	this.immediateSet = true;
    }
*/
}
 