<?php

namespace Comitium5\DesignerBundle\Entity;

use Comitium5\DesignerBundle\Helper\Utils;
use Comitium5\DesignerBundle\Model\ContentType;
use Comitium5\DesignerBundle\Model\Interfaces\Widget\AbstractDesignerWidgetControllerInterface;
use Comitium5\DesignerBundle\Model\Interfaces\Widget\WidgetGroupInterface;
use Comitium5\DesignerBundle\Model\Interfaces\Widget\WidgetInterface;
use Comitium5\DesignerBundle\Model\Traits\DateTimeTrait;
use Comitium5\DesignerBundle\Model\WidgetType;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\File;

/**
 * Class Widget
 *
 * @author Oscar Jimenez <oscarjg19.developer@gmail.com>
 * @package Comitium5\DesignerBundle\Entity
 */
class Widget extends AbstractSerializeEntity implements WidgetInterface
{
    use DateTimeTrait;

    const WIDGET_FRONT_NAMESPACE_PATH  = 'ComitiumSuite\Bundle\CSBundle\Widgets\\';

    const WIDGET_FRONT_CONTROLLER_NAME = 'WidgetController';

    /**
     * @var
     */
    private $title;

    /**
     *
     * @var string
     */
    private $name;

    /**
     * @var string
     */
    private $description;

    /**
     * @var integer
     */
    private $version;

    /**
     * @var WidgetType
     */
    private $type;

    /**
     * @var string
     */
    private $source;

    /**
     * @var ArrayCollection
     */
    private $options;

    /**
     * @var File
     */
    private $file;

    /**
     * @var WidgetGroupInterface
     */
    private $group;

    /**
     * @var
     */
    private $widgetFavorites;

    /**
     * Widget constructor.
     */
    public function __construct()
    {
        $this->subsites = new ArrayCollection();
    }


    /**
     * @return mixed
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * @param mixed $title
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

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

    /**
     * @param string $name
     *
     * @return $this
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * @param $description
     *
     * @return $this
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getVersion()
    {
        return $this->version;
    }

    /**
     * @param $version
     *
     * @return $this
     */
    public function setVersion($version)
    {
        $this->version = $version;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * @param $type
     *
     * @return $this
     */
    public function setType($type)
    {
        $this->type = $type;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getSource()
    {
        return $this->source;
    }

    /**
     * @param $source
     *
     * @return $this
     */
    public function setSource($source)
    {
        $this->source = $source;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getControllerNameSpace()
    {
        return $this->getFolderPath().'\Controller\\'.self::WIDGET_FRONT_CONTROLLER_NAME;
    }

    /**
     * @throws \Exception
     * @return AbstractDesignerWidgetControllerInterface
     */
    public function getControllerInstance()
    {
        if (!\class_exists($this->getControllerNameSpace())) {
            throw new \Exception('Class '.$this->getControllerNameSpace().'not exists');
        }

        $namespace = $this->getControllerNameSpace();

        $controller = new $namespace();
        $controller->setWidget($this);

        return $controller;
    }

    /**
     * @param bool $asNameSpace
     *
     * @return mixed
     */
    public function getFolderPath($asNameSpace = true)
    {
        $path = $asNameSpace ? self::WIDGET_FRONT_NAMESPACE_PATH : str_replace('\\', '/', self::WIDGET_FRONT_NAMESPACE_PATH);

        return $path.$this->buildFolderName($asNameSpace);
    }

    /**
     * @param bool $asNameSpace
     *
     * @return string
     */
    public function buildFolderName($asNameSpace = true)
    {
        return $this->standard ? sprintf('Standards%s%s', $asNameSpace ? '\\' : '/', $this->formatName()) : $this->formatName();
    }

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

    /**
     * @param $option
     *
     * @return mixed
     */
    public function addOption($option)
    {
        if ($this->options === null) {
            $this->options = new ArrayCollection();
        }

        $this->options->add($option);

        return $this;
    }

    /**
     * @param $option
     *
     * @return mixed
     */
    public function removeOption($option)
    {
        $this->options->removeElement($option);

        return $this;
    }

    /**
     * @param ArrayCollection $options
     *
     * @return mixed
     */
    public function setOptions(ArrayCollection $options)
    {
        $this->options = $options;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getOptions()
    {
        return $this->options;
    }

    /**
     * @return int
     */
    public static function getSelfContentType()
    {
        return ContentType::WIDGETS;
    }

    /**
     * @param File $file
     *
     * @return mixed
     */
    public function setFile(File $file)
    {
        $this->file = $file;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getFile()
    {
        return $this->file;
    }

    /**
     * @param WidgetGroupInterface $group
     *
     * @return $this
     */
    public function setGroup(WidgetGroupInterface $group)
    {
        $this->group = $group;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getGroup()
    {
        return $this->group;
    }

    /**
     * @return mixed
     */
    public function getWidgetFavorites()
    {
        return $this->widgetFavorites;
    }

    /**
     * @param mixed $widgetFavorites
     * @return $this
     */
    public function setWidgetFavorites(ArrayCollection $widgetFavorites)
    {
        $this->widgetFavorites = $widgetFavorites;

        return $this;
    }

    /**
     * @param array $allowedFields
     * @param array $deniedFields
     * @param array $entityFields
     * @return array
     */
    public function toArray(
        $allowedFields = array(),
        $deniedFields = array("widgetFavorites"),
        $entityFields = array()
    ) {
        return parent::toArray($allowedFields, $deniedFields, $entityFields);
    }
}
