<?php

/**
 * This is the model class for table "event_reporting".
 *
 * The followings are the available columns in table 'event_reporting':
 * @property string $id
 * @property string $type
 * @property string $description
 * @property string $full_desciption
 * @property string $status
 * @property string $action
 * @property string $comment
 * @property string $taken_in_charge_by
 * @property string $taken_in_charge_time
 * @property string $managed_by
 * @property string $managed_time
 * @property string $event_id
 * @property string $event_uuid
 * @property string $event_table_name
 * @property string $epoch
 * @property string $id_gategroup
 * @property string $origin_type
 * @property integer $confirmation_required
 * @property string $expected_start_time
 * @property string $expected_end_time
 * @property string $confirmed_by
 * @property string $confirmation_time
 * @property string $start_time
 * @property string $in_charge_to
 * @property string $in_charge_to_time
 * @property string $terminated_by
 * @property string $termination_type
 * @property string $termination_time
 * @property string $termination_confirmed_time
 * @property string $name
 * @property string $gate
 * @property string $event_note
 * @property string $extra_data
 * @property string $exta_data
 * @property string $behavior_tag
 * @property integer $just_modified
 * @property string $event_time
 */
class Alert extends ActiveRecord implements IBookmarkObject {

    const STATUS_NEW = "new";
    const STATUS_TAKEN_IN_CHARGE = "taken_in_charge";
    const STATUS_MANAGED = "managed";
    const TYPE_ALARM = "alarm";
    const TYPE_WARNING = "warning";
    const TYPE_INFO = "info";

    public $eventCounter;
    private $instanceEvent;

    /**
     * 
     * @param system $className
     * @return Alert alert's model
     */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

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

    public function rules() {
        return array(
            array('type, description, status, event_uuid, event_table_name', 'length', 'max' => 250),
            array('taken_in_charge_by, managed_by, event_id', 'length', 'max' => 20),
            array('full_desciption, action, comment, taken_in_charge_time, managed_time, epoch', 'safe'),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, type, description, full_desciption, status, action, comment, taken_in_charge_by, taken_in_charge_time, managed_by, managed_time, event_id, event_uuid, event_table_name, epoch', 'safe', 'on' => 'search'),
        );
    }

    public function relations() {
        return array(
            'takenInChargeOperator' => array(self::BELONGS_TO, 'User', 'taken_in_charge_by'),
            'managedByOperator' => array(self::BELONGS_TO, 'User', 'managed_by'),
            'event' => array(self::BELONGS_TO, 'Event', 'event_id'),
            'vehicleTrace' => array(self::BELONGS_TO, 'VehicleTrace', array('event_uuid' => 'VehicleUUID')),
            'bookmark' => array(self::HAS_ONE, 'Bookmark', 'id_reference', 'condition' => "bookmark.type='event_reporting' AND id_user=" . user()->id),
            'myGate' => array(self::BELONGS_TO, 'Gate', array('gate' => 'Gate')),
        );
    }

    public function scopes() {
        return array(
            'new' => array('condition' => 'status = :status', 'params' => array(':status' => self::STATUS_NEW)),
            'takenInCharge' => array('condition' => 'status = :status', 'params' => array(':status' => self::STATUS_TAKEN_IN_CHARGE)),
            'managed' => array('condition' => 'status = :status', 'params' => array(':status' => self::STATUS_MANAGED)),
            'alarms' => array('condition' => 'type = :type', 'params' => array(':type' => self::TYPE_ALARM)),
        );
    }

    public function behaviors() {
        return array('edatetimebehavior' => array('class' => 'ext.EDateTimeBehavior'));
    }

    public function myAttributeLabels() {
        return array(
            'id' => 'ID',
            'type' => 'Type',
            'description' => 'Description',
            'full_desciption' => 'Full Desciption',
            'status' => 'Status',
            'action' => 'Action',
            'comment' => 'Comment',
            'taken_in_charge_by' => 'Taken In Charge By',
            'taken_in_charge_time' => 'Taken In Charge Time',
            'managed_by' => 'Managed By',
            'managed_time' => 'Managed Time',
            'event_id' => 'Event',
            'event_uuid' => 'Event Uuid',
            'event_table_name' => 'Event Table Name',
            'epoch' => 'Epoch',
        );
    }

