<?php declare(strict_types=1);
namespace Newland\Contracts\Neos\Filter;

/*
 * This file is part of the "neos-filtering" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use Doctrine\ORM\Query\Expr;
use TYPO3Fluid\Fluid\Core\Rendering\RenderableInterface;

/**
 * A node in the filter tree.
 * A filter item can be everything from a specific input field adding a WHERE clause to the query
 * to a whole section containing children items or even invisible items that only contain
 * query behaviour.
 *
 * A normal filter could look something like this - with ever node in the tree being a filter item:
 *                      (ROOT)
 *                    /        \
 *   Section "categories"      Section "Properties"
 *     /                         /        \
 * Checkbox List        Checkbox List    Group: OR
 *                                        /      \
 *                            Range: Duration    Select: Difficulty
 */
interface FilterItem extends RenderableInterface
{

    /**
     * Returns a database expression that mirrors the item state.
     * This expression is applied to a database query in order to get the filtered results.
     *
     * Note: The entity that is being filtered for is always aliased as `entity`.
     *
     * @param Expr $expr
     * @return Expression An expression built by the given expression builder.
     */
    public function queryExpression(Expr $expr): Expression;

    /**
     * Sets the current state of the field.
     * This is meant to communicate the current value assignment of the field used when re-rendering
     * the form after submission. It contains information such as the string the user has provided
     * or wether or not the checkbox is checked.
     *
     * @param mixed $value
     */
    public function setState($value): void;

    /** @return mixed */
    public function getState();

    public function getId(): string;

    public function setConfiguration(array $configuration): void;

    public function getConfiguration(): array;

    public function setRoot(FilterRoot $root): void;

    public function getRoot(): FilterRoot;

    public function hasVisibleState(): bool;

    public function __toString(): string;
}
