<?php
namespace FSpires\CommitKeeperBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use FSpires\CommitKeeperBundle\Model\Enum\RequestType;
use FSpires\CommitKeeperBundle\Model\Enum\Phase;
use FSpires\CommitKeeperBundle\Model\Action\ActionInterface;
use FSpires\CommitKeeperBundle\Entity\TrafficLight;
use FSpires\CommitKeeperBundle\Model\Enum\TrafficLight as TL;
use FSpires\CommitKeeperBundle\Model\TrafficLightFactoryInterface;

/**
 * FSpires\CommitKeeperBundle\Entity\Request
 *
 * @ORM\Table(name="request")
 * @ORM\Entity(repositoryClass="FSpires\CommitKeeperBundle\Entity\RequestRepository")
 */
class Request
{
    /**
     * @var string $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string $title
     * @Assert\NotBlank()
     * @ORM\Column(name="title", type="string", length=200, nullable=false)
     */
    private $title;

    /**
     * @var TrafficLight $trafficLight
     *
     * Icon to display what state the request is in
     *
     * @ORM\ManyToOne(targetEntity="TrafficLight")
     * @ORM\JoinColumn(name="traffic_light", referencedColumnName="id")
     */
    private $trafficLight;


    /**
     * @var object $trafficLightFactory;
     *
     * The service that gives new traffic light objects
     * (Not saved in the database)
     */
    private $trafficLightFactory;

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

    /**
     * @var string $phase
     *
     * @ORM\Column(name="phase_pending_by", type="string", length=1, nullable=false)
     */
    private $phasePendingBy;


    /**
     * @var object $initiator
     *
     * @ORM\ManyToOne(targetEntity="UserName")
     * @ORM\JoinColumn(name="initiator_id", referencedColumnName="id")
     */
    private $initiator;


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


    /**
     * @var object $requestor
     *
     * @ORM\ManyToOne(targetEntity="UserName")
     * @ORM\JoinColumn(name="requestor_id", referencedColumnName="id")
     */
    private $requestor;

    /**
     * @var object $performer
     *
     * @ORM\ManyToOne(targetEntity="UserName")
     * @ORM\JoinColumn(name="performer_id", referencedColumnName="id")
     */
    private $performer;


    /**
     * The due date stored in the database
     * @var date $dueDate
     *
     * @ORM\Column(name="due_date", type="date", nullable=false)
     */
    private $dueDate;

    /**
     * @var date $newDueDate
     * @Assert\Date()
     * Temporary store for a new due date before
     * it is stored in the database
     */
    private $newDueDate;

    /**
     * @var string $superRequestId
     *
     * @ORM\Column(name="super_request_id", type="integer", nullable=true)
     */
    private $superRequestId;


    /**
     * A property just to store the action when inputing
     * new data from a form
     * (This is not stored in tha database on the request table,
     * but is insterad stored in the action_history.)
     */
    private $action;

    /**
     * A property just to store a description when inputing
     * new data from a form
     * (This is not stored in tha database on the request table,
     * but is insterad stored in the action_history.)
     * @Assert\NotBlank()
     */
    private $description;


    /**
     * Initialize a new request that is about to be made
     */
    public function initNewReqest($type, $user) {
      $this->initiator = $user;
      $this->phase = Phase::Preparation;
      $this->setTrafficLight(TL::Preparation);
      switch ($type) {
      case RequestType::Request:
        $this->requestor = $user;
        $this->performer = $user->getLastPerformer();
        $this->phasePendingBy = 'R';
        break;
      case RequestType::Offer:
        $this->requestor = $user->getLastRequestor();
        $this->performer = $user;
        $this->phasePendingBy = 'P';
        break;
      case RequestType::ToDo:
        $this->requestor = $user;
        $this->performer = $user;
        $this->phasePendingBy = 'R';
        break;
      default:
        throw new \InvalidArgumentException('Invalid New Request type: '. $type);
      }

      // Set an initial priority
      $this->priority = 1;

      // Set a default due date
      $this->newDueDate = $user->getDefaultDate();
    }

    /**
     * Get requestId
     *
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

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

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

    /**
     * Set a TrafficLightFactory that is used when setting the traffic light
     */
    public function setTrafficLightFactory(TrafficLightFactoryInterface $tlf) {
      $this->trafficLightFactory = $tlf;
    }

    /**
     * Set trafficLight
     *
     * @param string $trafficLight
     */
    public function setTrafficLight($trafficLight)
    {
      if ($trafficLight instanceof TrafficLight) {
        $this->trafficLight = $trafficLight;
        return;
      }
      if (!$this->trafficLightFactory) {
        throw new UnexpectedValueException('Request->setTrafficLightFactory() must be called first to set a valid traffic light factory');
      }
      $this->trafficLight = $this->trafficLightFactory->getTrafficLight($trafficLight);
    }

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

    /**
     * Set action
     *
     * @param string $action
     */
    public function setAction($action)
    {
        $this->action = $action;
    }

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


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

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


    /**
     * Set priority
     *
     * @param string $priority
     */
    public function setPriority($priority)
    {
        $this->priority = $priority;
    }

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

    /**
     * Set phase
     *
     * @param string $phase
     */
    public function setPhase($phase)
    {
        $this->phase = $phase;
    }

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

    /**
     * Set newDueDate
     *
     * @param date $newDueDate
     */
    public function setNewDueDate($newDueDate)
    {
        $this->newDueDate = $newDueDate;
    }

    /**
     * Get newDueDate
     *
     * @return date 
     */
    public function getNewDueDate()
    {
        return $this->newDueDate;
    }

    /**
     * Set dueDate to the new due date
     */
    public function updateDueDate()
    {
        $this->dueDate = $this->newDueDate;
    }

    /**
     * Get dueDate
     *
     * @return date 
     */
    public function getDueDate()
    {
        return $this->dueDate;
    }


    /**
     * Set requestor
     *
     * @param FSpires\CommitKeeperBundle\Entity\UserBase $requestor
     */
    public function setRequestor(UserBase $requestor)
    {
        $this->requestor = $requestor;
    }

    /**
     * Get requestor
     *
     * @return FSpires\CommitKeeperBundle\Entity\UserBase
     */
    public function getRequestor()
    {
        return $this->requestor;
    }

    /**
     * Set performer
     *
     * @param FSpires\CommitKeeperBundle\Entity\UserBase $performer
     */
    public function setPerformer(UserBase $performer)
    {
        $this->performer = $performer;
    }

    /**
     * Get performer
     *
     * @return FSpires\CommitKeeperBundle\Entity\UserBase
     */
    public function getPerformer()
    {
        return $this->performer;
    }


    /**
     * Set initiator
     *
     * @param FSpires\CommitKeeperBundle\Entity\UserBase $initiator
     */
    public function setInitiator(UserBase $initiator)
    {
        $this->initiator = $initiator;
    }

    /**
     * Get initiator
     *
     * @return FSpires\CommitKeeperBundle\Entity\UserBase
     */
    public function getInitiator()
    {
        return $this->initiator;
    }

    /**
     * Set phasePendingBy
     *
     * @param string $phasePendingBy
     */
    public function setPhasePendingBy($phasePendingBy)
    {
        $this->phasePendingBy = $phasePendingBy;
    }

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

    /**
     * Set superRequestId
     *
     * @param integer $superRequestId
     */
    public function setSuperRequestId($superRequestId)
    {
        $this->superRequestId = $superRequestId;
    }

    /**
     * Get superRequestId
     *
     * @return integer 
     */
    public function getSuperRequestId()
    {
        return $this->superRequestId;
    }
}
