<?php

namespace Crowded\Expressions;

/**
 * A trait that allows for easy chaining of expression or criteria classes.
 *
 * @author Nino Floris <nino@getcrowded.co>
 */
trait JunctableTrait
{
    public function andAlso(...$expr)
    {
        $currentExpr = $this->getJunctable();

        if ($currentExpr instanceof Composite && Composite::TYPE_AND === $currentExpr->getType()) {
            $expressions = array_merge($currentExpr->getExpressionList(), $expr);
        } else {
            $expressions = array_merge([$currentExpr], $expr);
        }

        return new Composite(Composite::TYPE_AND, $expressions);
    }

    public function orElse(...$expr)
    {
        $currentExpr = $this->getJunctable();

        if ($currentExpr instanceof Composite && Composite::TYPE_OR === $currentExpr->getType()) {
            $expressions = array_merge($currentExpr->getExpressionList(), $expr);
        } else {
            $expressions = array_merge([$currentExpr], $expr);
        }

        return new Composite(Composite::TYPE_OR, $expressions);
    }

    public function negateThis()
    {
        $currentExpr = $this->getJunctable();

        return new Composite(Composite::TYPE_NOT, [$currentExpr]);
    }

    /**
     * Override this function to change the resolution of the current expression.
     *
     * @return $this
     */
    protected function getJunctable()
    {
        return $this;
    }
}
