/*
 * Copyright 2004-2014 ICEsoft Technologies Canada Corp.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS
 * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

package org.icefaces.ace.util.collections;

import org.icefaces.ace.component.column.Column;
import org.icefaces.ace.component.list.ACEList;
import org.icefaces.ace.model.filter.FilterConstraint;
import org.icefaces.ace.json.JSONArray;

import javax.el.ELResolver;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
import java.text.DateFormat;
import java.util.Date;

public class PropertyConstraintPredicate implements Predicate {
    ValueExpression filterBy;
    String filterValue;
    FilterConstraint filterConstraint;
    FacesContext facesContext;
	Column column = null;
	ACEList list = null;
	JSONArray filterValues;

    public PropertyConstraintPredicate(FacesContext context, ValueExpression filterBy, String filterValue, FilterConstraint constraint, Column column) {
        this.filterValue = filterValue;
        this.filterConstraint = constraint;
        this.facesContext = context;
        this.filterBy = filterBy;
		this.column = column;
		if (column.getFilterValues() != null) {
			try {
				filterValues = new JSONArray(filterValue);
			} catch (Exception e) {
				filterValues = null;
			}
		}
    }

    public PropertyConstraintPredicate(FacesContext context, ValueExpression filterBy, String filterValue, FilterConstraint constraint, ACEList list) {
        this.filterValue = filterValue;
        this.filterConstraint = constraint;
        this.facesContext = context;
        this.filterBy = filterBy;
		this.list = list;
		if (list.getFilterValues() != null) {
			try {
				filterValues = new JSONArray(filterValue);
			} catch (Exception e) {
				filterValues = null;
			}
		}
    }

    public boolean evaluate(Object object) {
        Object value = filterBy.getValue(facesContext.getELContext());

        if (value instanceof Date)
            value = DateFormat.getDateInstance().format(value);

		if (value != null) {
			if (filterValues != null) {
				for (int i = 0; i < filterValues.length(); i++) {
					String fv;
					try {
						fv = filterValues.getString(i);
					} catch (Exception e) {
						fv = null;
					}
					if (fv != null && filterConstraint.applies(value.toString(), fv)) return true;
				}
				if (filterValues.length() == 0) return true;
				return false;
			} else {
				return filterConstraint.applies(value.toString(), filterValue);
			}
		} else if (filterValues != null && filterValues.length() > 0)
			return false;
        else if (filterValue != null && filterValue.length() > 0)
            return false;
        else
            return true;
    }
}
