<?php

class JsonController extends Controller
{

	/**
	 * Точки
	 */
	static function actionPoints()
	{
		if (App::$user && App::$user->isAdmin == 1) {
			$points = Point::model()->getAll();
		} else {
			$minEditDate = isset($_GET['time']) ? (int) $_GET['time'] : 0;
			if (!isset($_GET['bounds']) || !isset($_GET['bounds'][0]) || !isset($_GET['bounds'][1]) || !isset($_GET['bounds'][2]) || !isset($_GET['bounds'][3])) {
				$points = Point::model()->getAllPublished(false, $minEditDate);
			} else {
				$_GET['bounds'][0] = floatval($_GET['bounds'][0]);
				$_GET['bounds'][1] = floatval($_GET['bounds'][1]);
				$_GET['bounds'][2] = floatval($_GET['bounds'][2]);
				$_GET['bounds'][3] = floatval($_GET['bounds'][3]);

				$points = Point::model()->getAllPublished($_GET['bounds'], $minEditDate);
			}
		}

		$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));

		$result = array();

		foreach ($points as $point) {
			$tempPoint['id'] = $point->id;
			$tempPoint['name'] = $point->name;
			$tempPoint['lat'] = $point->lat;
			$tempPoint['lng'] = $point->lng;
			$tempPoint['categoryId'] = $point->categoryId;
			$tempPoint['moderate'] = $point->moderate ? 'show' : 'hide';

			$result[] = $tempPoint;
		}

		self::renderPartial('json.php', array(
			'data' => $result,
		));
	}

	/**
	 * Точка
	 */
	static function actionPoint()
	{
		$id = (int) App::getParam('id');
		if ($id) {
			$point = Point::model()->getByPK($id);

			$point->descriptionHtml = nl2br($point->description);
			$point->descriptionHtml = Helper::replaceLinks($point->descriptionHtml, 'js');
			$point->name = htmlspecialchars($point->name);
			$point->moderate = $point->moderate ? 'show' : 'hide';
			$imgs = $point->photos;
			$photosCount = 1;

			if ($point->img == '' && !empty($imgs)) {
				$img = array_shift($imgs);
				$point->img = $img->name;
			}

			$imgs = $point->photos;
			if (!empty($imgs)) {
				$tmp = array();
				$photosCount = count($imgs);
				foreach ($imgs as $img) {
					$tmp[] = $img->name;
				}
				$point->images = $tmp;
			}

			$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));

			$point->categoryIcon = $categories[$point->categoryId]['icon'];
			$point->categoryName = $categories[$point->categoryId]['name'];
			$point->photosCount = $photosCount;
			$point->inFavorites = Favorite::model()->checkIsMy($id);
			$point->iLike = Like::model()->checkIsMy($id);

			self::renderPartial('json.php', $point->getValues());
		} else {
			App::error404();
		}
	}

	/**
	 * Категории
	 */
	static function actionCategories()
	{
		$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true, 'noKeys' => true));

		self::renderPartial('json.php', array(
			'data' => $categories,
		));
	}

	/**
	 * Добавление точки
	 */
	static function actionAddPoint()
	{
		$errors = array();

		if (!App::$user) {
			$errors[8] = 'Вы не авторизованы! Пожалуйста, войдите.';
		}

		if (isset($_POST['id']) && $_POST['id'] && App::$user->isAdmin == 0) {
			$point = new Point();
			$id = (int) $_POST['id'];
			$point = $point->getByPK($id);

			if ($point->author != App::$user->id || $point->moderate == 1) {
				$errors[9] = 'Редактирование точек достурно только администратору или автору!';
			}
		}

		$photos = $images = array();
		if (empty($errors) && !App::$request['ajax'] && isset($_POST['id']) && (int) $_POST['id']) {
			$id = (int) $_POST['id'];
			$pathInfo = pathinfo($_SERVER['SCRIPT_FILENAME']);
			$uploaddir = $pathInfo['dirname'] . '/photos/';

			if (isset($_FILES) && !empty($_FILES)) {
				foreach ($_FILES['photos']['name'] as $key => $fileName) {
					$temp = pathinfo($_FILES['photos']['name'][$key]);
					$extension = strtolower($temp['extension']) ? strtolower($temp['extension']) : 'jpg';
					$photo = $id . strtolower('_' . substr(md5($fileName . time()), 0, 5) . '.' . $extension);
					if (move_uploaded_file($_FILES['photos']['tmp_name'][$key], $uploaddir . $photo)) {
						$photos[] = $photo;
					}
				}
			}

			if (isset($_POST['imgs']) && !empty($_POST['imgs'])) {
				foreach ($_POST['imgs'] as $key => $img) {
					if (mb_strpos($img, '://') !== false) {
						$temp = pathinfo($img);
						$extension = strtolower($temp['extension']) ? strtolower($temp['extension']) : 'jpg';
						$photo = $id . strtolower('_' . substr(md5($img . time()), 0, 5) . '.' . $extension);

						if (file_put_contents($uploaddir . $photo, file_get_contents($img))) {
							PhotoLinks::addLink($photo, $img);
							$images[] = $photo;
						}
					} else {
						$images[] = $img;
					}
				}
			}

			$resPhotos = array();
			$ordering = $_POST['ordering'];
			foreach ($ordering as $order) {
				$resPhotos[] = $order == 'FILE' ? array_shift($photos) : array_shift($images);
			}

			if (!empty($resPhotos)) {
				App::DB()->query('DELETE FROM `poi`.`photos` WHERE `pointId` = ' . $id . ';');

				$P = new Photo();
				foreach ($resPhotos as $key => $photo) {
					$P->add(array(
						'pointId' => $id,
						'name' => $photo,
						'ord' => $key,
					));
					Image::createAllSizes($photo);
					if ($ordering[$key] == 'FILE') {
						PhotoLinks::addLink($photo, $_POST['photoLinks'][$key]);
					}
				}

				$point = Point::model()->getByPK($id);
				$point->img = '';
				$point->save();
			}

			App::redirect('/?point=' . $id);
		}

		if (isset($_POST['name'])) {
			$_POST['name'] = strip_tags($_POST['name']);
		}

		if (isset($_POST['description'])) {
			$_POST['description'] = strip_tags($_POST['description']);
		}

		if (!( isset($_POST['name']) && $_POST['name'] && strlen($_POST['name']) > 1 ))
			$errors[1] = 'Неверное название точки';
		if (!( isset($_POST['img']) && (int) $_POST['img']))
			$errors[2] = 'Плохая ссылка на изображение';
		if (!( isset($_POST['description']) && $_POST['description'] && strlen($_POST['description']) > 25 ))
			$errors[3] = 'Слишком короткое описание';
		if (!( isset($_POST['categoryId']) && $_POST['categoryId'] ))
			$errors[4] = 'Не задана категория точки';
		if (!( isset($_POST['source']) ))
			$errors[5] = 'Не передано поле источкика информации. Допускается пустое значение.';
		if (!( isset($_POST['lat']) && $_POST['lat'] ))
			$errors[6] = 'Ошибочное значение широты';
		if (!( isset($_POST['lng']) && $_POST['lng'] ))
			$errors[7] = 'Ошибочное значение долготы';

		if (!empty($errors)) {
			header("HTTP/1.0 400 Bad Request");
			header('Content-Type: application/json');
			print json_encode($errors);
			return false;
		}

		if (App::$request['ajax']) {
			$point = new Point();
			unset($_POST['img']);

			if (isset($_POST['id']) && $_POST['id']) {
				// Редактирование существующей точки
				$id = (int) $_POST['id'];
				$_POST['dateEdit'] = time();

				$point = $point->getByPK($id);
				$point->setValues($_POST);
				$point->save();
			} else {
				$_POST['author'] = App::$user->id;
				$_POST['date'] = time();
				$_POST['dateEdit'] = time();
				$_POST['moderate'] = (App::$user && App::$user->isAdmin == 1) ? $_POST['moderate'] : 0;
				$point->add($_POST);

				if (!$point->id) {
					header("HTTP/1.0 500 Internal Server Error");
					die('Error 500 - Internal Server Error');
				}

				if (!App::getConfig('disableSMS')) {
					$ch = curl_init("http://sms.ru/sms/send");
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
					curl_setopt($ch, CURLOPT_TIMEOUT, 10);
					curl_setopt($ch, CURLOPT_POSTFIELDS, array(
						"api_id" => "2c2af6a7-a935-0e84-5952-599f5cd61905",
						"to" => "79046106141, 79046106144",
						"text" => "#" . $point->id . ": " . $point->name,
						"from" => "WIKIPOINTS",
					));
					curl_exec($ch);
					curl_close($ch);
				}
			}

			self::renderPartial('json.php', array(
				'data' => $point->id
			));
		}
	}

	static function actionSaveRoute()
	{
		if (!(isset($_POST['name']) && $_POST['name'] && isset($_POST['points']) && $_POST['points'])) {
			App::error404('Неправильное значение!');
		}

		$request = array(
			'author' => App::$user->id,
			'date' => time(),
			'name' => $_POST['name'],
			'points' => json_encode($_POST['points']),
		);

		$route = Route::model()->add($request);

		self::renderPartial('json.php', $route->id);
	}

	static function actionRoute()
	{
		$id = (int) App::getParam('id');
		if ($id) {
			$route = Route::model()->getByPK($id);
			self::renderPartial('json.php', $route->points);
		} else {
			App::error404();
		}
	}

	static function actionDeleteRoute()
	{
		$id = (int) App::getParam('id');
		if ($id && App::$user) {
			$route = Route::model()->getByPK($id);

			if ($route->author == App::$user->id) {
				$route->delete($id);
			}

			self::renderPartial('json.php', true);
		} else {
			App::error404();
		}
	}

	static function actionGeoCoding()
	{
		$address = isset($_GET['search']) ? $_GET['search'] : '';

		$res = @file_get_contents('http://geocode-maps.yandex.ru/1.x/?format=json&geocode=' . urlencode($address));
		$res = json_decode($res, true);

		if (isset($res['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos']))
			$point = explode(' ', $res['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos']);
		else
			$point = array(0, 0);

		$coords = array();
		$coords['lat'] = $point[1];
		$coords['lng'] = $point[0];

		self::renderPartial('json.php', $coords);
	}

	static function actionAddRemoveFavorites()
	{
		$id = (int) App::getParam('id');
		if (!$id || !App::$user) {
			App::error404();
		}
		self::renderPartial('json.php', Helper::boolval(Favorite::addRemove($id)));
	}

	static function actionAddRemoveLike()
	{
		$id = (int) App::getParam('id');
		if (!$id || !App::$user) {
			App::error404();
		}
		self::renderPartial('json.php', Helper::boolval(Like::addRemove($id)));
	}

	static function actionSearch()
	{
		$search = isset($_GET['query']) ? $_GET['query'] : '';

		$results = array();
		if ($search) {
			App::log('searchQueries', $search);
			// ====== POINTS ============
			$points = Point::model()->searchByString($search);
			if (!empty($points)) {
				foreach ($points as $point) {
					$results[] = array('value' => $point->name, 'data' => '/?point=' . $point->id);
				}
			}

			if (count($results) < 10 && strlen($search) > 5) {
				// ====== YANDEX ============
				$ch = curl_init();
				curl_setopt($ch, CURLOPT_URL, 'https://geocode-maps.yandex.ru/1.x/?geocode=' . urlencode($search));
				curl_setopt($ch, CURLOPT_TIMEOUT, 3);
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
				$out = null;
				$out = curl_exec($ch);

				if (!empty($out)) {
					$obj = simplexml_load_string($out);

					if (isset($obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found)) {
						$count = (int) $obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found;
						if ($count > 0) {
							for ($index = 0; $index < $count && $index < 5 && count($results) < 25; $index++) {
								$name = (string) $obj->GeoObjectCollection->featureMember[$index]->GeoObject->name;
								$coords = explode(' ', (string) $obj->GeoObjectCollection->featureMember[$index]->GeoObject->Point->pos);
								$lat = $coords[1];
								$lng = $coords[0];
								$results[] = array('value' => $name, 'data' => "/?lat=$lat&lng=$lng&zoom=13");
							}
						} else if (isset($obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->Point)) {
							$coords = explode(' ', (string) $obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->Point->pos);
							$lat = $coords[1];
							$lng = $coords[0];
							$name = "Координаты N°" . $lat . ' E°' . $lng;
							$results[] = array('value' => $name, 'data' => "/?lat=$lat&lng=$lng&zoom=13");
						}
					}
				}
				curl_close($ch);
			}

			if (count($results) < 10 && strlen($search) > 5) {
				// ====== GOOGLE ============
				$ch = curl_init();
				curl_setopt($ch, CURLOPT_URL, 'https://maps.googleapis.com/maps/api/geocode/json?language=ru&key=AIzaSyDuWmguxO35oV9WGc6D8xUPvQBaUS4kt78&address=' . urlencode($search));
				curl_setopt($ch, CURLOPT_TIMEOUT, 3);
				curl_setopt($ch, CURLOPT_REFERER, "http://wikipoints.ru");
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
				$out = null;
				$out = curl_exec($ch);

				if (!empty($out)) {
					$obj = json_decode($out);
					if ((string) $obj->status == 'OK') {
						$count = count($obj->results);
						if ($count > 0) {
							for ($index = 0; $index < $count && $index < 5 && count($results) < 25; $index++) {
								$name = (string) $obj->results[$index]->formatted_address;
								$lat = (string) $obj->results[$index]->geometry->location->lat;
								$lng = (string) $obj->results[$index]->geometry->location->lng;
								$results[] = array('value' => $name, 'data' => "/?lat=$lat&lng=$lng&zoom=13");
							}
						}
					}
				}
				curl_close($ch);
			}
		}

		self::renderPartial('json.php', array('query' => $search, 'suggestions' => $results));
	}

	/**
	 * Article / K.O. =)
	 */
	static function actionArticle()
	{
		$id = (int) App::getParam('id');
		if ($id) {
			$article = Article::model()->getByPK($id);

			if (!$article) {
				die;
			}
			self::renderPartial('modals/article.php', array(
				'title' => $article->title,
				'text' => $article->html,
			));
		}
	}

	static function actionPointagreement()
	{
		$article = Article::model()->getByPK(4);

		if (!$article) {
			die;
		}
		self::renderPartial('modals/pointAgreement.php', array(
			'title' => $article->title,
			'text' => $article->html,
		));
	}

	static function actionGetmyartphotos()
	{
		if (!App::$user) {
			App::error404();
		}

		self::renderPartial('json.php', array(
			'data' => ArticlePhotos::model()->getAll(
					array(
						'where' => '`owner` = ' . (int) App::$user->id,
						'order' => '`id` DESC',
						'asArray' => true,
						'noKeys' => true
					)
			)
		));
	}

}
