/**
 * 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 javax.faces.component.UIData;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;

import org.ajax4jsf.component.AjaxComponent;
import org.ajax4jsf.context.AjaxContext;
import org.ajax4jsf.event.AjaxEvent;
import org.ajax4jsf.event.AjaxListener;
import org.ajax4jsf.event.AjaxSource;
import org.ajax4jsf.renderkit.AjaxRendererUtils;


/**
 * UI implementation for SuggestionBox component.
 *
 * @author shura (latest modification by $Author: alexsmirnov $)
 * @version $Revision: 1.5 $ $Date: 2007/03/01 22:37:50 $
 */
public abstract class UISuggestionBox extends UIData
        implements AjaxComponent, AjaxSource {


    /**
     * Component type.
     */
    private static final String COMPONENT_TYPE = "org.richfaces.SuggestionBox";

    /**
     * Component family.
     */
    private static final String COMPONENT_FAMILY =
            "org.richfaces.SuggestionBox";

    /**
     * TRUE if submitted.
     */
    private transient boolean submitted = false;

    /**
     * Getter for for attribute.
     *
     * id (or full path of id's) of target components, for which this element
     * must provide support.
     * If a target component inside of the same <code>NamingContainer<code>
     * (UIForm, UIData in base implementstions), can be simple value of the
     * "id" attribute.
     * For other cases must include id's of <code>NamingContainer<code>
     * components, separated by ':'. For search from the root of components,
     * must be started with ':'.
     *
     * @return for value from local variable or value bindings
     */
    public abstract Object getSubmitedValue();

    public abstract void setSubmitedValue(Object v);

    public abstract String getFor();

    /**
     * Setter for attribute.
     *
     * @param f identifier
     */
    public abstract void setFor(String f);

    /**
     * Getter for suggestionAction.
     *
     * Method calls an expression to get a collection of suggestion data
     * on request. It must have one parameter with a type of Object with
     * content of input component and must return any type allowed for
     * <h:datatable>;
     *
     * @return suggestionAction value from local variable or value bindings
     */
    public abstract MethodBinding getSuggestionAction();

    /**
     * Setter for suggestionAction.
     *
     * @param action {@link javax.faces.el.MethodBinding}
     */
    public abstract void setSuggestionAction(MethodBinding action);

    /**
     * Getter for converter.
     * Id of Converter to be used or reference to a Converter.
     *
     * @return converter value from local variable or value bindings
     */
    public abstract Converter getConverter();

    /**
     * Setter for converter.
     *
     * @param converter {@link javax.faces.convert.Converter}
     */
    public abstract void setConverter(Converter converter);

    /**
     * Getter for rowClasses.
     *
     * @return rowClasses value from local variable or value bindings
     */
    public abstract String getRowClasses();

    /**
     * Getter for rowClasses.
     *
     * @param rowClasses row classes
     */
    public abstract void setRowClasses(String rowClasses);

    /**
     * Getter for selectValueClass.
     *
     * Name of the CSS class for a hidden suggestion entry
     * element (table cell)
     *
     * @return selectValueClass value from local variable or value bindings
     */
    public abstract String getSelectValueClass();

    /**
     * Setter for selectValueClass.
     *
     * @param value class
     */
    public abstract void setSelectValueClass(String value);

    /**
     * Getter for border.
     *
     * This attributes specifies the width (in pixels only) of the frame around a table
     *
     * @return border value from local variable or value bindings
     */
    public abstract String getBorder();

    /**
     * Setter for border.
     *
     * @param value of border
     */
    public abstract void setBorder(String value);

    /**
     * Getter for cellpadding.
     *
     * This attribute specifies the amount of space between the
     * border of the cell and its contents. If the value of
     * this attribute is a pixel length, all four margins
     * should be this distance from the contents. If the value
     * of the attribute is percentage length, the top and
     * bottom margins should be equally separated from the
     * content based on percentage of the available vertical
     * space, and the left and right margins should be equally
     * separated from the content based on percentage of the
     * available horizontal space
     */
    public abstract String getCellpadding();

    /**
     * Setter for cellpadding.
     *
     * @param value of cellpadding
     */
    public abstract void setCellpadding(String value);

    /**
     * Getter for immediate.
     *
     * @return immediate value from local variable or value bindings
     */
    public abstract boolean isImmediate();

    /**
     * Getter for immediate.
     *
     * @param value of immediate
     */
    public abstract void setImmediate(boolean value);

    /**
     * Getter for selfRendered.
     *
     * If true, forces active Ajax region render response
     * directly from stored components tree, bypasses page
     * processing. Can be used for increase performance. Also,
     * must be set to 'true' inside iteration components, such
     * as dataTable
     *
     * @return selfRendered value from local variable or value bindings
     */

    public abstract boolean isSelfRendered();

    /**
     * Getter for selfRendered.
     *
     * @param value for attribute
     */
    public abstract void setSelfRendered(boolean value);

    /**
     * Getter for entryClass.
     *
     * Name of the CSS class for a suggestion entry element (table row)
     *
     * @return entryClass value from local variable or value bindings
     */
    public abstract String getEntryClass();

    /**
     * Setter for entryClass.
     *
     * @param value of entry class
     */
    public abstract void setEntryClass(String value);

    /**
     * Getter for submitted.
     * 
     * @return TRUE if submited
     */
    public boolean isSubmitted() {
        return submitted;
    }

    /**
     * Setter for submitted.
     *
     * @param s of entry class
     */
    public void setSubmitted(boolean s) {
        this.submitted = s;
    }

    public abstract int getZindex();
    
    public abstract void setZindex(int zindex);
    
    public abstract String getNothingLabel();
    
    public abstract void setNothingLabel(String nothingLabel);

    /* (non-Javadoc)
     * @see javax.faces.component.UIData#broadcast(javax.faces.event.FacesEvent)
     */
    public final void broadcast(final FacesEvent event)
            throws AbortProcessingException {
        super.broadcast(event);
        if (event instanceof AjaxEvent) {
            FacesContext context = getFacesContext();
            AjaxRendererUtils.addRegionsFromComponent(this, context);
            AjaxRendererUtils.addRegionByName(context, this, this.getId());
            setSubmitted(true);
            if (isSelfRendered()) {
                AjaxContext.getCurrentInstance(context)
                        .renderSubmittedAjaxRegion(context, true);
            }
        }
    }

    public void addAjaxListener(final AjaxListener listener) {
        addFacesListener(listener);
    }

    public AjaxListener[] getAjaxListeners() {
        return (AjaxListener[]) getFacesListeners(AjaxListener.class);
    }

    public void removeAjaxListener(final AjaxListener listener) {
        removeFacesListener(listener);
    }
}
