<?php

class GeoUtils {

    public static function getRoutes($orgId) {
        $dao = new dbObject();
        $q = sprintf("SELECT * FROM routes WHERE id_organizacion=%s", $orgId);
        $res = $dao->fetchQuery($q);
        return $res;
    }

    public static function getRouteNodes($routeId) {
        $dao = new dbObject();
        $q = sprintf("SELECT * FROM route_nodes WHERE route_id = %s ORDER BY node_index", $routeId);
        $res = $dao->fetchQuery($q);
        return $res;
    }

    public static function getPoiList($anUser = null) {
        $q = "SELECT * FROM pois p 
			  LEFT JOIN tipos_de_pois t
			  ON p.id_tipo_poi = t.id_tipo_de_poi
			  WHERE p.mostrar=1";
        $dao = new dbObject();
        $res = $dao->fetchQuery($q);
        return $res;
    }

    public static function getRumbo($aHeading, $longFormat = false) {

        $rumbo = "-";
        if ($aHeading < 22.5) {
            $rumbo = ($longFormat) ? "Norte" : "N";
        } elseif (($aHeading >= 22.5) && ($aHeading < 67.5)) {
            $rumbo = ($longFormat) ? "Noreste" : "NE";
        } elseif (($aHeading >= 67.5) && ($aHeading < 112.5)) {
            $rumbo = ($longFormat) ? "Este" : "E";
        } elseif (($aHeading >= 112.5) && ($aHeading < 157.5)) {
            $rumbo = ($longFormat) ? "Sudeste" : "SE";
        } elseif (($aHeading >= 157.7) && ($aHeading < 202.5)) {
            $rumbo = ($longFormat) ? "Sur" : "S";
        } elseif (($aHeading >= 202.5) && ($aHeading < 247.5)) {
            $rumbo = ($longFormat) ? "Sudoeste" : "SO";
        } elseif (($aHeading >= 247.5) && ($aHeading < 292.5)) {
            $rumbo = ($longFormat) ? "Oeste" : "O";
        } elseif (($aHeading >= 292.5) && ($aHeading < 337.5)) {
            $rumbo = ($longFormat) ? "Noroeste" : "NO";
        } elseif (($aHeading >= 337.5)) {
            $rumbo = ($longFormat) ? "Norte" : "N";
        }
        return $rumbo;
    }

    public static function getRowStyle($motionState) {


        switch ($motionState) {
            case MOTION_STATUS_TOW:
            case MOTION_STATUS_IGN_OFF_MOTION:
            case MOTION_STATUS_SENSOR_MOTION:
                $rowStyle = "redRow";
                break;

            case MOTION_STATUS_FAKE_TOW:
                $rowStyle = "grayRow";
                break;

            case MOTION_STATUS_IGN_OFF_REST:
                MOTION_STATUS_SENSOR_REST:
                $rowStyle = "whiteRow";
                break;

            case MOTION_STATUS_IGN_ON_MOTION:
                $rowStyle = "greenRow";
                break;

            case MOTION_STATUS_IGN_ON_REST:
                $rowStyle = "yellowRow";
                break;

            default:
                $rowStyle = "whiteRow";
                break;
        }
        return $rowStyle;
    }

    public static function getInStatus($inputMask, $in) {
        return (($inputMask && pow(2, $in - 1)) > 0) ? 1 : 0;
    }

    public static function getGeoRef($currentPosition) {
        return "";
    }

    public static function getCity($currentPosition) {
        return "";
    }

    public static function getFechaShortString($lapse) {
        $seconds = $lapse % 60;
        $minutes = $lapse % 3600;
        $hours = $lapse % 3600 * 24;
        $days = $lapse % 60 * 60 * 24 * 7;
    }

    public static function getFechaString($aTimeStamp) {



        $dif = abs(time() - $aTimeStamp);
        $string = $dif;


        if ($dif < 30) {
            $string = "algunos segundos";
        } elseif (($dif >= 30) and ($dif < 60)) {
            $string = "menos de un minuto ";
        } elseif (($dif >= 60) and ($dif < 60 * 5)) {
            $string = "menos de cinco minutos";
        } elseif (($dif >= 60 * 5) and ($dif < 60 * 10)) {
            $string = "menos de diez minutos";
        } elseif (($dif >= 60 * 10) and ($dif < 60 * 30)) {
            $string = "menos de media hora";
        } elseif (($dif > 60 * 30) and ($dif < 60 * 60)) {
            $string = "menos de una hora";
        } else {
            $string = "una hora o mas (" . floor($dif / 60) . " minutos) ";
        }

        return $string;
    }

