<?php
class Document_PutController extends Library_Controller {
	public function __call($methodName, $args) {
		//inicializace objektu
		$objectInfo = $this->_parseActionName($methodName);
		$response = new Library_Response();

		//nacteni dokumentu
		$tableDocuments = new Application_Model_Documents();

		//kontrola jeslti se dokument nacita pomoci zkratky
		if (strlen($objectInfo["id"]) == 7) {
			$tableShortcuts = new Application_Model_DocumentsShortcuts();

			$shortcut = $tableShortcuts->fetchRow($tableShortcuts->select(false)
			->where("shortcut like ?", $_REQUEST["shortcut"]));

			if ($shortcut) {
				$document = $shortcut->findParentRow("Application_Model_Documents", "document", $select);
			} else {
				$document = false;
			}
		} else {
			$document = $tableDocuments->find($objectInfo["id"])->current();
		}

		if (!$document) {
			$response->setStatus("DOCUMENT_NOT_FOUND", 404);
			$this->_sendToRender($response, $objectInfo["format"]);
			return;
		}

		//nacteni opravneni
		$user = $this->_user;

		$groupList = $user->findDependentRowset("Application_Model_UsersHasManyUsersGroups", "user");
		$groups = array();

		foreach ($groupList as $group) {
			$groups[] = $group->user_group_id;
		}

		$permisions = $document->getPermisions($user->id, $groups);
		
		//nactnei role
		$tableRoles = new Application_Model_UsersRoles();
		$role = $user->findManyToManyRowset($tableRoles, "Application_Model_UsersHasManyUsersRoles", "user", "role", $tableRoles->select(false)->where("role_name like ?", "DOCUMENT_MANAGER"));

		//update obecnych dat
		$changed = false;

		if (isset($_REQUEST["document"]["document_name"])) {
			$changed = true;

			if (!($permisions->write || $user == 1 || $role->count())) {
				$response->setStatus("NO_PERMISIONS_TO_RENAME", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}

			$document->document_name = $_REQUEST["document"]["document_name"];
		}

		//kontrola zmeny masky opravneni
		if (isset($_REQUEST["document"]["mask"])) {
			$changed = true;

			if (!($document->user_id == $user->id || $user->id == 1 || $role->count())) {
				$response->setStatus("NO_PERMISIONS_TO_CHANGE_MASK", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}

			//kontorla validity masky
			$pattern = "^([r-]{1}[w-]{1}[x-]{1}){3}$";

			if (!ereg($pattern, $_REQUEST["document"]["mask"])) {
				$response->setStatus("INVALID_MASK", 400);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}

			$document->mask = $_REQUEST["document"]["mask"];
		}
		
		//kontorla pozadavku na zmenu mime typu
		if (isset($_REQUEST["document"]["mime_type"])) {
			//pozadavek na zmenu mime typu byl odeslan
			if (!($permisions->write || $user == 1 || $role->count())) {
				//uzivatel neni opravnen menit mime typ
				$response->setStatus("NO_PERMISIONS_TO_CHANGE_MIMETYPE", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
			
			$document->mime_type = $_REQUEST["document"]["mime_type"];
		}

		//kontrola jeslti byl odeslan obsah v souboru
		if (is_uploaded_file(@$_FILES["document"]["tmp_name"]["content"])) {
			$_REQUEST["document"]["content"] = file_get_contents($_FILES["document"]["tmp_name"]["content"]);
			$_REQUEST["document"]["mime_type"] = $_FILES["document"]["type"]["content"];
		}
		
		//kontorla zmeny v obsahu souboru
		if (isset($_REQUEST["document"]["content"])) {
			if (!($permisions->write || $user == 1 || $role->count())) {
				$response->setStatus("NO_PERMISIONS_TO_CREATE_REVISION", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
			
			//kontrola mime typu
			if (isset($_REQUEST["document"]["mime_type"])) {
				$document->mime_type = $_REQUEST["document"]["mime_type"];
			}

			//konotrla SHA-1 souctu puvodniho a noveho souboru
			$shaNew = sha1($_REQUEST["document"]["content"]);
			$shaOld = sha1_file(CONTENT_PATH . "/" . $document->uuid);
			
			//ulozeni dokumentu pro ziskani UUID neaktualniho obsahu a nastaveni stavu $changed na FALSE
			$oldUuid = $document->save();
			$changed = false;
			
			//konotrla jestli kontrolni soucty souhlasi
			if ($shaNew == $shaOld) {
				//kontrolni soucty souhlasi, vytvori se pouze symlink
				$this->_manageSymlinks($document->uuid, $oldUuid);
			} else {
				//vygenerovani cest
				$actualPath = CONTENT_PATH . "/" . $document->uuid;
				$oldPath = CONTENT_PATH . "/" . $oldUuid;

				//prejmenovani souboru
				rename($actualPath, $oldPath);
				
				//zapis dat do sobuoru
				file_put_contents($actualPath, $_REQUEST["document"]["content"]);
			}
		}

		//provedeni zmen
		if ($changed) {
			$oldUuid = $document->save();
			
			$this->_manageSymlinks($document->uuid, $oldUuid);
		}
	
		$response->setOk();
		$response["document"] = $document;
		
		$this->_sendToRender($response, $objectInfo["format"]);
	}
	
	/**
	 * vytvori symlink mezi starym a novym obsahem
	 * pokud je stary obsah take symlink, vytvori se link na puvodni soubor
	 * 
	 * @param string $actualUuid UUID aktualniho obsahu
	 * @param string $oldUuid UUID prepsaneho obsahu
	 */
	protected function _manageSymlinks($actualUuid, $oldUuid) {
		//sestveni celych cest
		$actualPath = CONTENT_PATH . "/" . $actualUuid;
		$oldPath = CONTENT_PATH . "/" . $oldUuid; 
		
		//prejmenovani aktualniho obsahu na stary
		rename($actualPath, $oldPath);
		
		//kontorla jestli stary obsah byl symlink
		if (is_link($oldPath)) {
			//stary obsah byl symlink, novy obsah se nalinkuje na stary soubor
			symlink(readlink($oldPath), $actualPath);
		} else {
			symlink($oldPath, $actualPath);
		}
	}
	
	/**
	 * zkontroluje, jestli je fyzicky TS novejsi nez virtualni
	 * @param string $physicTimestamp TS stazeni projektu
	 * @param string $virtualTimestamp TS posledni zmeny mistniho dokumentu
	 */
	protected function _checkTimestamp($physicTimestamp, $virtualTimestamp) {
		$format = Zend_Date::YEAR . "-" . Zend_Date::MONTH . "-" . Zend_Date::DAY . " " . Zend_Date::HOUR . ":" . Zend_Date::DAY . ":" . Zend_Date::SECOND;
		
		$localTS = new Zend_Date($virtualTimestamp, $format);
		$physicTS = new Zend_Date($virtualTimestamp, $format);
		
		return $localTS->compare($physicTS);
	}

	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");
		}
	}
}