<?php

/**
 * This is the model class for table "user_service_session".
 *
 * The followings are the available columns in table 'user_service_session':
 * @property integer $id
 * @property integer $id_user
 * @property integer $id_run
 * @property string $event_ids
 * @property string $create_time
 * @property string $update_time
 * 
 * @property Event firstEvent
 * @property Event lastEvent
 */
class UserEventQueue extends ActiveRecord
{

  public static function model($className=__CLASS__)
  {
    return parent::model($className);
  }

  public function tableName()
  {
    return 'user_service_session';
  }

  public function rules()
  {
    return array(
        array('id_run, id_user, event_ids', 'required'),
    );
  }

  public function relations()
  {
    return array(
        'user' => array(self::BELONGS_TO, 'User', 'id_user'),
        'service' => array(self::BELONGS_TO, 'Service', 'id_run'),
    );
  }

  public function behaviors()
  {
    return array(
        'CTimestampBehavior' => array(
            'class' => 'zii.behaviors.CTimestampBehavior',
            'setUpdateOnCreate' => true,
        )
    );
  }

  protected function afterFind()
  {
    $result = parent::afterFind();
    $this->event_ids = unserialize($this->event_ids);

    return $result;
  }

  protected function beforeSave()
  {
    $result = parent::beforeSave();
    $this->event_ids = serialize($this->event_ids);

    return $result;
  }

  protected function afterSave()
  {
    $result = parent::afterSave();
    $this->event_ids = unserialize($this->event_ids);

    return $result;
  }

  /**
   *
   * @return number
   */
  public function getEventsCount()
  {
    return count($this->event_ids);
  }

  /**
   *
   * @param Event $currentEvent
   * @return boolean
   */
  public function isFirst(Event $currentEvent)
  {
    return $this->event_ids[0] == $currentEvent->ID;
  }

  /**
   *
   * @param Event $currentEvent
   * @return boolean
   */
  public function isLast(Event $currentEvent)
  {
    return $this->event_ids[count($this->event_ids)-1] == $currentEvent->ID;
  }

  /**
   * set 'event_ids' to the ids of the give array of Event objects
   * @param Event[] $events
   */
  public function queueEvents($events)
  {
    $this->event_ids = array_map(function($event){
      return $event->ID;
    }, $events);
  }

  /**
   *
   * @return Event
   */
  public function getLastEvent()
  {
    return Event::model()->findByPk($this->event_ids[count($this->event_ids)-1]);
  }

  /**
   *
   * @return Event
   */
  public function getFirstEvent()
  {
    return Event::model()->findByPk($this->event_ids[0]);
  }

  /**
   *
   * @return Event
   */
  public function getPreviousEvent($currentEvent, $step = 1)
  {
    $nearbyEvents = $this->getNearbyEvents($currentEvent);
    return $nearbyEvents['previous'];
  }

  /**
   *
   * @return Event
   */
  public function getNextEvent($currentEvent, $step = 1)
  {
    $nearbyEvents = $this->getNearbyEvents($currentEvent);
    return $nearbyEvents['next'];
  }

  /**
   *
   * @return Event[]
   */
  private function getNearbyEvents($currentEvent, $step = 1)
  {
    $nearbyEvents = array();
    $nearbyEvents["previous"] = null;
    $nearbyEvents["next"] = null;

    if (($index = array_search($currentEvent->ID, $this->event_ids)) === false)
      return $nearbyEvents;

    $previousIndex = $index -$step;
    $nextIndex = $index +$step;

    if ($previousIndex >= 0)
      $nearbyEvents["previous"] = Event::model()->findByPk($this->event_ids[$previousIndex]);

    if ($nextIndex < count($this->event_ids))
      $nearbyEvents["next"] = Event::model()->findByPk($this->event_ids[$nextIndex]);

    return $nearbyEvents;
  }

  /**
   *
   * @return int
   */
  public function getEventIndex($currentEvent)
  {
    if (($index = array_search($currentEvent->ID, $this->event_ids)) === false)
      return -1;
     
    return $index;
  }
}
