<?php
register_module([
	"name" => "Page History",
	"version" => "0.3",
	"author" => "Starbeamrainbowlabs",
	"description" => "Adds the ability to keep unlimited page history, limited only by your disk space. Note that this doesn't store file history (yet). Currently depends on feature-recent-changes for rendering of the history page.",
	"id" => "feature-history",
	"code" => function() {
		/**
		 * @api {get} ?action=history&page={pageName} Get a list of revisions for a page
		 * @apiName History
		 * @apiGroup Page
		 * @apiPermission Anonymous
		 * 
		 * @apiParam {string}	page	The page name to return a revision list for.
		 */
		
		/*
		 * ██   ██ ██ ███████ ████████  ██████  ██████  ██    ██
		 * ██   ██ ██ ██         ██    ██    ██ ██   ██  ██  ██
		 * ███████ ██ ███████    ██    ██    ██ ██████    ████
		 * ██   ██ ██      ██    ██    ██    ██ ██   ██    ██
		 * ██   ██ ██ ███████    ██     ██████  ██   ██    ██
		 */
		add_action("history", function() {
			global $settings, $env, $pageindex;
			
			
			$content = "<h1>History for $env->page</h1>\n";
			if(!empty($pageindex->{$env->page}->history))
			{
				$content .= "\t\t<ul class='page-list'>\n";
				foreach(array_reverse($pageindex->{$env->page}->history) as $revisionData)
				{
					// Only display edits for now
					if($revisionData->type != "edit")
					continue;
					
					// The number (and the sign) of the size difference to display
					$size_display = ($revisionData->sizediff > 0 ? "+" : "") . $revisionData->sizediff;
					$size_display_class = $revisionData->sizediff > 0 ? "larger" : ($revisionData->sizediff < 0 ? "smaller" : "nochange");
					if($revisionData->sizediff > 500 or $revisionData->sizediff < -500)
					$size_display_class .= " significant";
					$size_title_display = human_filesize($revisionData->newsize - $revisionData->sizediff) . " -> " .  human_filesize($revisionData->newsize);
					
					$content .= "<li><a href='?page=" . rawurlencode($env->page) . "&revision=$revisionData->rid'>#$revisionData->rid</a> " . render_editor($revisionData->editor) . " " . render_timestamp($revisionData->timestamp) . " <span class='cursor-query $size_display_class' title='$size_title_display'>($size_display)</span>";
				}
			}
			else
			{
				$content .= "<p style='text-align: center;'><em>(None yet! Try editing this page and then coming back here.)</em></p>\n";
			}
			exit(page_renderer::render_main("$env->page - History - $settings->sitename", $content));
		});
		
		
		register_save_preprocessor("history_add_revision");
	}
]);

function history_add_revision(&$pageinfo, &$newsource, &$oldsource, $save_pageindex = true) {
	global $pageindex, $paths, $env;
	
	if(!isset($pageinfo->history))
		$pageinfo->history = [];
	
	// Save the *new source* as a revision
	// This results in 2 copies of the current source, but this is ok
	// since any time someone changes something, it create a new
	// revision
	// Note that we can't save the old source here because we'd have no
	// clue who edited it since $pageinfo has already been updated by
	// this point
	
	// TODO Store tag changes here
	$nextRid = count($pageinfo->history); // The next revision id
	$ridFilename = "$pageinfo->filename.r$nextRid";
	// Insert a new entry into the history
	$pageinfo->history[] = [
		"type" => "edit", // We might want to store other types later (e.g. page moves)
		"rid" => $nextRid,
		"timestamp" => time(),
		"filename" => $ridFilename,
		"newsize" => strlen($newsource),
		"sizediff" => strlen($newsource) - strlen($oldsource),
		"editor" => $pageinfo->lasteditor
	];
	
	// Save the new source as a revision
	file_put_contents("$env->storage_prefix$ridFilename", $newsource);
	
	// Save the edited pageindex
	if($save_pageindex)
		file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
}

?>