<?php

/*
 * ROMAN DIGITAL - Autor: Américo Patetta
 */

/**
 * Description of PositionsManager
 *
 * @author pc
 */
include_once("server/class/Unit.php");
include_once("server/class/User.php");

class PositionsManager {

    //put your code here

    private $machineId = null;
    private $dao = null;

    function __construct($machineId, User $user = null) {
        if ($user->isValidated()) {
            $this->machineId = $machineId;
            $this->dao = new dbObject();
        }
    }

    function getPositionsLog($ts1, $ts2) {

        if (!is_null($this->machineId)) {
            $rQuery = sprintf("SELECT log_id as id, sub_message as subMsg,gps_timestamp as ts, lat, lng, speed as spd, azimuth as az, hours as hr, mileage as mil,"
                    . "motion_status FROM log_positions WHERE machine_id = %d AND speed >= 0 "
                    . "AND (gps_timestamp BETWEEN %d AND %d) ORDER BY gps_timestamp", $this->machineId, $ts1, $ts2);

            $maxSpeed = 0;
            $acumSpd = 0;
            $movingPoints = 0;

            $positions = $this->dao->fetchQuery($rQuery);
            $dataTags = array();
            if (is_array($positions) && count($positions)) {

                for ($i = 0; $i < count($positions); $i++) {
                    if ($positions[$i]['spd'] > $maxSpeed) {
                        $maxSpeed = $positions[$i]['spd'];
                    }
                    if ($positions[$i]['motion_status'] & 0x02) {
                        $acumSpd += floatVal($positions[$i]['spd']);
                        $movingPoints++;
                    }
                    $positions[$i]['ign'] = ($positions[$i]['motion_status'] & 0x20) ? 1 : 0;
                }

                $dataTags['startKm'] = number_format($positions[0]['mil'], 1, ".", "");
                $dataTags['endKm'] = number_format($positions[count($positions) - 1]['mil'], 1, ".", "");
                $dataTags['startHr'] = number_format($positions[0]['hr'], 1, ".", "");
                $dataTags['endHr'] = number_format($positions[count($positions) - 1]['hr'], 1, ".", "");
                $dataTags['maxSpeed'] = number_format($maxSpeed, 1, ".", "");
                $dataTags['avgSpeed'] = ($movingPoints > 0) ? (number_format($acumSpd / $movingPoints, 1, ".", "")) : 0;
                $dataTags['tasaUso'] = ($ts2 > $ts1 && $dataTags['endHr'] > $dataTags['startHr']) ? (number_format((($dataTags['endHr'] - $dataTags['startHr']) * 360000) / ($ts2 - $ts1), 0, ".", ",")) : "-";
            }

            $log['nodes'] = $positions;
            $log['stops'] = array();
            $log['dataTags'] = $dataTags;
        } else {
            $log['nodes'] = null;
            $log['stops'] = null;
            $log['dataTags'] = null;
        }
        return $log;
    }

