/*
 * ICESOFT COMMERCIAL SOURCE CODE LICENSE V 1.1
 *
 * The contents of this file are subject to the ICEsoft Commercial Source
 * Code License Agreement V1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of the
 * License at
 * http://www.icesoft.com/license/commercial-source-v1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * Copyright 2009-2015 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 */
package com.icesoft.faces.facelets.component.util;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;


public class Util {
    public static String getServletContextParameter(String parameter) {
        // Get the servlet context based on the faces context
        ServletContext sc = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();

        // Return the value read from the parameter
        return sc.getInitParameter(parameter);
    }

    /**
     * Get parameter value from request scope.
     *
     * @param name the name of the parameter
     * @return the parameter value
     */
    public static String getRequestParameter(String name) {
        return FacesContext.getCurrentInstance().getExternalContext()
                .getRequestParameterMap().get(name);
    }

    /**
     * Get managed bean based on the bean name.
     *
     * @param beanName the bean name
     * @return the managed bean associated with the bean name
     */
    public static Object getManagedBean(String beanName) {
        FacesContext fc = FacesContext.getCurrentInstance();
        ELContext elc = fc.getELContext();
        ExpressionFactory ef = fc.getApplication().getExpressionFactory();
        ValueExpression ve = ef.createValueExpression(elc, getJsfEl(beanName), Object.class);
        return ve.getValue(elc);
    }

    private static String getJsfEl(String value) {
        return "#{" + value + "}";
    }

    /**
     * Store the managed bean inside the request scope.
     *
     * @param beanName    the name of the managed bean to be stored
     * @param managedBean the managed bean to be stored
     */
    public static void setManagedBeanInRequest(String beanName, Object managedBean) {
        FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(beanName, managedBean);
    }

    public static void clearAllUIInputs(UIComponent comp) {
        if (comp instanceof UIInput) {
            UIInput uiC = (UIInput) comp;
            uiC.setValue(null);
            uiC.setSubmittedValue(null);
            uiC.setLocalValueSet(false);
            uiC.setValid(true);
        }
        if (comp.getChildCount() > 0) {
            for (UIComponent uiComponent : comp.getChildren()) {
                clearAllUIInputs(uiComponent);
            }
        }
        if (comp.getFacets().size() > 0) {
            Map fMap = comp.getFacets();
            for (Object o : fMap.entrySet()) {
                Entry entry = (Entry) o;
                clearAllUIInputs((UIComponent) entry.getValue());
            }
        }
    }

    /**
     * Finds component with the given id.
     *
     * @param c  component check children of.
     * @param id id of component to search for.
     * @return found component if any.
     */
    public static UIComponent findComponent(UIComponent c, String id) {

        if (id.equals(c.getId())) {
            return c;
        }

        Iterator<UIComponent> kids = c.getFacetsAndChildren();

        while (kids.hasNext()) {
            UIComponent found = findComponent(kids.next(), id);

            if (found != null) {
                return found;
            }
        }

        return null;
    }


}
