<?php

class Point extends Model
{

	function __construct($fromArray = array())
	{
		$this->_tableName_ = 'points';
		parent::__construct($fromArray);
		$this->setRelation('category', 'categoryId', 'Category', 'id', self::TO_ONE);
		$this->setRelation('authorUser', 'author', 'User', 'id', self::TO_ONE);
		$this->setRelation('photos', 'id', 'Photo', 'pointId', self::TO_MANY);
	}

	static function model()
	{
		return new self();
	}

	public function getImg($size = 'small')
	{
		$img = $this->img;
		if ($img == '') {
			$photos = $this->photos;
			$img = array_shift($photos);

			if (!$img)
				return null;

			$img = '/photos/' . $size . '/' . $img->name;
		}

		return $img;
	}

	public function getRandom()
	{
		$res = App::DB()->query("SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `" . $this->_tableName_ . "`")->fetch(PDO::FETCH_ASSOC);
		$offset = $res['offset'];

		$res = App::DB()->query('SELECT `id` FROM ' . $this->_tableName_ . ' LIMIT ' . $offset . ',1;')->fetch(PDO::FETCH_ASSOC);
		$pointId = $res['id'];

		return $this->getByPK($pointId);
	}

	public function getClosestPoints($pointId)
	{
		$point = Point::model()->getByPK($pointId);
		$lat = floatval($point->lat);
		$lng = floatval($point->lng);

		$query = '
			SELECT *, (
			SQRT(POW(`lat`-:lat,2)+POW(`lng`-:lng,2))
			) AS `dist` FROM `' . $this->_tableName_ . '`
			WHERE
			`moderate` = 1
			AND
			`lat` BETWEEN :minLat AND :maxLat
			AND
			`lng` BETWEEN :minLng AND :maxLng
			AND
			`lat` <> :lat
			AND
			`lng` <> :lng
			ORDER BY `dist`
			LIMIT 6;';

		$res = App::DB()->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
		$res->execute(array(':lat' => $lat, ':lng' => $lng, ':minLat' => $lat - 1, ':minLng' => $lng - 1, ':maxLat' => $lat + 1, ':maxLng' => $lng + 1));

		$ready = array();
		$calledClass = get_called_class();
		while ($res && $row = $res->fetch(PDO::FETCH_ASSOC)) {
			$ready[] = new $calledClass($row);
		}

		return $ready;
	}

	public function getCountByUser($userId)
	{
		$res = App::DB()->query('SELECT count(`id`) AS `cnt` FROM ' . $this->_tableName_ . ' WHERE `author` = ' . $userId . ' ;')->fetch(PDO::FETCH_ASSOC);
		return $res['cnt'];
	}

	public function searchByString($search)
	{
		return $this->getAll(array('where' => "`name` LIKE '%$search%' OR `description` LIKE '%$search%'", 'limit' => 20));
	}

	public function getAllPublished($bounds = false, $minEditDate = 0)
	{
		$userId = App::$user ? App::$user->id : 0;
		$minEditDate = intval($minEditDate);
		if ($bounds) {
			$b0 = $bounds[0] < $bounds[2] ? $bounds[0] : $bounds[2];
			$b2 = $bounds[0] < $bounds[2] ? $bounds[2] : $bounds[0];
			$b1 = $bounds[1] < $bounds[3] ? $bounds[1] : $bounds[3];
			$b3 = $bounds[1] < $bounds[3] ? $bounds[3] : $bounds[1];

			return $this->getAll(array('where' => "(`moderate` = 1 OR `author` = $userId) AND (`dateEdit` >= $minEditDate) AND (`lat` BETWEEN '$b0' AND '$b2') AND(`lng` BETWEEN '$b1' AND '$b3')"));
		} else {
			return $this->getAll(array('where' => "(`moderate` = 1 OR `author` = " . $userId . ") AND (`dateEdit` >= $minEditDate)"));
		}
	}

}