    function getPositionsLogWithSpeedLimits($ts1, $ts2, $v1, $v2) {

        if (!is_null($this->machineId)) {
            $rQuery = sprintf("SELECT log_id as id, sub_message as subMsg,gps_timestamp as ts, lat, lng, speed as spd, azimuth as az, hours as hr, mileage as mil,"
                    . "motion_status FROM log_positions WHERE machine_id = %d AND speed >= 0 "
                    . "AND (gps_timestamp BETWEEN %d AND %d) ORDER BY gps_timestamp", $this->machineId, $ts1, $ts2);

            $maxSpeed = 0;
            $acumSpd = 0;
            $movingPoints = 0;

            $positions = $this->dao->fetchQuery($rQuery);
            $dataTags = array();
            if (is_array($positions) && count($positions)) {

                for ($i = 0; $i < count($positions); $i++) {
                    if ($positions[$i]['spd'] > $maxSpeed) {
                        $maxSpeed = $positions[$i]['spd'];
                    }
                    if ($positions[$i]['motion_status'] & 0x02) {
                        $acumSpd += floatVal($positions[$i]['spd']);
                        $movingPoints++;
                    }
                    $positions[$i]['ign'] = ($positions[$i]['motion_status'] & 0x20) ? 1 : 0;
                }

                $dataTags['startKm'] = number_format($positions[0]['mil'], 1, ".", "");
                $dataTags['endKm'] = number_format($positions[count($positions) - 1]['mil'], 1, ".", "");
                $dataTags['startHr'] = number_format($positions[0]['hr'], 1, ".", "");
                $dataTags['endHr'] = number_format($positions[count($positions) - 1]['hr'], 1, ".", "");
                $dataTags['maxSpeed'] = number_format($maxSpeed, 1, ".", "");
                $dataTags['avgSpeed'] = ($movingPoints > 0) ? (number_format($acumSpd / $movingPoints, 1, ".", "")) : 0;
                $dataTags['tasaUso'] = ($ts2 > $ts1 && $dataTags['endHr'] > $dataTags['startHr']) ? (number_format((($dataTags['endHr'] - $dataTags['startHr']) * 360000) / ($ts2 - $ts1), 0, ".", ",")) : "-";
            }

            $log['nodes'] = $positions;
            $log['stops'] = array();
            $log['dataTags'] = $dataTags;
            $log['v1'] = $this->getArbitraryOverspeedLog($ts1, $ts2, $v1, $v2);
            $log['v2'] = $this->getArbitraryOverspeedLog($ts1, $ts2, $v2, 999);
        } else {
            $log['nodes'] = null;
            $log['stops'] = null;
            $log['dataTags'] = null;
        }
        return $log;
    }

