<?php

class DocumentationCtrl extends Ctrl {



	public function index($doc = 1, $pageId = 1, $versionId = null) {
		$v = new View();
		$v->add($this->getTableOfContents($doc));
		$v->add($this->getPage($pageId, $versionId));
		$index = new Index();
		$index->add($v);
		return $index;
	}



	public function getTableOfContents($doc = 1) {
		$loggedIn = AuthService::getCurrentUserId();
		$toc = new Tree('toc');
		$dp = new DocumentationPage();
		$chapters = $dp->loadBySQLCondition("doc_id = '$doc' AND parent_id IS NULL AND is_del = 0");
		foreach ($chapters as $chapter) {
			$ch = &new TreeNode('documentation_node_' . $chapter->id);
			$ch->text = $chapter->title;
			$ch->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/getPage', $chapter->id)));
			if ($loggedIn) {
				$ch->addListener(new DropOntoListener('toc-change-chapter', new Action('/doc/DocumentationCtrl/changeChapter', $chapter->id)));
			}
			$toc->add($ch);
			foreach ($chapter->documents as $document) {
				if ($document->is_del) {
					continue;
				}
				$d = &new TreeNode('documentation_node_' . $document->id);
				$d->class = 'TreeNode document';
				$d->text = $document->title;
				$d->icon = 'var/img/document.png';
				$d->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/getPage', $document->id)));
				if ($loggedIn) {
					$d->addListener(new DragStartListener('toc-change-chapter', new Action('/doc/DocumentationCtrl/changeChapter', $document->id)));
				}
				$ch->add($d);
			}
		}
		return $toc;
	}



	public function hideTableOfContents() {
		$this->response->eval("document.getElementById('toc').style.display = 'none';");
	}



	public function showTableOfContents() {
		$this->response->eval("document.getElementById('toc').style.display = 'block';");
	}



	public function getPage($pageId, $versionId = null) {
		$this->showTableOfContents();
		$page = new View('documentation_page');
		$page->template = 'doc/page.tpl';
		$page->loggedIn = AuthService::getCurrentUserId();
		$page->title = 'untitled';
		if (!$pageId) {
			return $page;
		}
		// loading basic data
		$d = new DocumentationPage();
		$d->loadById($pageId);
		$v = $d->getVersion($versionId);
		$wt = new WikiTranslator();
		$page->title = $d->title;
		$page->content = $wt->mtov($v->content);
		$page->permalink = "?action=/doc/DocumentationCtrl/index&args[]={$d->doc_id}&args[]=$pageId&args[]=$versionId";
		// edit button
		$page->add($edit = new Button(), 'edit');
		$edit->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/editPage', $pageId)));
		$edit->text = 'Edit';
		// add/delete buttons
		if ($d->parent_id) {
			$page->add($delete = new Button(), 'delete');
			$deleteAction = new Action('/doc/DocumentationCtrl/deletePage', $pageId);
			$delete->addListener(new ClickListener(new Behaviour("if (confirm('Do you really want to delete this page?')) $deleteAction")));
			$delete->text = 'Delete';
		} else {
			$page->add($add = new Button(), 'add');
			$add->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/addPage', $pageId)));
			$add->text = 'New page';
		}
		// versions list
		$options = array();
		foreach ($d->versions as $version) {
			$options[$version->id] = '#' . $version->id . ' - ' . $version->changes;
		}
		if (!empty($options)) {
			krsort($options);
			$versions = new Select('documentation_page-versions');
			$versions->value = $pageId;
			$versions->options = $options;
			$versions->addListener(new ChangeListener(new Action('/doc/DocumentationCtrl/getPage', array($pageId, $versions->valueReader()))));
			if ($versionId) {
				$versions->value = $versionId;
			}
			$page->versions = $versions;
			$cv = $d->getVersion();
			$page->edited = date('d-m-Y h:i', $cv->created);
			$page->author = $cv->user_id;
		}
		$page->comments = $this->getComments($pageId);
		return $page;
	}



	public function addPage($parentId) {
		if (!($userId = AuthService::getCurrentUserId())) {
			$this->response->alert('You need to be logged in to add pages.');
			return;
		}
		$parentPage = new DocumentationPage();
		$parentPage->loadById($parentId);
		$d = new DocumentationPage();
		$d->title = '';
		$d->content = '';
		$d->parent_id = $parentId;
		$d->doc_id = $parentPage->doc_id;
		$d->user_id = $userId;
		$d->save();
		return $this->editPage($d->getPrimaryKeyValue());
	}



	public function editPage($pageId) {
		if (!($userId = AuthService::getCurrentUserId())) {
			$this->response->alert('You need to be logged in to edit.');
			return;
		}
		$page = new Form('documentation_page');
		$page->template = 'doc/pageForm.tpl';
		$page->add($title = new Input('documentation_page-title'), 'title');
		$page->add($content = new TextArea('documentation_page-content'), 'content');
		$page->add($changes = new Input('documentation_page-changes'), 'changes');
		$page->add($ok = new Button(), 'ok');
		$ok->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/savePage', array($pageId, $page->valueReader()))));
		$ok->text = 'Save';
		$page->add($cancel = new Button(), 'cancel');
		$cancel->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/getPage', $pageId)));
		$cancel->text = 'Cancel';
		$d = new DocumentationPage();
		$d->loadById($pageId);
		$v = $d->getVersion();
		$title->value = $d->title;
		$content->value = $v->content;
		$page->add($this->getPagePreview($content->value), 'preview');
		$a = new Action('/doc/DocumentationCtrl/getPagePreview', $content->valueReader());
		$content->addListener(new StopTypingListener(new Behaviour("if ({$content->valueReader()} != '') $a;"), 5000));
		$this->hideTableOfContents();
		return $page;
	}