    public function getBookmarkData() {
        $a = $this;
        $e = $this->event;
        $v = $this->vehicleTrace;

        $bd = new CArray();

        $bd->has_alert = $a != null;
        if ($a != null) {
            $bd->alert_id = $a->id;
            $bd->alert_book = Bookmark::model()->find("id_user=:usr AND id_reference=:ref AND type=:typ", array(':usr' => user()->id, ':ref' => $bd->alert_id, ':typ' => Bookmark::TYPE_ALERT));
        }

        $bd->has_event = $e != null;
        if ($e != null) {
            $bd->event_id = $e->ID;
            $bd->event_book = Bookmark::model()->find("id_user=:usr AND id_reference=:ref AND type=:typ", array(':usr' => user()->id, ':ref' => $bd->event_id, ':typ' => Bookmark::TYPE_EVENT));
        }

        $bd->has_trace = $v != null;
        if ($v != null) {
            $bd->trace_id = $v->ID;
            $bd->trace_book = Bookmark::model()->find("id_user=:usr AND id_reference=:ref AND type=:typ", array(':usr' => user()->id, ':ref' => $bd->trace_id, ':typ' => Bookmark::TYPE_VEHICLE_TRACE));
        }

        $bd->self_id = $this->id;
        $bd->self_type = Bookmark::TYPE_ALERT;
        $bd->self_book = $bd->alert_book;

        return $bd;
    }

    public function last($numOfItems) {
        $this->getDbCriteria()->limit = $numOfItems;
        $this->getDbCriteria()->order = 'epoch DESC';

        return $this;
    }

    public function youngerToOlder() {
        $this->getDbCriteria()->order = 't.epoch DESC';
        return $this;
    }

    public function olderToYounger() {
        $this->getDbCriteria()->order = 't.epoch ASC';
        return $this;
    }

    public function recently($seconds) {
        $interval = new DateInterval("PT{$seconds}S");
        $past = new DateTime();
        $past->sub($interval);

        $this->getDbCriteria()->mergeWith(
                array(
                    'condition' => 'epoch >= :pasteDateTime',
                    'params' => array(':pasteDateTime' => DateHelper::formatISO9075DateTime($past))
                )
        );
        return $this;
    }

    public function after($Time) {
        $this->getDbCriteria()->mergeWith(
                array(
                    'condition' => 'epoch >= :theStartDateTime',
                    'params' => array(':theStartDateTime' => DateHelper::formatISO9075DateTime($Time))
                )
        );

        return $this;
    }

    public function before($Time) {
        $this->getDbCriteria()->mergeWith(
                array(
                    'condition' => 'epoch <= :theEndDateTime',
                    'params' => array(':theEndDateTime' => DateHelper::formatISO9075DateTime($Time))
                )
        );

        return $this;
    }

    public function takenInChargeBy($operator) {
        $this->getDbCriteria()->mergeWith(
                array(
                    'condition' => 'taken_in_charge_by >= :takeninchargeby',
                    'params' => array(':takeninchargeby' => $operator->id)
                )
        );
        return $this;
    }

    public function managedBy($operator) {
        $this->getDbCriteria()->mergeWith(
                array(
                    'condition' => 'managed_by >= :managedby',
                    'params' => array(':managedby' => $operator->id)
                )
        );
        return $this;
    }

    public function groupByType() {
        $this->getDbCriteria()->group = 't.type';

        return $this;
    }

    public function byGate($gate) {
        if (is_object($gate)) {
            $className = get_class($gate);
            if (!empty($className) == "Gate")
                $gate = $gate->Gate;
        }

        if (!is_array($gate))
            $gate = array($gate);

        $this->getDbCriteria()->addInCondition('gate', $gate);

        return $this;
    }

    public function byType($type) {
        if (!is_array($type))
            $type = array($type);

        $this->getDbCriteria()->addInCondition('t.type', $type);

        return $this;
    }

    public function withBookmark() {
        $withCriteria = $this->getDbCriteria()->with[] = 'bookmark';

        return $this;
    }

    public function byDescription($description) {
        if (!is_array($description))
            $gates = array($description);

        $this->getDbCriteria()->addInCondition('description', $description);

        return $this;
    }