    function getDetencionesLog($ts1, $ts2) {
        $rQuery = sprintf("
                SELECT log_id,gps_timestamp,i.lat, i.lng, i.event_id, reference, nombre_poi, p.lat as p_lat, p.lng as p_lng, is_buffer, message_timestamp
                FROM f22.log_ignition i
                LEFT JOIN locations l ON l.location_id = i.location_id
                LEFT JOIN (SELECT * FROM pois where activo = 1) p ON p.id_poi = i.poi_id
                WHERE machine_id = %d AND i.event_id IN ('GTSTP','GTLSP') AND gps_timestamp BETWEEN %d AND %d
                ORDER BY gps_timestamp DESC, log_id DESC", $this->machineId, $ts1, $ts2);

        $stops = $this->dao->fetchQuery($rQuery);
        return $stops;
    }

    function getTrip($ts1, $ts2) {
        $rQuery = sprintf("SELECT DISTINCT lat,lng FROM log_positions "
                . "WHERE unit_id = '%s' "
                . "AND gps_timestamp BETWEEN (%d AND %d) "
                . "ORDER BY gps_timestamp, log_id", $this->machineId, $ts1, $ts2);
        $res = $this->dao->fetchQuery($rQuery);
        return $res;
    }

    function getEngineStartStopLog($from, $to) {
        $rQuery = sprintf("SELECT i.log_id,i.lat,i.lng,i.gps_timestamp,i.event_id,i.ign_on_off_duration as dur, l.reference,
                            p.nombre_poi, p.lat as p_lat, p.lng as p_lng
                            FROM f22.log_ignition i
                            LEFT JOIN locations l ON l.location_id = i.location_id
                            LEFT JOIN (SELECT * FROM pois where activo = 1) p ON p.id_poi = i.poi_id
                            WHERE machine_id = %s AND i.event_id IN (\"GTIGN\",\"GTIGF\") 
                            AND i.gps_timestamp BETWEEN %d AND %d
                            ORDER BY gps_timestamp, log_id", $this->machineId, $from, $to);

        $events = $this->dao->fetchQuery($rQuery);

        return $events;
    }

    function getOverspeedLog($from, $to) {

        $osRoutes = false;

        $unit = new Unit($this->machineId);
        $maxAllowedSpeed = $unit->getMaxAllowedSpeed();

        $rQuery = sprintf("SELECT gps_timestamp, lat, lng, speed, mileage FROM log_positions WHERE gps_timestamp BETWEEN %d AND %d AND machine_id = %d ", $from, $to, $this->machineId);
        $res = $this->dao->fetchQuery($rQuery);

        $wasOverSpeeding = false;
        $maxSpeed = 0;
        if (is_array($res) && count($res)) {
            foreach ($res as $node) {
                if ($node["speed"] > $maxAllowedSpeed) {
                    $maxSpeed = ($node['speed'] > $maxSpeed) ? $node['speed'] : $maxSpeed;
                    if (!$wasOverSpeeding) {
                        $overspeedRoute = array();
                        $startTs = $node['gps_timestamp'];
                        $startMil = $node['mileage'];
                    }
                    $overspeedRoute[] = $node;
                    $wasOverSpeeding = true;
                } else {
                    if ($wasOverSpeeding) {
                        if (isset($overspeedRoute) && is_array($overspeedRoute) && (count($overspeedRoute) > 1)) {

                            $os['nodes'] = $overspeedRoute;
                            $os['st'] = $startTs;
                            $os['et'] = $node['gps_timestamp'];
                            $os['max'] = $maxSpeed;
                            $os['skm'] = $startMil;
                            $os['ekm'] = $node['mileage'];
                            $osRoutes[] = $os;
                        }
                    }
                    $wasOverSpeeding = false;
                }
            }
        }

        return $osRoutes;
    }

    function getArbitraryOverspeedLog($from, $to, $minSpeed, $maxSpeed) {

        $osRoutes = false;
        $unit = new Unit($this->machineId);
        $rQuery = sprintf("SELECT lat, lng, speed FROM log_positions WHERE gps_timestamp BETWEEN %d AND %d AND machine_id = %d ", $from, $to, $this->machineId);
        $res = $this->dao->fetchQuery($rQuery);

        $wasOverSpeeding = false;
        
        if (is_array($res) && count($res)) {
            foreach ($res as $node) {
                if ($node["speed"] >= $minSpeed && $node["speed"] < $maxSpeed) {
                    if (!$wasOverSpeeding) {
                        $overspeedRoute = array();
                    }
                    $overspeedRoute[] = $node;
                    $wasOverSpeeding = true;
                } else {
                    if ($wasOverSpeeding) {
                        if (isset($overspeedRoute) && is_array($overspeedRoute) && (count($overspeedRoute) > 1)) {
                            $os['nodes'] = $overspeedRoute;
                            $osRoutes[] = $os;
                        }
                    }
                    $wasOverSpeeding = false;
                }
            }
        }
        return $osRoutes;
    }

    function getTimeline($from, $to) {
        $rQuery = sprintf("SELECT i.*,l.lat as loc_lat, l.lng as loc_lng, l.reference,
                            p.nombre_poi, p.lat as p_lat, p.lng as p_lng
                            FROM f22.log_ignition i
                            LEFT JOIN locations l ON l.location_id = i.location_id
                            LEFT JOIN (SELECT * FROM pois where activo = 1) p ON p.id_poi = i.poi_id
                            WHERE machine_id = %s AND i.event_id IN (\"GTIGN\",\"GTIGF\") 
                            AND i.gps_timestamp BETWEEN %d AND %d
                            ORDER BY gps_timestamp, log_id", $this->machineId, $from, $to);

        $events = $this->dao->fetchQuery($rQuery);
        $timeLine = array();
        $lastIgnKm = -1;

        $lastIgnTs = null;
        $lastIgfTs = null;

        if (is_array($events) && count($events)) {
            $tlIndex = 0;
            foreach ($events as $i => $event) {
                switch ($event['event_id']) {
                    case "GTIGN":

                        $lastIgnTs = $event['gps_timestamp'];

                        $timeLine[$tlIndex]['tipo'] = "PRK";
                        $timeLine[$tlIndex]['dur'] = $event['ign_on_off_duration'];
                        $timeLine[$tlIndex]['d1'] = $lastIgnTs;
                        $timeLine[$tlIndex]['d0'] = $lastIgfTs;

                        $timeLine[$tlIndex]['lat'] = $event['lat'];
                        $timeLine[$tlIndex]['lng'] = $event['lng'];
                        $tlIndex++;

                        $timeLine[$tlIndex]['tipo'] = "ARR";
                        $timeLine[$tlIndex]['lat'] = $event['lat'];
                        $timeLine[$tlIndex]['lng'] = $event['lng'];
                        $timeLine[$tlIndex]['ref'] = $event['reference'];
                        $timeLine[$tlIndex]['poi'] = $event['nombre_poi'];
                        $timeLine[$tlIndex]['d'] = $event['gps_timestamp'];
                        $tlIndex++;

                        $lastIgnKm = $event['mileage'];
                        break;

                    case "GTIGF":

                        $lastIgfTs = $event['gps_timestamp'];

                        $timeLine[$tlIndex]['tipo'] = "VIA";
                        $timeLine[$tlIndex]['d0'] = $lastIgnTs;
                        $timeLine[$tlIndex]['d1'] = $lastIgfTs;
                        $timeLine[$tlIndex]['dur'] = $event['ign_on_off_duration'];

                        $timeLine[$tlIndex]['km'] = ($lastIgnKm >= 0) ? ($event['mileage'] - $lastIgnKm) : null;
                        $tlIndex++;

                        $timeLine[$tlIndex]['tipo'] = "APA";
                        $timeLine[$tlIndex]['lat'] = $event['lat'];
                        $timeLine[$tlIndex]['lng'] = $event['lng'];
                        $timeLine[$tlIndex]['ref'] = $event['reference'];
                        $timeLine[$tlIndex]['poi'] = $event['nombre_poi'];
                        $timeLine[$tlIndex]['d'] = $event['gps_timestamp'];

                        $tlIndex++;
                        break;
                }
            }
        }


        return $timeLine;
    }

    function getKm($events, $index) {
        if ($events[$index]['event_id'] == "GTIGF") {
            // Termina un viaje, podemos determinar su extensión en Km
            $indexPrima = $index - 1;
            while ($indexPrima) {
                if ($events[$indexPrima]['event_id'] == "GTIGN") {
                    
                }
            }
        }
    }

    function getGeoReference($event) {
        $ref = ($event['nombre_poi']) ? $event['nombre_poi'] . "##" : "";
        $ref .= $event['reference'];
        return $ref;
    }

    function getMotionStatusChangeLog($ts1, $ts2, $stopTypeMask = 3) {


        /*
         * Bit 0: STOP, Bit 1: LONG STOP, Bit 2: START
         */

        $includeGroup = ($stopTypeMask & 0x01) ? "'GTSTP'" : "";
        $includeGroup .= ($stopTypeMask & 0x02) ? ((($includeGroup) ? "," : "") . "'GTLTP'") : "";
        $includeGroup .= ($stopTypeMask & 0x04) ? ((($includeGroup) ? "," : "") . "'GTSTT'") : "";
        $includeGroup = ($includeGroup) ? sprintf("AND event_id IN (%s)", $includeGroup) : "";

        $rQuery = sprintf("SELECT i.*,l.lat as loc_lat, l.lng as loc_lng, l.reference,
                            p.nombre_poi, p.lat as p_lat, p.lng as p_lng
                            FROM f22.log_ignition i
                            LEFT JOIN locations l ON l.location_id = i.location_id
                            LEFT JOIN (SELECT * FROM pois where activo = 1) p ON p.id_poi = i.poi_id
                            WHERE machine_id = %s %s 
                            AND i.gps_timestamp BETWEEN (%d AND %d)
                            ORDER BY gps_timestamp, log_id", $this->machineId, $includeGroup, $ts1, $ts2);

        $events = $this->dao->fetchQuery($rQuery);
        $dataTags = array();
        $lastIgnKm = -1;
        if (is_array($events) && count($events)) {
            
        }

        function getEngineActivityLog($from, $to) {
            
        }

    }

}