	public function getPagePreview($content) {
		$preview = new View('documentation_page-preview');
		$wt = new WikiTranslator();
		$preview->addText($wt->mtov($content) . '&nbsp;');
		return $preview;
	}



	public function savePage($pageId, FormContext $cx) {
		if (!($userId = AuthService::getCurrentUserId())) {
			$this->response->alert('You need to be logged in to edit.');
			return;
		}
		StopTypingListener::cease();
		$d = new DocumentationPage();
		$d->loadById($pageId);
		$d->title = $cx->title;
		$d->user_id = $userId;
		$v = $d->getNewVersion();
		$v->user_id = $userId;
		$v->content = $cx->content;
		$v->changes = $cx->changes;
		$v->save();
		$d->save();
		$toc = $this->getTableOfContents($d->doc_id);
		$toc->update();
		return $this->getPage($pageId);
	}



	public function deletePage($pageId) {
		if (!($userId = AuthService::getCurrentUserId())) {
			$this->response->alert('You need to be logged in to delete.');
			return;
		}
		$d = new DocumentationPage();
		$d->loadById($pageId);
		$d->user_id = $userId;
		$d->is_del = 1;
		$d->save();
		$toc = $this->getTableOfContents($d->doc_id);
		$toc->update();
		return $this->getPage($d->parent_id);
	}



	public function changeChapter($to, $pageId) {
		if (!($userId = AuthService::getCurrentUserId())) {
			$this->response->alert('You need to be logged in to move pages.');
			return;
		}
		$d = new DocumentationPage();
		$d->loadById($pageId);
		$d->parent_id = $to;
		$d->save();
		return $this->getTableOfContents($d->doc_id);
	}



	public function getComments($pageId) {
		$userId = AuthService::getCurrentUserId();
		$v = new View('documentation_page-all-comments');
		if ($userId) {
			$addComment = new Button();
			$addComment->text = 'Post a comment';
			$addComment->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/openCommentForm', $pageId)));
			$v->add($addComment);
		}
		$c = new DocumentationPageComment();
		foreach ($c->loadBySQLCondition("doc_id = '$pageId'") as $comment) {
			$wt = new WikiTranslator('documentation_page-comment-' . $comment->id);
			$wt->unregister('WikiTranslatorHeadingMode');
			$com = &new View();
			$com->template = 'doc/comment.tpl';
			$com->author = $comment->user_id;
			$com->body = $wt->mtov($comment->content);
			$com->date = date('d-m-Y h:i', $comment->created);
			if ($userId and $userId == $comment->user_id) {
				$edit = &new Button();
				$edit->text = 'Edit';
				$edit->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/openCommentForm', array($pageId, $comment->id))));
				$com->edit = $edit;
			}
			$v->add($com);
		}
		return $v;
	}



	public function openCommentForm($pageId, $commentId = null) {
		$w = new Window('documentation_page-comment-window');
		$w->title = 'Editing comment';
		$w->add($this->getCommentForm($pageId, $commentId));
		$w->open();
	}



	private function getCommentForm($pageId, $commentId = null) {
		$closeBeh = new Behaviour("Window.close('documentation_page-comment-window')");
		$body = new TextArea('documentation_page-comment-body-textarea');
		$body->addListener(new StopTypingListener(new Action('/doc/DocumentationCtrl/getCommentPreview', $body->valueReader())));
		$ok = new Button();
		$ok->text = 'Submit';
		$ok->addListener(new ClickListener(new Action('/doc/DocumentationCtrl/submitComment', array($pageId, $body->valueReader(), $commentId))));
		$ok->addListener(new ClickListener($closeBeh));
		$cancel = new Button();
		$cancel->text = 'Cancel';
		$cancel->addListener(new ClickListener($closeBeh));
		if ($commentId) {
			$c = new DocumentationPageComment();
			$c->loadById($commentId);
			if ($c->user_id == AuthService::getCurrentUserId() and $c->doc_id == $pageId) {
				$body->value = $c->content;
			}
		}
		$f = new Form();
		$f->template = 'doc/commentForm.tpl';
		$f->body = $body;
		$f->preview = $this->getCommentPreview($body->value);
		$f->ok = $ok;
		$f->cancel = $cancel;
		return $f;
	}



	public function getCommentPreview($content) {
		$preview = new View('documentation_page-comment-preview');
		$wt = new WikiTranslator();
		$preview->addText($wt->mtov($content) . '&nbsp;');
		return $preview;
	}



	public function submitComment($pageId, $content, $commentId = null) {
		$c = new DocumentationPageComment();
		if ($commentId) {
			$c->loadById($commentId);
			if ($c->user_id != AuthService::getCurrentUserId() or $c->doc_id != $pageId) {
				$this->response->alert('Unsupported operation');
				return;
			}
		}
		$c->content = $content;
		$c->doc_id = $pageId;
		$c->user_id = AuthService::getCurrentUserId();
		$c->created = time();
		$c->save();
		return $this->getComments($pageId);
	}



} // class DocumentationCtrl

?>