<?php
class Directory_PutController extends Library_Controller {
	public function __call($methodName, $args) {
		//priprava objektu
		$response = new Library_Response();
		$objectInfo = $this->_parseActionName($methodName);
		
		//nacteni informaci o pozadovanem adresari
		$tableDirectories = new Application_Model_DocumentsDirectories();
		
		/* @var $directory Application_Model_Row_Directory */
		$directory = $tableDirectories->find($objectInfo["id"])->current();

		if (!$directory) {
			//adresar nebyl nalezen
			$response->setStatus("DIRECTORY_NOT_FOUND", 404);
			$this->_sendToRender($response, $objectInfo["format"]);
			return;
		}
		
		//nacteni skupin
		$tableGroups = new Application_Model_UsersGroups();
		$groupList = $this->_user->findManyToManyRowset($tableGroups, "Application_Model_UsersHasManyUsersGroups", "user", "group");
		$groups = array();
		
		foreach ($groupList as $group) {
			$groups[] = $group->id;
		}
		
		//nacteni role
		$tableRoles = new Application_Model_UsersRoles();
		$role = $this->_user->findManyToManyRowset($tableRoles, "Application_Model_UsersHasManyUsersRoles", "user", "role", $tableRoles->select(false)->where("role_name like ?", "DOCUMENT_MANAGER"));
		
		//vyhodnoceni zmeny jmena
		if (isset($_REQUEST["directory"]["directory_name"])) {
			//pozadavek na zemnu jmena existuje
			
			//nacteni rodicovskeho adresare
			/* @var $parent Application_Model_Row_directory */
			$parent = $directory->findParentRow($tableDirectories, "parent");
			
			//kontorla opravneni menit jmeno
			if (!($this->_user->id == 1 || $role->count() || $parent->getPermisions($this->_user->id, $groups))) {
				//uzivatel nema opravneni zapisovat
				$response->setStatus("NO_PERMISION_TO_RENAME", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
			
			//validace jmena
			$name = $_REQUEST["directory"]["directory_name"];
			$name = trim($name);
			
			if (empty($name)) {
				//jmeno je prazdne
				$response->setStatus("NAME_IS_EMPTY", 400);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
			
			//zapsani noveho jmena
			$directory->directory_name = $name;
		}
		
		//vyhodnoceni zmeny skupiny
		if (isset($_REQUEST["directory"]["group_id"])) {
			//pozadavek na zmenu skupiny existuje
			
			//kontorla opravneni
			if (!($this->_user->id == 1 || $directory->user_id == $this->_user->id || $role->count())) {
				//uzivatel nema opravneni menit skupinu
				$response->setStatus("NO_PERMISION_TO_CHANGE_GROUP", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
			
			//kontrola jeslti ej uzivatel ve skupine, pokud je to treba
			if ($this->_user->id == $directory->user_id && $this->_user->id != 1 || !$role->count()) {
				//uzivatel je majitelem adredare, ale neni root ani nema roli, musi se zkontrolovat prirazeni ke skupine
				if (!in_array($_REQUEST["directory"]["group_id"], $groups) && $_REQUEST["directory"]["group_id"] != "0") {
					//uzivatelo neni ve skupine
					$response->setStatus("IVALID_GROUP", 400);
					$this->_sendToRender($response, $objectInfo["format"]);
					return;
				}
			}
			
			//zapis skupiny
			$directory->group_id = $_REQUEST["directory"]["group_id"];
		}
		
		//vyhodnoceni zmeny majitele
		if (isset($_REQUEST["directory"]["user_id"])) {
			//pozadavek na zmenu majitele existuje, zkontroluje se, jeslti ma uzivatel roli nebo je root
			if (!($role->count() || $this->_user->id == 1)) {
				$response->setStatus("NO_PERMISION_TO_CHANGE_OWNER", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
			
			//zmena uzivatele
			$directory->user_id = $_REQUEST["directory"]["user_id"];
		}
		
		//vyhdnoceni zapisovatelnosti do adresare
		$writeAble = $this->_user->id == 1 || $role->count() || $directory->getPermisions($this->_user->id, $groups);
		
		//vyhodnoceni jestli se maji updatovat dokumenty v adresri
		if (isset($_REQUEST["directory"]["document"])) {
			//kontorla opravneni zapisovat do adresare
			if (!$writeAble) {
				$response->setStatus("NO_WRITE_PERMISIONS", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
			
			//kontorla konfliktu mezi jmeny
			$nameList = array();
			$unnameList = array();
			
			foreach ($_REQUEST["directory"]["document"] as $uuid => $info) {
				//kontorla jestli se nejedna o odpad
				if (!isset($info["write"], $info["document_name"])) {
					//jedna se o nezadouci odpad
					continue;
				}
				
				//kontrola jesti ma dojit k zapisu
				if ($info["write"]) {
					//k zapisu ma dojit, vyhodnoti se nastaveni jmena
					if (empty($info["document_name"])) {
						//pouzije se hlavni jmeno dokumentu
						$unnameList[] = $uuid;
					} else {
						//kontrola jestli je jmeno v seznamu
						if (in_array($info["document_name"], $nameList)) {
							$response->setStatus("DOCUMENT_NAME_EXISTS", 409);
							$this->_sendToRender($response, $objectInfo["format"]);
							return;
						}
						
						$nameList[] = $info["document_name"];
					}
				}
			}
			
			//pokud je to treba, dojde k vyhodnoceni dokumentu s implicitnim jmenem
			if ($unnameList) {
				//vytvoreni selectu
				$tableDocuments = new Application_Model_Documents();
				
				$select = $tableDocuments->select(false)->where("uuid in (?)", $unnameList);
				$documents = $tableDocuments->fetchAll($select);
				
				foreach ($documents as $document) {
					if (in_array($document->document_name, $nameList)) {
						$response->setStatus("DOCUMENT_NAME_EXISTS", 409);
						$this->_sendToRender($response, $objectInfo["format"]);
						return;
					}
					
					$nameList[] = $document["document_name"];
				}
			}
			
			//odebrani starych asociaci k souborum
			$tableDirectoriesDocuments = new Application_Model_DocumentsDirectoriesHasManyDocuments();
			$tableDirectoriesDocuments->delete("document_directory_id = " . $directory->id);
			
			//zapsani novych asociaci
			$data = array(
				"document_uuid" => "",
				"document_name" => "",
				"document_directory_id" => $directory->id
			);
			
			foreach ($_REQUEST["directory"]["document"] as $uuid => $info) {
				//kontorla jestli se nejedna o odpad
				if (!isset($info["write"], $info["document_name"])) {
					//jedna se o nezadouci odpad
					continue;
				}
				
				//kontrola jesti ma dojit k zapisu
				if ($info["write"]) {
					//k zapisu ma dojit
					$info["document_name"] = trim($info["document_name"]);
					
					//nastaveni dat
					$data["document_uuid"] = $uuid;
					$data["document_name"] = empty($info["document_name"]) ? new Zend_Db_Expr("NULL") : $info["document_name"];
					
					//zapsani dat
					$tableDirectoriesDocuments->insert($data);
				}
			}
		}
		
		//odeslani odpovedi
		$directory->save();
		
		$response->setOk();
		$response["directory"] = $directory;
		$this->_sendToRender($response, $objectInfo["format"]);
	}
	
	protected function _sendToRender(Library_Response $response, $format) {
		//zapsani do view
		$this->view->response = $response;
		$response->sendHeader();
		
		if ($format != "html") {
			$this->_helper->layout()->disableLayout();
		}
		
		//vyhodnoceni formatu
		switch ($format) {
			case "html":
				$this->_helper->viewRenderer("put-html");
				break;
			
			case "json":
			
			default:
				$this->_helper->viewRenderer("put-json");
		}
	}
}