/*
 * Copyright 2016 Bridje Framework.
 *
 * 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.bridje.orm;

import java.util.ArrayList;
import java.util.List;

/**
 * Represents a database column associated with a field of an Entity, or a
 * function column. Objects from this class will be generated by the ORM api so
 * the user can use then for building the querys for the Entities of his data
 * model. Ex: MyEntity_.someColumn.eq("A Name") => Condition for
 * MyEntity.someColumn field.
 *
 * @param <E> The type for the entity that this column belongs to.
 * @param <T> The type of the column.
 */
public class Column<E, T>
{
    private final Table<E> table;

    private final String field;

    private final Class<T> type;

    private String function;

    private List<Object> parameters;

    /**
     * This constructor is used to create a column without any funcions, a
     * column constructed by this constructor along will represent the plain
     * database column with no functions, columns must be created with the table
     * object they belong to, the field name as declared in the entity class,
     * and the Type of the field.
     *
     * @param table The Table object this columns belong to.
     * @param field The field name for the declared java field in the base
     * entity class.
     * @param type The java type for this column.
     */
    public Column(Table<E> table, String field, Class<T> type)
    {
        this.table = table;
        this.field = field;
        this.type = type;
    }

    /**
     * This constructor is used to create a column with a function or operator.
     *
     * @param table The Table object this columns belong to.
     * @param field The field name for the declared java field in the base
     * entity class.
     * @param type The java type for this column.
     * @param function The function expresion to be use when selialize this
     * object to a query.
     * @param parameters The parameters list on the current query, that this
     * column must have for correct serialization.
     */
    public Column(Table<E> table, String field, Class<T> type, String function, List<Object> parameters)
    {
        this.table = table;
        this.field = field;
        this.type = type;
        this.function = function;
        if (parameters != null)
        {
            this.parameters = new ArrayList<>();
            this.parameters.addAll(parameters);
        }
    }

    /**
     * Gets the function expresion for this column, if any. if this functions
     * return null or empty it means that this object represents a plain column
     * with no functions.
     *
     * @return The function expression or null if none exists.
     */
    public String getFunction()
    {
        return function;
    }

    /**
     * The table this column belongs to.
     *
     * @return A Table object representing the table this column belongs to.
     */
    public Table<E> getTable()
    {
        return table;
    }

    /**
     * Gets the field name for the declared java field in the base entity class.
     *
     * @return The field name for the declared java field in the base entity
     * class.
     */
    public String getField()
    {
        return field;
    }

    /**
     * Gets the java type for this column.
     *
     * @return The java type for this column.
     */
    public Class<T> getType()
    {
        return type;
    }

    /**
     * Creates a new equals "=" condition with this column as a left operand and
     * the provided value as the left operand.
     *
     * @param value The right operaand for the condition.
     * @return The new created condition.
     */
    public Condition eq(T value)
    {
        return new BinaryCondition(this, Operator.EQ, value);
    }

    /**
     * Creates a new not equals "&lt;&gt;" condition with this column as a left
     * operand and the provided value as the left operand.
     *
     * @param value The right operaand for the condition.
     * @return The new created condition.
     */
    public Condition ne(T value)
    {
        return new BinaryCondition(this, Operator.NE, value);
    }

    /**
     * Creates a new greather than "&gt;" condition with this column as a left
     * operand and the provided value as the left operand.
     *
     * @param value The right operator for the condition.
     * @return The new created condition.
     */
    public Condition gt(T value)
    {
        return new BinaryCondition(this, Operator.GT, value);
    }

    /**
     * Creates a new greather than or equals to "&gt;=" condition with this
     * column as a left operand and the provided value as the left operand.
     *
     * @param value The right operaand for the condition.
     * @return The new created condition.
     */
    public Condition ge(T value)
    {
        return new BinaryCondition(this, Operator.GE, value);
    }

    /**
     * Creates a new leaser than "&lt;" condition with this column as a left
     * operand and the provided value as the left operand.
     *
     * @param value The right operaand for the condition.
     * @return The new created condition.
     */
    public Condition lt(T value)
    {
        return new BinaryCondition(this, Operator.LT, value);
    }

    /**
     * Creates a new leaser than or equals to "&lt;=" condition with this column
     * as a left operand and the provided value as the left operand.
     *
     * @param value The right operaand for the condition.
     * @return The new created condition.
     */
    public Condition le(T value)
    {
        return new BinaryCondition(this, Operator.LE, value);
    }

    /**
     * Creates a new ascending order by statement that can be user to order a
     * query that involves the entity of this column.
     *
     * @return The new ascending OrderBy statement.
     */
    public OrderBy asc()
    {
        return new OrderBy(OrderByType.ASC, this);
    }

    /**
     * Creates a new descending order by statement that can be user to order a
     * query that involves the entity of this column.
     *
     * @return The new descending OrderBy statement.
     */
    public OrderBy desc()
    {
        return new OrderBy(OrderByType.DESC, this);
    }

    /**
     * Adds a new parameter to this column, this method should only be use in
     * the functions columns, that needs parameters when they are serialize to
     * create and execute the query into the database.
     *
     * @param param The param to be added.
     */
    protected void addParameter(Object param)
    {
        if (parameters == null)
        {
            parameters = new ArrayList<>();
        }
        parameters.add(param);
    }

    /**
     * Gets the parameters list for the function expresion for this column, if
     * any. if this functions return null or empty it means that this object
     * represents that no parameter has being put into this column.
     *
     * @return The parameters list or null if none exists.
     */
    public List<Object> getParameters()
    {
        return parameters;
    }
}

@@ -959,17 +959,16 @@
 Name%22) =
-%3E
  Conditi

Fix release errors.