<?php
/**
 * @package     woobooking.Platform
 * @subpackage  Database
 *
 *  Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

namespace TourOperatorPro\Database\query;
defined('_TOUROPERATOR_EXEC') or die;

/**
 * Query Element Class.
 *
 * @property-read    string $name      The name of the element.
 * @property-read    array $elements  An array of elements.
 * @property-read    string $glue      Glue piece.
 *
 * @since  11.1
 */
class DatabaseQueryElement
{
    /**
     * @var    string  The name of the element.
     * @since  11.1
     */
    protected $name = null;
    /**
     * @var    array  An array of elements.
     * @since  11.1
     */
    protected $elements = null;
    /**
     * @var    string  Glue piece.
     * @since  11.1
     */
    protected $glue = null;

    /**
     * Constructor.
     *
     * @param string $name The name of the element.
     * @param mixed $elements String or array.
     * @param string $glue The glue for elements.
     *
     * @since   11.1
     */
    public function __construct($name, $elements, $glue = ',')
    {
        $this->elements = array();
        $this->name = $name;
        $this->glue = $glue;
        $this->append($elements);
    }

    /**
     * Magic function to convert the query element to a string.
     *
     * @return  string
     *
     * @since   11.1
     */
    public function __toString()
    {
        if (substr($this->name, -2) == '()') {
            return PHP_EOL . substr($this->name, 0, -2) . '(' . implode($this->glue, $this->elements) . ')';
        } else {
            return PHP_EOL . $this->name . ' ' . implode($this->glue, $this->elements);
        }
    }

    /**
     * Appends element parts to the internal list.
     *
     * @param mixed $elements String or array.
     *
     * @return  void
     *
     * @since   11.1
     */
    public function append($elements)
    {
        if (is_array($elements)) {
            $this->elements = array_merge($this->elements, $elements);
        } else {
            $this->elements = array_merge($this->elements, array($elements));
        }
    }

    /**
     * Gets the elements of this element.
     *
     * @return  array
     *
     * @since   11.1
     */
    public function getElements()
    {
        return $this->elements;
    }

    /**
     * Sets the name of this element.
     *
     * @param string $name Name of the element.
     *
     * @return  DatabaseQueryElement  Returns this object to allow chaining.
     *
     * @since   3.6
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Method to provide deep copy support to nested objects and arrays
     * when cloning.
     *
     * @return  void
     *
     * @since   11.3
     */
    public function __clone()
    {
        foreach ($this as $k => $v) {
            if (is_object($v) || is_array($v)) {
                $this->{$k} = unserialize(serialize($v));
            }
        }
    }
}
