<?php

/**
 * Class Entity
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is protected by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\Webservices\ObjectBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;

/**
 * Class Object
 *
 * @ORM\Entity
 * @ORM\Table(
 *     name="obj_object",
 *     indexes={
 *          @Orm\Index(name="reference_idx", columns={"reference_id"}),
 *          @Orm\Index(name="obj_name_idx", columns={"lower_name"}),
 *          @Orm\Index(name="tree_idx", columns={"tree_id"})
 *     }
 * )
 * @ORM\HasLifecycleCallbacks()
 *
 * @copyright  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package    Sso\Webservices\ObjectBundle\Entity
 */
class Object
{
    CONST INVALID_TREE_ID = 'INVALID';

    /**
     * @var string
     *
     * @ORM\Column(name="guid", type="uuid", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $guid;

    /**
     * @var string
     *
     * @ORM\Column(name="reference_id", type="string", length=255, unique=true)
     */
    private $referenceId;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="Object", mappedBy="parent")
     * */
    private $children;

    /**
     * @var Object
     *
     * @ORM\ManyToOne(targetEntity="Object", inversedBy="children",cascade={"persist"})
     * @ORM\JoinColumn(name="parent_guid", referencedColumnName="guid", onDelete="CASCADE")
     * */
    private $parent;

    /**
     * @var string
     *
     * @ORM\Column(name="parent_guid", type="uuid", unique=false, nullable=true)
     */
    private $parentGuid;

    /**
     * @var Type
     *
     * @ORM\ManyToOne(targetEntity="Type", inversedBy="objects",cascade={"persist"})
     * @ORM\JoinColumn(name="type_id", referencedColumnName="id", nullable=false)
     */
    private $type;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="lower_name", type="string", length=255, nullable=false)
     */
    private $lowerName;

    /**
     * @var ObjectAttributeValue[]
     *
     * @ORM\OneToMany(targetEntity="ObjectAttributeValue", mappedBy="object", fetch="EAGER")
     */
    private $attributeValues;

    /**
     * ORM Mapping
     * @ORM\Column(name="created", type="datetime", nullable=false)
     *
     * Define Var Type
     * @var \DateTime
     *
     */
    private $created;

    /**
     * ORM Mapping
     * @ORM\Column(name="updated", type="datetime", nullable=false)
     *
     * Define Var Type
     * @var \DateTime
     *
     */
    private $updated;

    /**
     * ORM Mapping
     * @ORM\Column(name="active", type="boolean",options={"default"= 0})
     *
     * Define Var Type
     * @var boolean
     *
     */
    private $active = false;

    /**
     * @var string
     *
     * @ORM\Column(name="tree_id", type="string", length=64, nullable=true)
     */
    private $treeId;


    public function __construct()
    {
        $this->guid = Uuid::uuid4();
        $this->children = new ArrayCollection();
        $this->attributeValues = new ArrayCollection();
    }

    /**
     * Set guid
     *
     * @param string $guid
     * @return Object
     */
    public function setGuid($guid)
    {

        $this->guid = $guid instanceof UuidInterface ? $guid : Uuid::fromString($guid);

        return $this;
    }

    /**
     * Get guid
     *
     * @return string
     */
    public function getGuid()
    {
        return (string)$this->guid;
    }

    /**
     * @return string
     */
    public function getReferenceId()
    {
        return $this->referenceId;
    }

    /**
     * @param string $referenceId
     * @return Object
     */
    public function setReferenceId($referenceId)
    {
        $this->referenceId = $referenceId;

        return $this;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Object
     */
    public function setName($name)
    {
        $this->name = $name;
        $this->setLowerName(mb_strtolower($name, 'utf-8'));
        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set lowerName
     *
     * @param string $lowerName
     * @return Object
     */
    public function setLowerName($lowerName)
    {
        $this->lowerName = $lowerName;

        return $this;
    }

    /**
     * Get lowerName
     *
     * @return string
     */
    public function getLowerName()
    {
        return $this->lowerName;
    }

    /**
     * Add children
     *
     * @param \Sso\Webservices\ObjectBundle\Entity\Object $children
     * @return Object
     */
    public function addChild(\Sso\Webservices\ObjectBundle\Entity\Object $children)
    {
        $this->children[] = $children;

        return $this;
    }

    /**
     * Remove children
     *
     * @param \Sso\Webservices\ObjectBundle\Entity\Object $children
     */
    public function removeChild(\Sso\Webservices\ObjectBundle\Entity\Object $children)
    {
        $this->children->removeElement($children);
    }

    /**
     * Get children
     *
     * @return Object[]
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * Set parent
     *
     * @param \Sso\Webservices\ObjectBundle\Entity\Object $parent
     * @return Object
     */
    public function setParent(\Sso\Webservices\ObjectBundle\Entity\Object $parent = null)
    {
        if ($parent === $this) {
            throw new \InvalidArgumentException('parent should not point to object itself (' . $parent->getGuid() . ")");
        }
        $this->parent = $parent;

        return $this;
    }

    /**
     * Get parent
     *
     * @return \Sso\Webservices\ObjectBundle\Entity\Object
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Set type
     *
     * @param \Sso\Webservices\ObjectBundle\Entity\Type $type
     * @return Object
     */
    public function setType(\Sso\Webservices\ObjectBundle\Entity\Type $type)
    {
        $this->type = $type;

        return $this;
    }

    /**
     * Get type
     *
     * @return \Sso\Webservices\ObjectBundle\Entity\Type
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Add attributeValues
     *
     * @param \Sso\Webservices\ObjectBundle\Entity\ObjectAttributeValue $attributeValues
     * @return Object
     */
    public function addAttributeValue(\Sso\Webservices\ObjectBundle\Entity\ObjectAttributeValue $attributeValues)
    {
        $this->attributeValues[] = $attributeValues;

        return $this;
    }

    /**
     * Remove attributeValues
     *
     * @param \Sso\Webservices\ObjectBundle\Entity\ObjectAttributeValue $attributeValues
     */
    public function removeAttributeValue(\Sso\Webservices\ObjectBundle\Entity\ObjectAttributeValue $attributeValues)
    {
        $this->attributeValues->removeElement($attributeValues);
    }

    /**
     * Get attributeValues
     *
     * @return ObjectAttributeValue[]
     */
    public function getAttributeValues()
    {
        return $this->attributeValues;
    }

    /**
     * Set created
     *
     * @ORM\PrePersist
     */
    public function setCreatedAt()
    {
        $this->created = new \DateTime();
        $this->updated = new \DateTime();
    }

    /**
     * Get created
     *
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }

    /**
     * Set updated
     *
     * @ORM\PreUpdate
     */
    public function setUpdated()
    {
        $this->updated = new \DateTime();
    }

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function clearTreeId()
    {
        $this->treeId = '';
    }

    /**
     * Get updated
     *
     * @return \DateTime
     */
    public function getUpdated()
    {
        return $this->updated;
    }

    /**
     * Set active
     *
     * @param boolean $active
     * @return Object
     */
    public function setActive($active)
    {
        $this->active = $active;

        return $this;
    }

    /**
     * Get active
     *
     * @return boolean
     */
    public function getActive()
    {
        return $this->active;
    }

    /**
     * @return string
     */
    public function getTypeId()
    {
        return $this->getType() === null ? null : $this->getType()->getId();
    }

    /**
     * @return string
     */
    public function getTypeName()
    {
        return $this->getType() === null ? null : $this->getType()->getName();
    }

    /**
     * @return string
     */
    public function getTypeOrder()
    {
        return $this->getType() === null ? null : $this->getType()->getTypeOrder();
    }

    /**
     * @return string
     */
    public function getParentGuid()
    {
        return $this->parentGuid;
    }

    /**
     * @param string $parentGuid
     * @return Object
     */
    public function setParentGuid($parentGuid)
    {
        $this->parentGuid = $parentGuid;
        return $this;
    }

    /**
     * @return string
     */
    public function getTreeId()
    {
        return $this->treeId;
    }

    /**
     * @param string $treeId
     * @return Object
     */
    public function setTreeId($treeId)
    {
        $this->treeId = $treeId;
        return $this;
    }
}