    public function selectForCount($query) {
        $selectColumns = array(
            "type",
            "count(ID) as eventCounter",
        );

        $query->mergeWith(array('select' => $selectColumns));

        return $query;
    }

    public function takeCharge($operator) {
        $this->taken_in_charge_by = $operator->id;
        $timeNow = new DateTime();
        $this->taken_in_charge_time = $timeNow;
        $this->status = self::STATUS_TAKEN_IN_CHARGE;

        return $this->save();
    }

    public function releaseCharge() {
        $this->taken_in_charge_by = null;
        $this->status = self::STATUS_NEW;

        return $this->save();
    }

    public function manage($operator) {
        $this->managed_by = $operator->id;
        $timeNow = new DateTime();
        $this->managed_time = $timeNow;
        $this->status = self::STATUS_MANAGED;

        return $this->save();
    }

    public function canEdit($userID) {
        if (!$this->isTakenInCharge())
            return false;

        if ($userID != $this->taken_in_charge_by)
            return false;

        return true;
    }

    public function isTakenInCharge() {
        return ($this->status == self::STATUS_TAKEN_IN_CHARGE);
    }

    public function isManaged() {
        return ($this->status == self::STATUS_MANAGED);
    }

    public function isNew() {
        return ($this->status == self::STATUS_NEW);
    }

    public function isBlacklist() {
        return $this->description == 'blacklist';
    }

    public function isTrafficAlarm() {
        return $this->behavior_tag == 'SlowTrafficAlarm' || $this->behavior_tag == 'StationaryTrafficAlarm' || $this->behavior_tag == 'NoTrafficAlarm';
    }

    public function hasAssociatedEvent() {
        return ($this->event_id != 0 && $this->event_id != null);
    }

    public function getAssociatedEventClass() {
        switch (strtolower( $this->event_table_name)) {
            case 'storicotable':
                return 'Event';
                break;

            case 'vehicletracetable':
                return 'VehicleTrace';
                break;
        }
        return null;
    }

    /**
     * 
     * @return IVehicleEvent
     */
    public function getAssociatedEvent() {
        $klass = $this->getAssociatedEventClass();
        if ($klass === null)
            return new NullEvent();

        if ($this->instanceEvent !== null) {
            return $this->instanceEvent;
        }
        $this->instanceEvent = $klass::model()->findByPk($this->event_id);
        if ($this->instanceEvent === null)
            return new NullEvent();
        else
            return $this->instanceEvent;
    }

    public function getPreviewPhotoUrl() {
        if ($this->hasAssociatedEvent()) {
            return $this->associatedEvent->previewPhotoUrl;
        }
    }

    public function getPreviewColorPhotoUrl() {
        if ($this->hasAssociatedEvent()) {
            return $this->associatedEvent->previewColorPhotoUrl;
        }
    }

    public function getGateLabel() {


        if ($this->hasAssociatedEvent()) {
//            if (!GateMaster::getInstance()->isGatePresent($this->associatedEvent->gate->ID)) {
//                GateMaster::getInstance()->addGate($this->associatedEvent->gate);
//            } 
//            return GateMaster::getInstance()->getGate($this->associatedEvent->gate->ID)->gateLabel;
            return $this->associatedEvent->gateLabel;
        }

        return $this->myGate->Descrizione;
    }

    public function getGateShortLabel() {
        if ($this->hasAssociatedEvent())
            return $this->associatedEvent->gateShortLabel;

        return $this->myGate->short_name;
    }

    public function getSpeedLimitSignList() {
        return $this->associatedEvent->speedLimitSignList;
    }

    public function getYellowBarType() {
        return $this->associatedEvent->yellowBarType;
    }

    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;
        //	var_dump($this->description);

        $withCriteria = array(
            'takenInChargeOperator',
            'managedByOperator',
        );


        $criteria->with = $withCriteria;
        $criteria->together = true;

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'pagination' => array(
                'pageSize' => 15,
            ),
        ));
    }

    /**
     * @param boolean $doPagination default=true
     * @return CActiveDataProvider
     */
    public function searchAlerts($doPagination = true) {
        $options = array(
            'criteria' => $this->dbCriteria,
        );
        if ($doPagination)
            $options['pagination'] = array('pageSize' => 15);
        else
            $options['pagination'] = false;

        return new CActiveDataProvider($this, $options);
    }

}