    static function getReferenceText($lat, $lng) {

        $referenceText = "-";
        $referenceArray = GeoUtils::getReference($lat, $lng);
        try {
            if (is_array($referenceArray)) {
                $referenceText = $referenceArray['calle_1'];
                $referenceText .= (isset($referenceArray['calle_2'])) ? sprintf(" %s %s", "y", $referenceArray['calle_2']) : "";
                $referenceText .= (isset($referenceArray['city'])) ? sprintf(", %s", $referenceArray['city']) : "";
            }
        } catch (Exception $e) {
            $referenceText = "-";
        }
        return $referenceText;
    }

    static function getReference($lat, $lng) {

        $ref = array(null, null);
        $dao = new dbObject();

        $nodeQ = sprintf("SELECT node_id FROM ref_routing_nodes ORDER BY POW(lat-%s,2)+POW(lng-%s,2) LIMIT 0,1", $lat, $lng);
        
        /*
        $nodeQ = sprintf("SELECT node_id FROM (SELECT node_id,lat,lng FROM ref_routing_nodes 
                            WHERE lat >= %s-0.02 AND lat <=%s+0.02 
                            AND lng >= %s-0.02 AND lng <= %s+0.02) n
                            ORDER BY POW(lat-%s,2)+POW(lng-%s,2) LIMIT 0,1", $lat, $lat, $lng, $lng,$lat, $lng);
        */
        $res = $dao->fetchQuery($nodeQ);
        

        //echo $nodeQ;
        //echo "<pre>";
        //print_r($res);

        if (is_array($res) && count($res)) {
            $streetQ = sprintf("SELECT street_name, c.city_name FROM ref_street_nodes n 
				LEFT JOIN ref_streets s ON s.street_id = n.street_id 
				LEFT JOIN ref_cities c ON s.city_id = c.city_id
				WHERE n.node_id = %d LIMIT 0,2;", $res[0]['node_id']);
            $res = $dao->fetchQuery($streetQ);
            //echo "<pre>";
            //print_r($res);
            if (is_array($res)) {
                switch (count($res)) {
                    case 2:
                        $ref = array("calle_1" => $res[0]["street_name"], "calle_2" => $res[1]["street_name"], "city" => $res[0]['city_name']);
                        break;
                    case 1:
                        $ref = array("calle_1" => $res[0]["street_name"], "calle_2" => "S/D", "city" => $res[0]['city_name']);
                        break;
                }
            }
        }

        return $ref;
    }

    static function getTheDistance($lat2, $lng2, $lat, $lng) {

        if (($lat == $lat2) && ($lng == $lng2)) {
            $c = 0;
        } else {
            $latDist = $lat - $lat2;
            $lngDist = $lng - $lng2;
            $latDistRad = deg2rad($latDist);
            $lngDistRad = deg2rad($lngDist);
            $sinLatD = sin($latDistRad);
            $sinLngD = sin($lngDistRad);
            $cosLat1 = cos(deg2rad($lat));
            $cosLat2 = cos(deg2rad($lat2));
            $a = $sinLatD * $sinLatD + $cosLat1 * $cosLat2 * $sinLngD * $sinLngD * $sinLngD;
            if ($a < 0)
                $a = -1 * $a;
            $c = 2 * atan2(sqrt($a), sqrt(1 - $a));

            $a = (sin($latDistRad / 2) * sin($latDistRad / 2) + cos(deg2rad($lat2)) * cos(deg2rad($lat)) * sin($lngDistRad / 2) * sin($lngDistRad / 2));
            $c = (2 * atan2(sqrt($a), sqrt(1 - $a)));
        }
        return abs(EARTH_RADIUS * $c);
    }

    static function makeStatus($speed, $heading, $motionStatus) {
        $rumbo = GeoUtils::getRumbo($heading);
        if ($speed == 0) {
            $status = "Detenido";
        } else {
            $status = sprintf("Al %s a %s km/h", $rumbo, number_format($speed, 0));
        }
        return $status;
    }

}

?>