<?php
require_once __DIR__ .'/../../../includes/Event.php';

App::uses('AppModel', 'Model');
/**
 * Event Model
 *
 * @property Monitor $Monitor
 * @property Frame $Frame
 */
class Event extends AppModel {

/**
 * Use table
 *
 * @var mixed False or table name
 */
	public $useTable = 'Events';

/**
 * Primary key field
 *
 * @var string
 */
	public $primaryKey = 'Id';

/**
 * Display field
 *
 * @var string
 */
	public $displayField = 'Name';

  // For events that never wrote EndDateTime (zmc killed/crashed mid-event),
  // fall back to StartDateTime + Length (Length is flushed to the DB every few
  // seconds during recording, so it reflects the actual recorded duration).
  // Only fall back to NOW() if Length is also 0 (event has no recorded data
  // yet, e.g. just started). This prevents montagereview and other consumers
  // from painting an event bar across hours/days of no real recording.
  public $virtualFields = array(
    'StartTimeSecs' => 'UNIX_TIMESTAMP(StartDateTime)',
    'EndTimeSecs' => '(CASE WHEN Event.EndDateTime IS NOT NULL THEN UNIX_TIMESTAMP(Event.EndDateTime) WHEN Event.Length > 0 THEN UNIX_TIMESTAMP(Event.StartDateTime) + Event.Length ELSE UNIX_TIMESTAMP(Event.StartDateTime) END)',
    'StartTime' => 'StartDateTime',
    'EndTime' => '(CASE WHEN Event.EndDateTime IS NOT NULL THEN Event.EndDateTime WHEN Event.Length > 0 THEN DATE_ADD(Event.StartDateTime, INTERVAL FLOOR(Event.Length) SECOND) ELSE NOW() END)'
  );

	//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */
	public $belongsTo = array(
		'Monitor' => array(
			'className' => 'Monitor',
			'foreignKey' => 'MonitorId',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		),
    'Storage' =>  array(
      'className' => 'Storage',
      'joinTable' => 'Storage',
      'foreignKey' => 'StorageId',
      'conditions' => '',
      'fields' => '',
      'order' => ''
      )
	);

/**
 * hasMany associations
 *
 * @var array
 */
	public $hasMany = array(
		'Frame' => array(
			'className' => 'Frame',
			'foreignKey' => 'EventId',
			'dependent' => true,
			'conditions' => '',
			'fields' => '',
			'order' => '',
			'limit' => '',
			'offset' => '',
			'exclusive' => 'true',
			'finderQuery' => '',
			'counterQuery' => ''
		)
	);

   /**
    *     *  * hasMany associations
    *         *   *
    *             *    * @var array
    *                 *     */
  public $hasAndBelongsToMany = array(
    'Group' => array(
      'className' => 'Group',
      'joinTable' =>  'Groups_Monitors',
      'foreignKey' => 'MonitorId',
      'associationForeignKey' => 'MonitorId',
      'unique'      =>  true,
      'dependent' => false,
      'conditions' => '',
      'fields' => '',
      'order' => '',
      'limit' => '',
      'offset' => '',
      'exclusive' => '',
      'finderQuery' => '',
      'counterQuery' => ''
    ),
    'Tag' => array(
      'className' => 'Tag',
      'joinTable' =>  'Events_Tags',
      'foreignKey' => 'EventId',
      'associationForeignKey' => 'TagId',
      'unique'      =>  true,
      'dependent' => false,
      'conditions' => '',
      'fields' => '',
      'order' => '',
      'limit' => '',
      'offset' => '',
      'exclusive' => '',
      'finderQuery' => '',
      'counterQuery' => ''
    ),
  );

  public $actsAs = array(
    'Containable',
    'CakePHP-Enum-Behavior.Enum' => array(
      'Orientation'     => array('ROTATE_0','ROTATE_90','ROTATE_180','ROTATE_270','FLIP_HORI','FLIP_VERT'),
      'Scheme'          => array('Deep','Medium','Shallow')
    )
  );

  public function Relative_Path() {
    $Event = ZM\Event::find_one(['Id'=>$this->id]);
    return $Event ? $Event->Relative_Path() : '';
  } // end function Relative_Path()

  public function Path() {
    $Event = ZM\Event::find_one(['Id'=>$this->id]);
    return $Event ? $Event->Path() : '';
  }

  public function Link_Path() {
    $Event = ZM\Event::find_one(['Id'=>$this->id]);
    return $Event ? $Event->Link_Path() : '';
  }

  public function fileExists($event) {
    if ($event['DefaultVideo']) {
      if (file_exists($this->Path().'/'.$event['DefaultVideo'])) {
        return 1;
      }

      // While an event is recording its DefaultVideo is incomplete.mp4. When
      // the event closes the file is renamed to <Id>-video.* and the DB row is
      // updated. If we still see incomplete.mp4 the model is likely stale, so
      // reload the event from the database and re-check the new DefaultVideo.
      if (preg_match('/^incomplete\./', basename($event['DefaultVideo']))) {
        ZM\Event::clear_cache();
        $Event = ZM\Event::find_one(array('Id'=>$this->id));
        if ($Event and $Event->DefaultVideo() and $Event->DefaultVideo() != $event['DefaultVideo']
            and file_exists($Event->Path().'/'.$Event->DefaultVideo())) {
          return 1;
        }
      }

      ZM\Warning('File does not exist at ' . $this->Path().'/'.$event['DefaultVideo'] );
    } else {
      return 0;
    }
  } // end function fileExists($event)

  public function fileSize($event) {
    return filesize($this->Path().'/'.$event['DefaultVideo']);
  }

  public function beforeDelete($cascade=true) {
    $Event = ZM\Event::find_one(['Id'=>$this->id]);
    if ($Event) $Event->delete();
    // Event->delete() will do it all, so cake doesn't have to do anything.
    return false;
  } // end function afterDelete
}
