package org.seasar.jsf.validator;

import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import org.seasar.jsf.util.LongValidatorUtil;
import org.seasar.jsf.util.MessageUtil;
import org.seasar.jsf.util.UIComponentUtil;

public class S2LongRangeValidator implements Validator, StateHolder {

    public static final String MAXIMUM_MESSAGE_ID = "javax.faces.validator.LongRangeValidator.MAXIMUM";

    public static final String MINIMUM_MESSAGE_ID = "javax.faces.validator.LongRangeValidator.MINIMUM";

    private Long minimum = null;

    private Long maximum = null;

    private boolean bTransient = false;

    public void validate(FacesContext context, UIComponent component,
            Object value) throws ValidatorException {

        if (value == null) {
            return;
        }
        double dvalue = LongValidatorUtil.parseLongValue(context, component, value);
        if (minimum != null && maximum != null) {
            if (dvalue < minimum.longValue() || dvalue > maximum.longValue()) {
                Object[] args = { minimum, maximum,
                        UIComponentUtil.getLabel(component) };
                throw new ValidatorException(MessageUtil.getErrorMessage(
                        NOT_IN_RANGE_MESSAGE_ID, args));
            }
        } else if (minimum != null) {
            if (dvalue < minimum.longValue()) {
                Object[] args = { minimum, UIComponentUtil.getLabel(component) };
                throw new ValidatorException(MessageUtil.getErrorMessage(
                        MINIMUM_MESSAGE_ID, args));
            }
        } else if (maximum != null) {
            if (dvalue > maximum.longValue()) {
                Object[] args = { maximum, UIComponentUtil.getLabel(component) };
                throw new ValidatorException(MessageUtil.getErrorMessage(
                        MAXIMUM_MESSAGE_ID, args));
            }
        }
    }

    public long getMaximum() {
        return maximum != null ? maximum.longValue() : Long.MAX_VALUE;
    }

    public void setMaximum(long maximum) {
        this.maximum = new Long(maximum);
    }

    public long getMinimum() {
        return minimum != null ? minimum.longValue() : Long.MIN_VALUE;
    }

    public void setMinimum(long minimum) {
        this.minimum = new Long(minimum);
    }

    public boolean isTransient() {
        return bTransient;
    }

    public void setTransient(boolean transientValue) {
        this.bTransient = transientValue;
    }

    public Object saveState(FacesContext context) {
        Object values[] = new Object[2];
        values[0] = maximum;
        values[1] = minimum;
        return values;
    }

    public void restoreState(FacesContext context, Object state) {
        Object values[] = (Object[]) state;
        maximum = (Long) values[0];
        minimum = (Long) values[1];
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof S2LongRangeValidator)) {
            return false;
        }
        final S2LongRangeValidator longRangeValidator = (S2LongRangeValidator) o;
        if (maximum != null ? !maximum.equals(longRangeValidator.maximum)
                : longRangeValidator.maximum != null) {
            return false;
        }
        if (minimum != null ? !minimum.equals(longRangeValidator.minimum)
                : longRangeValidator.minimum != null) {
            return false;
        }
        return true;
    }
}