<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="http://www.fustrate.com/dev/sources/Other/modification.xsl"?>
<!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification">
<modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/">
	<id>yodaofdarkness:advrep</id>
	<version>1.8</version>

	<file name="$boarddir/index.php">
		<operation>
			<search position="before"><![CDATA[
		'reporttm' => array('SendTopic.php', 'ReportToModerator'),]]></search>
			<add><![CDATA[
		'reputation' => array('Karma.php', 'SendKarma'),]]></add>
		</operation>
	</file>

	<file name="$themedir/Display.template.php">
		<operation>
			<search position="replace"><![CDATA[global $context, $settings, $options, $txt, $scripturl, $modSettings;]]></search>
			<add><![CDATA[global $context, $settings, $options, $txt, $scripturl, $modSettings, $user_info;]]></add>
		</operation>

		<operation>
			<search position="before"><![CDATA[
			<a id="top"></a>]]></search>
			<add><![CDATA[
			<span id="reputation_menu" style="visibility: hidden; display: none;">
				<div class="windowbg2">
					<strong>', $txt['karma_add_to'], ': <span id="reputation_name">&nbsp;</span></strong>
					<fieldset>
						<legend>', $txt['karma_your_opinion'], '</legend>
						<form id="reputation_form" name="reputation_form" action="', $scripturl, '?action=modifykarma" method="post" accept-charset="', $context['character_set'], '" class="reputation_form" onsubmit="aReputation[0].sendRep(); return false;">
							<input type="radio" name="type" value="agree"', !$context['can_pos_rep'] ? ' disabled="disabled"' : ' checked="checked"', ' /> ', $txt['karma_agree'], '
							<input type="radio" name="type" value="disagree"', !$context['can_neg_rep'] ? ' disabled="disabled"' : !$context['can_pos_rep'] ? ' checked="checked"' : '', ' /> ', $txt['karma_disagree'], '
							<span id="reputation_fields">&nbsp;</span>
							<br />
							', $txt['comment'], ': <input type="text" name="reputation_comment" /><br />
							<br />
							<input type="submit" value="', $txt['submit'], '" />
							<input type="hidden" name="topic" value="', $context['current_topic'], '.', $context['start'], '" />
							<input type="hidden" id="sessionid" name="', $context['session_var'], '" value="', $context['session_id'], '" />
						</form>
					</fieldset>
					<script language="JavaScript" type="text/javascript"><!-- // -->
						// Ajaxify that reputation box!
						if (typeof(window.XMLHttpRequest) != "undefined")
						{
							aReputation[0] = new Reputation({
								sBackReference: "aReputation[0]",
								sScriptUrl: "', $scripturl, '"
							});
						}
					</script>
				</div>
			</span>]]></add>
		</operation>

		<operation error="ignore">
			<search position="replace"><![CDATA[
			// Is karma display enabled?  Total or +/-?
			if ($modSettings['karmaMode'] == '1')
				echo '
								<li class="karma">', $modSettings['karmaLabel'], ' ', $message['member']['karma']['good'] - $message['member']['karma']['bad'], '</li>';
			elseif ($modSettings['karmaMode'] == '2')
				echo '
								<li class="karma">', $modSettings['karmaLabel'], ' +', $message['member']['karma']['good'], '/-', $message['member']['karma']['bad'], '</li>';

			// Is this user allowed to modify this member's karma?
			if ($message['member']['karma']['allow'])
				echo '
								<li class="karma_allow">
									<a href="', $scripturl, '?action=modifykarma;sa=applaud;uid=', $message['member']['id'], ';topic=', $context['current_topic'], '.' . $context['start'], ';m=', $message['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $modSettings['karmaApplaudLabel'], '</a>
									<a href="', $scripturl, '?action=modifykarma;sa=smite;uid=', $message['member']['id'], ';topic=', $context['current_topic'], '.', $context['start'], ';m=', $message['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $modSettings['karmaSmiteLabel'], '</a>
								</li>';]]></search>
			<add><![CDATA[
			// Is karma display enabled?
			if ($modSettings['karmaMode'] != '0')
			{
				echo '
							<li class="karma">', $txt['karma_power'], ': ', $message['member']['karma']['power'], '</li>
							<li class="karma_allow repbars">
									';
				foreach($message['member']['karma']['bars'] as $karma_bar)
					echo '<img src="', $settings['images_url'], '/karma_', $karma_bar['type'], '.gif" title="', $message['member']['name'], ' ', $karma_bar['desc'], '" alt="', $message['member']['name'], ' ', $karma_bar['desc'], '" />';

				echo '
							</li>';
			}]]></add>
		</operation>

		<operation error="ignore">
			<search position="after"><![CDATA[
				// Since we know this person isn't a guest, you *can* message them.
				if ($context['can_send_pm'])
					echo '
										<li><a href="', $scripturl, '?action=pm;sa=send;u=', $message['member']['id'], '" title="', $message['member']['online']['is_online'] ? $txt['pm_online'] : $txt['pm_offline'], '">', $settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/im_' . ($message['member']['online']['is_online'] ? 'on' : 'off') . '.gif" alt="' . ($message['member']['online']['is_online'] ? $txt['pm_online'] : $txt['pm_offline']) . '" border="0" />' : ($message['member']['online']['is_online'] ? $txt['pm_online'] : $txt['pm_offline']), '</a></li>';]]></search>
			<add><![CDATA[

				// Is this user allowed to modify this member's karma?
				if (($context['can_pos_rep'] || $context['can_neg_rep']) && $message['can_send_karma'] && ($user_info['id'] != $message['member']['id']))
					echo '
										<span style="visibility: hidden; display: none;" id="reputation_form_', $message['id'], '">
											<input type="hidden" name="uid" value="', $message['member']['id'], '" />
											<input type="hidden" name="m" value="', $message['id'], '" />
										</span>
										<li><a id="repicon" onclick="reputationForm(\'reputation_form_', $message['id'], '\', \'', $message['member']['name'], '\', this, event); return false;" href="', $scripturl, '?action=reputation;uid=', $message['member']['id'], ';m=', $message['id'], ';topic=', $context['current_topic'], '.', $context['start'], ';', $context['session_var'], '=', $context['session_id'], '"><img src="', $settings['images_url'], '/karma.gif" alt="', $txt['add_karma'], '" title="', $txt['add_karma'], '" /></a></li>';]]></add>
		</operation>
	</file>

	<file name="$themedir/PersonalMessage.template.php">
		<operation>
			<search position="replace"><![CDATA[
			// Is karma display enabled?  Total or +/-?
			if ($modSettings['karmaMode'] == '1')
				echo '
				<li class="karma">', $modSettings['karmaLabel'], ' ', $message['member']['karma']['good'] - $message['member']['karma']['bad'], '</li>';
			elseif ($modSettings['karmaMode'] == '2')
				echo '
				<li class="karma">', $modSettings['karmaLabel'], ' +', $message['member']['karma']['good'], '/-', $message['member']['karma']['bad'], '</li>';

			// Is this user allowed to modify this member's karma?
			if ($message['member']['karma']['allow'])
				echo '
				<li class="karma_allow">
					<a href="', $scripturl, '?action=modifykarma;sa=applaud;uid=', $message['member']['id'], ';f=', $context['folder'], ';start=', $context['start'], $context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '', ';pm=', $message['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $modSettings['karmaApplaudLabel'], '</a> <a href="', $scripturl, '?action=modifykarma;sa=smite;uid=', $message['member']['id'], ';f=', $context['folder'], ';start=', $context['start'], $context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '', ';pm=', $message['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $modSettings['karmaSmiteLabel'], '</a>
				</li>';]]></search>
			<add><![CDATA[
			// Karma removed by the Advanced Reputation System - who ever though karma in PMs was a good decision?]]></add>
		</operation>
	</file>

	<file name="$themedir/Profile.template.php">
		<operation>
			<search position="end" />
			<add><![CDATA[
// Shows recent reputation actions, and allows moderators to moderate them.
function template_reputation()
{
	global $context, $settings, $options, $scripturl, $modSettings, $txt;

	echo '
	<h3 class="titlebg">
		<span class="left"></span>
		<img src="', $settings['images_url'], '/karma.gif" alt="" /> ', $txt['karma_latest_title'], '
	</h3>
	<div class="windowbg2">
		<span class="topslice"><span></span></span>
		<div class="content">';

	if(empty($context['member']['karma_actions']))
				echo '
			', $txt['no_reputation_actions'];
	else
	{
		// If they can delete karma actions, start the form
		if($context['can_delete_karma'])
			echo '
			<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=reputation" method="post" accept-charset="', $context['character_set'], '">
				<input type="hidden" name="uid" value="', $context['id_member'], '" />
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />';

		echo '
				<table border="0" cellspacing="0" cellpadding="8" width="100%">
					<tr class="windowbg" style="font-weight: bold;">
						<td width="1%">&nbsp;</td>
						<td width="', $context['can_delete_karma'] ? '29' : '30', '%">', $txt['topic'], '</td>
						<td width="15%">', $txt['date'], '</td>
						<td width="30%">', $txt['comment'], '</td>
						<td width="12%">', $txt['to'], '</td>
						<td width="12%">', $txt['from'], '</td>', $context['can_delete_karma'] ? '
						<td width="1%"><input type="checkbox" onclick="invertAll(this, this.form);" class="check" /></td>' : '', '
					</tr>';

		$which = false;

		foreach($context['member']['karma_actions'] as $karma)
		{
			$which = !$which;

			echo '
					<tr class="windowbg', $which ? '2' : '', '">
						<td align="center"><img src="', $settings['images_url'], '/', $karma['action_type'], '_basic.gif" /></td>
						<td><a href="', $scripturl, '?topic=', $karma['topic_href'], '">', $karma['topic_title'], '</a></td>
						<td>', $karma['time'], '</td>
						<td>', $karma['comment'], '</td>
						<td>', $karma['target'], '</td>
						<td>', $karma['executor'], '</td>', $context['can_delete_karma'] ? '
						<td align="center"><input type="checkbox" name="deleteBoxes[]" value="' . $karma['delete_value'] . '" class="check" /></td>' : '', '
					</tr>';
		}

		echo '
				</table>
				<br />
				<strong>', $txt['pages'], ': ', $context['page_index'], '</strong>';


		// If they can delete karma actions, end the old
		if($context['can_delete_karma'])
			echo '
				<br />
				<div width="100%" align="right">
					<input class="button_submit" type="submit" name="del_selected" value="', $txt['quickmod_delete_selected'], '" onclick="if (!confirm(\'', $txt['quickmod_confirm'], '\')) return false;" /></span>
				</div>
			</form>';
	}

	echo '
		</div>
		<span class="botslice"><span></span></span>
	</div>
	<br />';
}]]></add>
		</operation>
	</file>

	<file name="$themedir/Stats.template.php">
		<operation>
			<search position="replace"><![CDATA[
			</div>
		</div>
		<div class="flow_hidden">
			<div id="top_topics_replies">]]></search>
			<add><![CDATA[
			</div>
		</div>';

	if(!empty($modSettings['karmaMode']))
	{
		echo '
		<div class="flow_hidden">
			<div id="best_karma">
				<h3 class="catbg"><span class="left"></span>
					<img src="', $settings['images_url'], '/stats_posters.gif" class="icon" alt="" /> ', $txt['best_karma'], '
				</h3>
				<div class="windowbg2">
					<span class="topslice"><span></span></span>
					<div class="content">
						<dl class="stats">';

		if(!empty($context['reputation_best']))
			foreach ($context['reputation_best'] as $member)
				echo '
							<dt>
								', $member['link'], ' (', $member['amount'], ')
							</dt>
							<dd class="statsbar">
								<span class="repbars">', $member['reputation_bars'], '</span>
							</dd>';

		echo '
						</dl>
						<div class="clear"></div>
					</div>
					<span class="botslice"><span></span></span>
				</div>
			</div>
			<div id="worst_karma">
				<h3 class="catbg"><span class="left"></span>
					<img src="', $settings['images_url'], '/stats_posters.gif" class="icon" alt="" /> ', $txt['worst_karma'], '
				</h3>
				<div class="windowbg2">
					<span class="topslice"><span></span></span>
					<div class="content">
						<dl class="stats">';

		if(!empty($context['reputation_worst']))
			foreach ($context['reputation_worst'] as $member)
				echo '
							<dt>
								', $member['link'], ' (', $member['amount'], ')
							</dt>
							<dd class="statsbar">
								<span class="repbars">', $member['reputation_bars'], '</span>
							</dd>';

		echo '
						</dl>
						<div class="clear"></div>
					</div>
					<span class="botslice"><span></span></span>
				</div>
			</div>
		</div>';
	}

	echo '
		<div class="flow_hidden">
			<div id="top_topics_replies">]]></add>
		</operation>
	</file>

	<file name="$themedir/Xml.template.php">
		<operation>
			<search position="end" />
			<add><![CDATA[
function template_reputation()
{
	global $context, $settings, $options, $txt;

	echo '<', '?xml version="1.0" encoding="', $context['character_set'], '"?', '>
<smf>';

	if($context['error_txt'] == "")
		echo '
	<result>', cleanXml($txt['reputation_sent']), '</result>';
	else
		echo '
	<error>', cleanXml($context['error_txt']), '</error>';

	echo '
</smf>';
}
]]></add>
		</operation>
	</file>

	<file name="$themedir/scripts/script.js">
		<operation>
			<search position="end" />
			<add><![CDATA[

var disappeardelay = 30 * 1000; // karma box hide display time, in milliseconds
var vertical_offset = "0px"; // vertical offset of karma box from image
var horizontal_offset = "-3px"; // horizontal offset of karma box from image

function getposOffset(what, offsettype)
{
	var totaloffset = (offsettype=="left") ? what.offsetLeft : what.offsetTop;
	var parentEl = what.offsetParent;

	while (parentEl!=null)
	{
		totaloffset = (offsettype == "left") ? totaloffset + parentEl.offsetLeft : totaloffset + parentEl.offsetTop;
		parentEl = parentEl.offsetParent;
	}

	return totaloffset;
}

function showhiderep(obj, e)
{
	rep_box.style.left = rep_box.style.top = -500;
	rep_box.widthobj = rep_box.style;
	rep_box.widthobj.width = '300px';

	if (obj.visibility == "visible"){
		obj.visibility = "hidden";
		obj.display = "none";
	}
	else
	{
		obj.visibility = "visible";
		obj.display = "block";
	}
}

function reputationForm(rep_contents, member_name, obj, e)
{
	if(window.event)
		event.cancelBubble = true;
	else if(e.stopPropagation)
		e.stopPropagation();

	clearhidebox();

	rep_box = document.getElementById("reputation_menu");
	rep_fields = document.getElementById("reputation_fields");
	rep_name = document.getElementById("reputation_name");
	setInnerHTML(rep_fields, getInnerHTML(document.getElementById(rep_contents)));
	setInnerHTML(rep_name, member_name);

	showhiderep(rep_box.style, e);

	rep_box.x = getposOffset(obj, "left");
	rep_box.y = getposOffset(obj, "top");
	rep_box.style.left = rep_box.x + "px";
	rep_box.style.top = rep_box.y + obj.offsetHeight + "px";

	delayhidebox();
}

function hidebox(e)
{
	if(typeof rep_box != "undefined")
		rep_box.style.visibility = "hidden";
}

function delayhidebox()
{
	delayhide = setTimeout("hidebox()", disappeardelay);
}

function clearhidebox()
{
	if(typeof delayhide != "undefined")
		clearTimeout(delayhide);
}

var aReputation = new Array();

// *** Reputation object.
function Reputation(oOptions)
{
	if (!this.isXmlHttpCapable())
		return;

	this.opt = oOptions;
	this.funcParent = this;
}

// Determine whether the quick modify can actually be used.
Reputation.prototype.isXmlHttpCapable = function ()
{
	if (typeof(window.XMLHttpRequest) == 'undefined')
		return false;

	// Opera didn't always support POST requests. So test it first.
	if (typeof(window.opera) != 'undefined')
	{
		var test = new XMLHttpRequest();
		if (typeof(test.setRequestHeader) != 'function')
			return false;
	}

	return true;
}

// The function called after a user wants to save his precious message.
Reputation.prototype.sendRep = function (sSessionId)
{
	var i, x = new Array();
	var form = document.forms.reputation_form.elements;
	x[x.length] = 'reputation_comment=' + escape(form['reputation_comment'].value.replace(/&#/g, "&#38;#").php_to8bit()).replace(/\+/g, "%2B");
	x[x.length] = 'topic=' + parseInt(form['topic'].value);
	x[x.length] = 'uid=' + parseInt(form['uid'].value);
	x[x.length] = 'm=' + parseInt(form['m'].value);
	x[x.length] = 'type=' + (form['type'][0].checked ? form['type'][0].value : form['type'][1].value);
	x[x.length] = document.getElementById('sessionid').name + '=' + document.getElementById('sessionid').value;

	// Happy Easter!
	if(form['reputation_comment'].value == "about:reputation"){
		alert("Version 1.7, for SMF 2.0 RC1. Code by Fustrate (http://www.fustrate.com/), who is pretty awesome.");
		return;
	}

	// Send in the XMLhttp request and let's hope for the best.
	ajax_indicator(true);
	sendXMLDocument.call(this, smf_prepareScriptUrl(this.opt.sScriptUrl) + "action=xmlhttp;sa=reputation;xml", x.join("&"), this.onRepDone);

	return false;
}

// Callback function of the XMLhttp request sending the modified message.
Reputation.prototype.onRepDone = function (XMLDoc)
{
	// We've finished the loading stuff.
	ajax_indicator(false);
	hidebox();

	// If we didn't get a valid document, just cancel.
	if (!XMLDoc || !XMLDoc.getElementsByTagName('smf')[0])
		return;

	var result = XMLDoc.getElementsByTagName('smf')[0].getElementsByTagName('result')[0];
	var error = XMLDoc.getElementsByTagName('smf')[0].getElementsByTagName('error')[0];

	if (result)
	{
		alert(result.childNodes[0].nodeValue);
		document.getElementById('repicon').style.display = 'none';
		document.getElementById('repicon').style.visibility = 'hidden';
	}
	else if (error)
		alert(error.childNodes[0].nodeValue);
}]]></add>
		</operation>
	</file>

	<file name="$themedir/css/index.css">
		<operation>
			<search position="end" />
			<add><![CDATA[
.repbars img
{
	padding: 0 1px 0 0;
}

#reputation_menu{
	position: absolute;
	border: 1px solid black;
	z-index: 100;
}]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Display.php">
		<operation>
			<search position="before"><![CDATA[
		'can_see_ip' => allowedTo('moderate_forum') || ($message['id_member'] == $user_info['id'] && !empty($user_info['id'])),]]></search>
			<add><![CDATA[
		'can_send_karma' => empty($message['is_repped']) && ($user_info['id'] != $message['id_member']),]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
		$messages_request = $smcFunc['db_query']('', '
			SELECT
				id_msg, icon, subject, poster_time, poster_ip, id_member, modified_time, modified_name, body,
				smileys_enabled, poster_name, poster_email, approved,
				id_msg_modified < {int:new_from} AS is_read
			FROM {db_prefix}messages
			WHERE id_msg IN ({array_int:message_list})
			ORDER BY id_msg' . (empty($options['view_newest_first']) ? '' : ' DESC'),
			array(
				'message_list' => $messages,
				'new_from' => $topicinfo['new_from'],
			)
		);]]></search>
			<add><![CDATA[
		$messages_request = $smcFunc['db_query']('', '
			SELECT
				m.id_msg, m.icon, m.subject, m.poster_time, m.poster_ip, m.id_member, m.modified_time, m.modified_name, m.body,
				m.smileys_enabled, m.poster_name, m.poster_email, m.approved,
				m.id_msg_modified < {int:new_from} AS is_read, k.message AS is_repped
			FROM {db_prefix}messages AS m
				LEFT JOIN {db_prefix}log_karma AS k ON (k.message = m.id_msg AND k.id_executor = {int:current_member})
			WHERE m.id_msg IN ({array_int:message_list})
			ORDER BY m.id_msg' . (empty($options['view_newest_first']) ? '' : ' DESC'),
			array(
				'message_list' => $messages,
				'new_from' => $topicinfo['new_from'],
				'current_member' => $user_info['id'],
			)
		);]]></add>
		</operation>
		<operation>
			<search position="before"><![CDATA[
	$context['can_reply'] |= $context['can_reply_unapproved'];]]></search>
			<add><![CDATA[
	$context['can_pos_rep'] = allowedTo('positive_karma');
	$context['can_neg_rep'] = allowedTo('negative_karma');]]></add>
		</operation>
	</file>


	<file name="$sourcedir/Karma.php">
		<operation>
			<search position="end" />
			<add><![CDATA[
// Modify a user's karma, only better than the old one!
function ModifyKarma()
{
	global $modSettings, $txt, $user_info, $smcFunc;

	// A fix for templates that don't get edited correctly, and still show the old links.
	if(isset($_GET['sa']) && ($_GET['sa'] == 'applaud' || $_GET['sa'] == 'smite'))
		redirectexit('action=reputation;uid=' . $_GET['uid'] . ';m=' . $_GET['m'] . ';topic=' . $_GET['topic'] . ';' . $context['session_var'] . '=' . $context['session_id']);

	// If the mod is disabled, show an error.
	if (empty($modSettings['karmaMode']))
		fatal_lang_error('feature_disabled', true);

	// These _must_ be numbers, no matter what.
	$uid = (int) $_POST['uid'];
	$message_id = (int) $_POST['m'];
	$topic_id = (int) $_POST['topic'];

	// If you're a guest or can't do this, blow you off...
	is_not_guest();
	isAllowedTo('karma_edit');

	checkSession('request');

	// If you don't have enough posts, tough luck.
	// !!! Should this be dropped in favor of post group permissions?  Should this apply to the member you are smiting/applauding?
	if ($user_info['posts'] < $modSettings['karmaMinPosts'])
		fatal_lang_error('not_enough_posts_karma', true, array($modSettings['karmaMinPosts']));

	// And you can't modify your own, punk! (use the profile if you need to, admins!)
	if (empty($uid) || $uid == $user_info['id'])
		fatal_lang_error('cant_change_own_karma', false);

	// Find their (super)power (and their secret identity)! Can't go into negatives...
	$points = $user_info['karma_good'] - $user_info['karma_bad'];
	$power = ($points - ($points % $modSettings['karmaBarPower'])) / $modSettings['karmaBarPower'];
	$power = (int) (($power > 0) ? $power : 0);

	// !!! Should use a modSetting for 300
	$comment = (strlen($_POST['reputation_comment']) > 300) ? substr($_POST['reputation_comment'], 0, 300) : $_POST['reputation_comment'];
	
	// I fart in your general direction!
	if (strtolower($comment) == 'your mother was a hamster and your father smelt of elderberries!')
		fatal_error('...and Saint Attila raised the hand grenade up on high, saying, "O Lord, bless this Thy hand grenade that with it Thou mayest blow Thine enemies to tiny bits, in Thy mercy." And the Lord did grin and the people did feast upon the lambs and sloths and carp and anchovies and orangutans and breakfast cereals, and fruit bats and large chu... *ahem* And the Lord spake, saying, "First shalt thou take out the Holy Pin, then shalt thou count to three, no more, no less. Three shall be the number thou shalt count, and the number of the counting shall be three. Four shalt thou not count, neither count thou two, excepting that thou then proceed to three. Five is right out. Once the number three, being the third number, be reached, then lobbest thou thy Holy Hand Grenade of Antioch towards thy foe, who being naughty in my sight, shall snuff it." Amen.', false);

	//Find the time 24 hours ago... but wait... what if karmaWaitTime is greater than 24?! Bad var name, but who gives a hoot, if it works?
	$yesterday = time() - 86400;
	$longtimeago = time() - (60 * 60 * ($modSettings['karmaWaitTime']));
	$hoursAgo = ($modSettings['karmaWaitTime'] < 24) ? $yesterday : $longtimeago;

	// Applauding or smiting? Don't try to do a cheap javascript injection on me...
	switch ($_POST['type'])
	{
		case 'agree':
			if(!allowedTo('positive_karma'))
				fatal_lang_error('karma_cant_agree', false);
			$karma_which = 'karma_good';
			break;
		case 'disagree':
			if(!allowedTo('negative_karma'))
				fatal_lang_error('karma_cant_disagree', false);
			$karma_which = 'karma_bad';
			break;
		default:
			// Should never get here
			fatal_lang_error('karma_choose_action', false);
	}

	// Going in order of permissions... it only gets added if it passes all of the tests!

	// Used up all of their $modSettings['karmaMaxPerDay'] ?
	if (!empty($modSettings['karmaMaxPerDay']) && ($modSettings['karmaMaxPerDay'] > 0))
	{
		// Find out if this user has done this in the past 24 hours.
		$request = $smcFunc['db_query']('', '
			SELECT log_time
			FROM {db_prefix}log_karma
			WHERE id_executor = {int:current_member}
				AND log_time >= {int:yesterday}',
			array(
				'current_member' => $user_info['id'],
				'yesterday' => $hoursAgo,
			)
		);

		if ($smcFunc['db_num_rows']($request) >= $modSettings['karmaMaxPerDay']){ // but why would they be over?
			$smcFunc['db_free_result']($request);
			fatal_lang_error('karma_maxed_out', false, array($modSettings['karmaMaxPerDay']));
		}

		$smcFunc['db_free_result']($request);
	}

	// Haven't waited long enough?
	if (!empty($modSettings['karmaWaitTime']) && (!empty($modSettings['karmaTimeRestrictAdmins']) || !allowedTo('moderate_forum')) && $modSettings['karmaWaitTime'] > 0)
	{
		// Find out if this user has done this in the past $longenough.
		$request = $smcFunc['db_query']('', '
			SELECT log_time
			FROM {db_prefix}log_karma
			WHERE id_executor = {int:current_member}
				AND log_time >= {int:waittime}
			LIMIT 1',
			array(
				'current_member' => $user_info['id'],
				'waittime' => $longtimeago,
			)
		);

		if ($smcFunc['db_num_rows']($request) > 0)
		{
			// Give them approximate minutes until they can, to be nice ;)
			list ($log_time) = $smcFunc['db_fetch_row']($request);
			$log_time_wait = ($log_time + (60 * 60 * $modSettings['karmaWaitTime'])) - time(); // seconds
			$log_time_wait = ($log_time_wait - ($log_time_wait % 60)) / 60; // minutes
			$smcFunc['db_free_result']($request);
			fatal_lang_error('karma_please_wait', false, array($modSettings['karmaWaitTime'], $log_time_wait));
		}

		$smcFunc['db_free_result']($request);
	}

	// Need to spread it around a bit? No, not the flu, silly!
	if (!empty($modSettings['karmaSpreadAround']) && ($modSettings['karmaSpreadAround'] > 0))
	{
		// Grab the latest karmaSpreadAround actions - if the target is in there, throw an error!
		$request = $smcFunc['db_query']('', '
			SELECT id_target
			FROM {db_prefix}log_karma
			WHERE id_executor = {int:current_member}
			ORDER BY log_time DESC
			LIMIT {int:spread}',
			array(
				'current_member' => $user_info['id'],
				'spread' => $modSettings['karmaSpreadAround'],
			)
		);

		if ($smcFunc['db_num_rows']($request) > 0)
			while($row = $smcFunc['db_fetch_assoc']($request))
				if($row['id_target'] == $uid)
					fatal_lang_error('karma_spread_around', false);

		$smcFunc['db_free_result']($request);
	}

	// One last test - have they already sent rep to this particular post?
	$request = $smcFunc['db_query']('', '
		SELECT log_time
		FROM {db_prefix}log_karma
		WHERE id_executor = {int:executor}
			AND message = {string:message}
		LIMIT 1',
		array(
			'executor' => $user_info['id'],
			'message' => $message_id
		)
	);

	if($smcFunc['db_num_rows']($request) != 0)
		fatal_lang_error('karma_sent_twice', false);

	$smcFunc['db_free_result']($request);

	// Finally! Now do an update

	$request = $smcFunc['db_query']('', '
		UPDATE {db_prefix}members
		SET {raw:which} = {raw:which} + {int:power}
		WHERE id_member = {int:uid}',
		array(
			'power' => $power,
			'uid' => $uid,
			'which' => $karma_which,
		)
	);

	if(!$request)
		fatal_lang_error('karma_didnt_update', false);

	$action_type = ($power != 0) ? $karma_which : 'karma_disabled';

	$request = $smcFunc['db_query']('', '
		SELECT subject
		FROM {db_prefix}messages
		WHERE id_msg = {int:id_message}
		LIMIT 1',
		array(
			'id_message' => $message_id,
		)
	);

	list ($title) = $smcFunc['db_fetch_row']($request);

	$smcFunc['db_free_result']($request);

	// Log this new action!
	$smcFunc['db_insert']('replace',
		'{db_prefix}log_karma',
		array('action' => 'int', 'id_target' => 'int', 'id_executor' => 'int', 'log_time' => 'int', 'comment' => 'string', 'action_type' => 'string', 'message' => 'int', 'topic' => 'int', 'title' => 'string'),
		array($power, $uid, $user_info['id'], time(), $comment, $action_type, $message_id, $topic_id, $title),
		array('id_target', 'id_executor')
	);

	// Figure out where to go back to.... the topic?
	if (isset($_POST['topic']))
		redirectexit('topic=' . $_POST['topic'] . '#msg' . $_POST['m']);
	// Hrm... maybe a personal message?
	elseif (isset($_POST['f']))
		redirectexit('action=pm;f=' . $_POST['f'] . ';start=' . $_POST['start'] . (isset($_POST['l']) ? ';l=' . $_POST['l'] : '') . (isset($_POST['pm']) ? '#' . $_POST['pm'] : ''));
	// JavaScript as a last resort.
	else
	{
		echo '
<html>
	<head>
		<title>...</title>
		<script language="JavaScript" type="text/javascript"><!-- // -->
			history.go(-1);
		</script>
	</head>
	<body>&laquo;</body>
</html>';

		obExit(false);
	}
}

// For those poor souls without javascript support :(
function SendKarma()
{
	global $modSettings, $user_info, $context, $smcFunc, $txt;

	// If the mod is disabled, show an error.
	if (empty($modSettings['karmaMode']))
		fatal_lang_error('feature_disabled', true);

	if(!isset($_GET['uid']) && !isset($_GET['m']) && !isset($_GET['topic']))
		return ReputationLog();

	// If you're a guest or can't do this, blow you off...
	is_not_guest();
	isAllowedTo('karma_edit');
	checkSession('request');

	// These _must_ be a number, no matter what.
	$uid = (int) $_GET['uid'];
	$message = (int) $_GET['m'];
	$topic = (int) $_GET['topic'];

	// You can't modify your own, punk! (use the profile if you need to.)
	if (empty($uid) || $uid == $user_info['id'])
		fatal_lang_error('cant_change_own_karma', false);

	// If you don't have enough posts, tough luck.
	// !!! Should this be dropped in favor of post group permissions?  Should this apply to the member you are smiting/applauding?
	if ($user_info['posts'] < $modSettings['karmaMinPosts'])
		fatal_lang_error('not_enough_posts_karma', true, array($modSettings['karmaMinPosts']));

	$message_request = $smcFunc['db_query']('', '
		SELECT *
		FROM {db_prefix}messages
		WHERE id_msg = {int:message}
		LIMIT 1',
		array(
			'message' => $message,
		)
	);

	while($row = $smcFunc['db_fetch_assoc']($message_request))
	{
		$context['message'] = $row;

		$board_request = $smcFunc['db_query']('', '
			SELECT *
			FROM {db_prefix}boards
			WHERE id_board = {int:board}',
			array(
				'board' => $context['message']['id_board']
			)
		);

		$board = $smcFunc['db_fetch_assoc']($board_request);

		// Load the membergroups allowed, and check permissions.
		$board_groups = $board['member_groups'] == '' ? array() : explode(',', $board['member_groups']);
		$smcFunc['db_free_result']($board_request);

		// Kick 'em out if they don't have permission to view this topic!
		if (count(array_intersect($user_info['groups'], $board_groups)) == 0 && !$user_info['is_admin'])
			fatal_lang_error('topic_gone', false);

		// Put it in quote tags to make it stand out a little... and because it's a quote.
		$context['message']['body'] = "[quote author={$context['message']['poster_name']} link=topic={$context['message']['id_topic']}.msg{$context['message']['id_msg']}#msg{$context['message']['id_msg']} date={$context['message']['poster_time']}]{$context['message']['body']}[/quote]";

		// Amish girls gone wild!
		censorText($context['message']['body']);
		censorText($context['message']['subject']);

		// Run BBC interpreter on the message.
		$context['message']['body'] = parse_bbc($context['message']['body'], $context['message']['smileys_enabled'], $context['message']['id_msg']);
	}

	$context['sub_template'] = 'main';
	$context['page_title'] = $txt['karma_add_to'];
	$context['topic'] = $topic;
	$context['m'] = $message;
	$context['uid'] = $uid;
	$context['can_pos_rep'] = allowedTo('positive_karma');
	$context['can_neg_rep'] = allowedTo('negative_karma');

	loadTemplate('Karma');
}

function ReputationLog()
{
	global $modSettings, $user_info, $context, $smcFunc, $txt, $scripturl;

	// If the mod is disabled, show an error.
	if (empty($modSettings['karmaMode']))
		fatal_lang_error('feature_disabled', true);

	// If you're a guest or can't do this, blow you off...
	is_not_guest();
	isAllowedTo('karma_edit');

	// Set up the stuff and load the user.
	$context['page_title'] = $txt['reputation_log'];
	$context['start'] = isset($_GET['start']) ? (int) $_GET['start'] : 0;

	$context['rep_sent'] = array();

	$request = $smcFunc['db_query']('', '
		SELECT COUNT(*) AS count
		FROM {db_prefix}log_karma',
		array()
	);

	list ($num_given) = $smcFunc['db_fetch_row']($request);
	$smcFunc['db_free_result']($request);

	$request = $smcFunc['db_query']('', '
		SELECT k.*, r.real_name AS receiver_name, s.real_name AS sender_name
		FROM {db_prefix}log_karma AS k
			LEFT JOIN {db_prefix}members AS r ON (r.id_member = k.id_target)
			LEFT JOIN {db_prefix}members AS s ON (s.id_member = k.id_executor)
		ORDER BY log_time DESC
		LIMIT {int:start}, 50',
		array(
			'start' => $context['start'],
		)
	);

	while ($row = $smcFunc['db_fetch_assoc']($request))
	{
		parsesmileys($row['comment']);

		$context['rep_sent'][] = array(
			'action_type' => !empty($row['action_type']) ? $row['action_type'] : ($row['action'] > 0) ? 'karma_good' : 'karma_bad',
			'executor' => array(
				'name' => $row['sender_name'],
				'id' => $row['id_executor'],
			),
			'target' => array(
				'name' => $row['receiver_name'],
				'id' => $row['id_target'],
			),
			'time' => timeformat($row['log_time']),
			'comment' => $row['comment'],
			'topic_href' => $row['topic'] . '.msg' . $row['message'] . '#msg' . $row['message'],
			'topic_title' => $row['title'],
		);
	}

	$smcFunc['db_free_result']($request);

	loadTemplate('Karma');
	$context['sub_template'] = 'log';

	// Construct the page index
	$context['page_index'] = constructPageIndex($scripturl . '?action=reputation', $_REQUEST['start'], $num_given, 50);
}]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
// Modify a user's karma.
function ModifyKarma()
{]]></search>
			<add><![CDATA[
/******************* Disabled by Advanced Reputation System **********************
**********************************************************************************
// Modify a user's karma the old and disgusting way...
function ModifyKarma_old()
{]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
		obExit(false);
	}
}

// What's this?  I dunno, what are you talking about?  Never seen this before, nope.  No siree.
function BookOfUnknown()]]></search>
			<add><![CDATA[
		obExit(false);
	}
}
**********************************************************************************
******************** Disabled by Advanced Reputation System *********************/

// What's this?  I dunno, what are you talking about?  Never seen this before, nope.  No siree.
function BookOfUnknown()]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Load.php">
		<operation>
			<search position="before"><![CDATA[
		'time_offset' => empty($user_settings['time_offset']) ? 0 : $user_settings['time_offset'],]]></search>
			<add><![CDATA[
		'karma_good' => empty($user_settings['karma_good']) ? 0 : $user_settings['karma_good'],
		'karma_bad' => empty($user_settings['karma_bad']) ? 0 : $user_settings['karma_bad'],]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
			mem.karma_good, mem.id_post_group, mem.karma_bad, mem.lngfile, mem.id_group, mem.time_offset, mem.show_online,]]></search>
			<add><![CDATA[
			mem.karma_good, mem.id_post_group, mem.karma_bad, mem.lngfile, mem.id_group, mem.time_offset, mem.show_online, mem.karma_disabled,]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
			mem.openid_uri, mem.birthdate, mem.icq, mem.aim, mem.yim, mem.msn, mem.posts, mem.last_login, mem.karma_good,]]></search>
			<add><![CDATA[
			mem.birthdate, mem.icq, mem.aim, mem.yim, mem.msn, mem.posts, mem.last_login, mem.karma_good, mem.karma_disabled,]]></add>
		</operation>
		<operation>
			<search position="before"><![CDATA[
	$buddy_list = !empty($profile['buddy_list']) ? explode(',', $profile['buddy_list']) : array();]]></search>
			<add><![CDATA[

	$profile['karma_bars'] = array();

	// If they are in the positives, and want it displayed
	if(!$profile['karma_disabled'] && ($profile['karma_good'] >= $profile['karma_bad']))
	{
		$points = $profile['karma_good'] - $profile['karma_bad'];
		$power = ($points - ($points % $modSettings['karmaBarPower'])) / $modSettings['karmaBarPower'];
		$bars = ($points - ($points % $modSettings['karmaBarPoints'])) / $modSettings['karmaBarPoints'];
		$bars = $bars == 0 ? 1 : $bars;
		$bars = ($bars > $modSettings['karmaMaxBars']) ? $modSettings['karmaMaxBars'] : $bars;
		$descriptions = preg_split("/(\r)?\n/", $modSettings['karmaDescriptions']);
		$description = $descriptions[$bars - 1];

		for($i = 0; $i < $bars; $i++)
			$profile['karma_bars'][] = array(
				'type' => 'good_basic',
				'desc' => $description
			);

		if($bars >= $modSettings['karmaSuperBar'])
			for($i = ($modSettings['karmaSuperBar'] - 1); $i < $bars; $i++)
				$profile['karma_bars'][$i]['type'] = 'good_super';

	// If they are in the negatives and want it displayed (or don't have a choice)
	}
	else if(!$profile['karma_disabled'])
	{
		$points = $profile['karma_bad'] - $profile['karma_good'];
		$bars = ($points - ($points % $modSettings['karmaBarPoints'])) / $modSettings['karmaBarPoints'];
		$bars = $bars == 0 ? 1 : $bars;
		$bars = ($bars > $modSettings['karmaMaxBars']) ? $modSettings['karmaMaxBars'] : $bars;

		for($i = 0; $i < $bars; $i++)
			$profile['karma_bars'][] = array(
				'type' => 'bad_basic',
				'desc' => $modSettings['karmaNegativeDescription']
			);

		$power = 0;

		if($bars >= $modSettings['karmaSuperBar'])
			for($i = ($modSettings['karmaSuperBar'] - 1); $i < $bars; $i++)
				$profile['karma_bars'][$i]['type'] = 'bad_super';
	// They don't want it displayed!
	}
	else
	{

		$profile['karma_bars'][] = array(
			'type' => 'disabled_basic',
			'desc' => $modSettings['karmaDisabledDescription']
		);

		$power = 0;

	}]]></add>
		</operation>
		<operation>
			<search position="after"><![CDATA[
			'good' => $profile['karma_good'],
			'bad' => $profile['karma_bad'],]]></search>
			<add><![CDATA[
			'total' => $profile['karma_good'] - $profile['karma_bad'],
			'disabled' => $profile['karma_disabled'],
			'bars' => $profile['karma_bars'],
			'power' => $power,]]></add>
		</operation>
	</file>

	<file name="$sourcedir/ManageMaintenance.php">
		<operation>
			<search position="replace"><![CDATA[
	// Clear out the karma actions.
	$smcFunc['db_query']('', '
		DELETE FROM {db_prefix}log_karma');]]></search>
			<add><![CDATA[
// Advanced Reputation System - Never clear out karma logs!
/*
	// Clear out the karma actions.
	$smcFunc['db_query']('', '
		DELETE FROM {db_prefix}log_karma');
*/]]></add>
		</operation>
	</file>

	<file name="$sourcedir/ManagePermissions.php">
		<operation>
			<search position="before"><![CDATA[
		'view_mlist',
		'karma_edit',]]></search>
			<add><![CDATA[
		// Advanced Reputation System Settings
		'disable_karma_display',
		'positive_karma',
		'negative_karma',
		'delete_karma',]]></add>
		</operation>
		<operation>
			<search position="before"><![CDATA[
			'karma_edit' => array(false, 'general', 'moderate_general'),]]></search>
			<add><![CDATA[
			// Advanced Reputation System Settings
			'disable_karma_display' => array(false, 'general', 'moderate_general'),
			'positive_karma' => array(false, 'general', 'moderate_general'),
			'negative_karma' => array(false, 'general', 'moderate_general'),
			'delete_karma' => array(false, 'general', 'moderate_general'),]]></add>
		</operation>
		<operation>
			<search position="before"><![CDATA[
	$context['non_guest_permissions'] = array(]]></search>
			<add><![CDATA[
		// Advanced Reputation System Settings
		'disable_karma_display',
		'positive_karma',
		'negative_karma',
		'delete_karma',]]></add>
		</operation>
	</file>

	<file name="$sourcedir/ManageServer.php">
		<operation>
			<search position="after"><![CDATA[
	$inlinePermissions = array();
	foreach ($config_vars as $var)]]></search>
			<add><![CDATA[
	if(isset($_POST['karmaDescriptions'])){
		// Let's set two other ones, too!
		$config_vars[] = array('int', 'karmaMaxBars');
		$config_vars[] = array('int', 'karmaSuperBar');

		$_POST['karmaDescriptions'] = trim($_POST['karmaDescriptions']);
		$descriptions = count(preg_split("/(\r)?\n/", $_POST['karmaDescriptions']));

		$_POST['karmaMaxBars'] = $descriptions;
		$_POST['karmaSuperBar'] = ($descriptions - ($descriptions % 2))/2 + 1;
	}
]]></add>
		</operation>
	</file>

	<file name="$sourcedir/ManageSettings.php">
		<operation>
			<search position="replace"><![CDATA['karmaMode' => 2,]]></search>
			<add><![CDATA['karmaMode' => 1,]]></add>
		</operation>
		<operation>
			<search position="before"><![CDATA[
			array('text', 'karmaSmiteLabel'),]]></search>
			<add><![CDATA[
		'',
			// Advanced Reputation System Settings
			array('int', 'karmaValuePost'),
			array('int', 'karmaValueThread'),
			array('int', 'karmaBarPower'),
			array('int', 'karmaBarPoints'),
			array('int', 'karmaRegistration'),
			array('int', 'karmaBirthday'),
			array('text', 'karmaMaxPerDay'),
			array('text', 'karmaSpreadAround'),
			array('large_text', 'karmaDescriptions'),
			array('text', 'karmaDisabledDescription'),
			array('text', 'karmaNegativeDescription'),]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
			'karma' => array(
			),
			'sig' => array(]]></search>
			<add><![CDATA[
			'karma' => array(
				'description' => $txt['karma_settings_desc'],
			),
			'sig' => array(]]></add>
		</operation>

	</file>

	<file name="$sourcedir/Post.php">
		<operation>
			<search position="replace"><![CDATA[
		$posterIsGuest = $user_info['is_guest'];
	}
	// Posting a new topic.]]></search>
			<add><![CDATA[
		$posterIsGuest = $user_info['is_guest'];

		if(!$user_info['is_guest'] && $modSettings['karmaValuePost'] > 0)
			$request = $smcFunc['db_query']('', '
				UPDATE {db_prefix}members
				SET karma_good = karma_good + {int:newkarma}
				WHERE id_member = {int:member}',
				array(
					'newkarma' => $modSettings['karmaValuePost'],
					'member' => $user_info['id']
				)
			);
	}
	// Posting a new topic.]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
		$posterIsGuest = $user_info['is_guest'];
	}
	// Modifying an existing message?]]></search>
			<add><![CDATA[
		$posterIsGuest = $user_info['is_guest'];

		if(!$user_info['is_guest'] && $modSettings['karmaValueThread'] > 0)
			$request = $smcFunc['db_query']('', '
				UPDATE {db_prefix}members
				SET karma_good = karma_good + {int:newkarma}
				WHERE id_member = {int:member}',
				array(
					'newkarma' => $modSettings['karmaValueThread'],
					'member' => $user_info['id']
				)
			);
	}
	// Modifying an existing message?]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Profile.php">
		<operation>
			<search position="before"><![CDATA[
				'permissions' => array(
					'label' => $txt['showPermissions'],
					'file' => 'Profile-View.php',
					'function' => 'showPermissions',
					'permission' => array(
						'own' => 'manage_permissions',
						'any' => 'manage_permissions',
					),
				),]]></search>
			<add><![CDATA[
				'reputation' => array(
					'label' => $txt['reputation'],
					'file' => 'Profile-View.php',
					'function' => 'reputation',
					'permission' => array(
						'own' => array('profile_view_own'),
						'any' => array('moderate_forum'),
					),
					'enabled' => (empty($modSettings['karmaMode']) ? false : true),
				),]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Profile-Modify.php">
		<operation>
			<search position="before"><![CDATA[
			'enabled' => !empty($modSettings['karmaMode']),
		),]]></search>
			<add><![CDATA[
		'karma_disabled' => array(
			'type' => 'check',
			'value' => empty($cur_profile['karma_disabled']) ? false : true,
			'label' => $txt['user_disable_karma'],
			'subtext' => $txt['user_disable_karma_description'],
			'permission' => 'disable_karma_display',
			'input_validate' => create_function('&$value', '
				$value = $value == 1 ? 1 : 0;

				return true;
			')
		),]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
			'karma_good', 'hr',]]></search>
			<add><![CDATA[
			'karma_good', 'karma_disabled', 'hr',]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[]]></search>
			<add><![CDATA[]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Profile-View.php">
		<operation>
			<search position="end" />
			<add><![CDATA[
// View a summary. Includes the deletion of actions.
function reputation($memID)
{
	global $context, $memberContext, $txt, $modSettings, $user_info, $user_profile, $sourcedir, $scripturl, $smcFunc;

	// If the mod is disabled, show an error.
	if (empty($modSettings['karmaMode']))
		fatal_lang_error('feature_disabled', true);

	// Attempt to load the member's profile data.
	if (!loadMemberContext($memID) || !isset($memberContext[$memID]))
		fatal_lang_error('not_a_user', false);

	// Set up the stuff and load the user.
	$context += array(
		'page_title' => $txt['reputation'] . ' - ' . $memberContext[$memID]['name'],
		'member' => &$memberContext[$memID],
		'can_delete_karma' => allowedTo('karma_delete'),
		'start' => isset($_GET['start']) ? (int) $_GET['start'] : 0,
	);

	$amount = 15;

	// Are we deleting karma entries?
	if(isset($_POST['deleteBoxes']))
	{
		is_not_guest();
		isAllowedTo('delete_karma');
		checkSession('request');

		foreach($_POST['deleteBoxes'] as $value)
			if(!preg_match('/[0-9]+\|[0-9]+\|[0-9]{10}/', $value))
				die('Hacker!!!');
			else
				$delete[] = explode('|', $value);

		foreach($delete as $value)
		{
			$request = $smcFunc['db_query']('', '
				SELECT action, action_type
				FROM {db_prefix}log_karma
				WHERE id_executor = {int:executor}
				AND log_time = {int:time}
				LIMIT 1',
				array(
					'executor' => $value[1],
					'time' => $value[2]
				)
			);

			// Reverse prior actions
			while($row = $smcFunc['db_fetch_assoc']($request))
			{
				loadMemberData($value[0]);
				loadMemberContext($value[0], false);

				if($row['action_type'] == 'karma_good')
					updateMemberData($value[0], array('karma_good' => ($memberContext[$value[0]]['karma']['good'] - ((int) $row['action']))));
				else if($row['action_type'] == 'karma_bad')
					updateMemberData($value[0], array('karma_bad' => ($memberContext[$value[0]]['karma']['bad'] - ((int) $row['action']))));
			}

			$smcFunc['db_free_result']($request);

			$smcFunc['db_query']('', '
				DELETE
				FROM {db_prefix}log_karma
				WHERE id_executor = {int:executor}
				AND log_time = {int:time}',
				array(
					'executor' => $value[1],
					'time' => $value[2]
				)
			);
		}
	}

	// A list of actions they've been a part of
	$request = $smcFunc['db_query']('', '
		SELECT *
		FROM {db_prefix}log_karma
		WHERE id_target = {int:target}
			OR id_executor = {int:target}
		LIMIT {int:start}, {int:amount}',
		array(
			'target' => $memID,
			'start' => $context['start'],
			'amount' => $amount,
		)
	);

	while ($row = $smcFunc['db_fetch_assoc']($request))
	{
		// There are two types of rows - ones you sent, and ones you received.
		if($row['id_target'] == $memID)
		{
			loadMemberData($row['id_executor']);
			loadMemberContext($row['id_executor'], false);

			parsesmileys($row['comment']);

			$context['member']['karma_actions'][] = array(
				'action_type' => !empty($row['action_type']) ? $row['action_type'] : (($row['action'] > 0) ? 'karma_good' : 'karma_bad'),
				'executor' => $memberContext[$row['id_executor']]['link'],
				'target' => $txt['reputation_you'],
				'time' => timeformat($row['log_time']),
				'comment' => $row['comment'],
				'topic_href' => $row['topic'] . '.msg' . $row['message'] . '#msg' . $row['message'],
				'topic_title' => $row['title'],
				'delete_value' => $row['id_target'] . '|' . $row['id_executor'] . '|' . $row['log_time'],
			);
		}
		else
		{
			loadMemberData($row['id_target']);
			loadMemberContext($row['id_target'], false);

			parsesmileys($row['comment']);

			$context['member']['karma_actions'][] = array(
				'action_type' => !empty($row['action_type']) ? $row['action_type'] : (($row['action'] > 0) ? 'karma_good' : 'karma_bad'),
				'executor' => $txt['reputation_you'],
				'target' => $memberContext[$row['id_target']]['link'],
				'time' => timeformat($row['log_time']),
				'comment' => $row['comment'],
				'topic_href' => $row['topic'] . '.msg' . $row['message'] . '#msg' . $row['message'],
				'topic_title' => $row['title'],
				'delete_value' => $row['id_target'] . '|' . $row['id_executor'] . '|' . $row['log_time'],
			);
		}
	}

	$smcFunc['db_free_result']($request);

	// And let's find out where the most are...
	$request = $smcFunc['db_query']('', '
		SELECT COUNT(*) AS num_rows
		FROM {db_prefix}log_karma
		WHERE id_target = {int:id}
			OR id_executor = {int:id}',
		array(
			'id' => $memID
		)
	);

	list ($total_actions) = $smcFunc['db_fetch_row']($request);
	$smcFunc['db_free_result']($request);

	// Construct the page index
	$context['page_index'] = constructPageIndex($scripturl . '?action=profile;area=reputation;u=' . $memID, $context['start'], $total_actions, $amount);
}]]></add>
		</operation>
	</file>

	<file name="$sourcedir/RemoveTopic.php">
		<operation>
			<search position="replace"><![CDATA[
	if (!empty($row['id_member']) && $decreasePostCount && empty($row['count_posts']) && $row['approved'])
		updateMemberData($row['id_member'], array('posts' => '-'));]]></search>
			<add><![CDATA[
	if (!empty($row['id_member']) && $decreasePostCount && empty($row['count_posts']) && $row['approved'])
	{
		updateMemberData($row['id_member'], array('posts' => '-'));

		if($modSettings['karmaValuePost'] > 0)
			$request = $smcFunc['db_query']('', '
				UPDATE {db_prefix}members
				SET karma_good = karma_good - {int:newkarma}
				WHERE id_member = {int:member}',
				array(
					'newkarma' => $modSettings['karmaValuePost'],
					'member' => $row['id_member']
				)
			);
	}]]></add>
		</operation>
		<operation>
			<search position="replace"><![CDATA[
			while ($rowMembers = $smcFunc['db_fetch_assoc']($requestMembers))
				updateMemberData($rowMembers['id_member'], array('posts' => 'posts - ' . $rowMembers['posts']));]]></search>
			<add><![CDATA[
			while ($rowMembers = $smcFunc['db_fetch_assoc']($requestMembers))
			{
				updateMemberData($rowMembers['id_member'], array('posts' => 'posts - ' . $rowMembers['posts']));

				if($modSettings['karmaValueThread'] > 0)
					$request = $smcFunc['db_query']('', '
						UPDATE {db_prefix}members
						SET karma_good = karma_good - {int:newkarma}
						WHERE id_member = {int:memberid}',
						array(
							'newkarma' => $modSettings['karmaValueThread'],
							'memberid' => $rowMembers['id_member']
						)
					);
			}]]></add>
		</operation>
	</file>

	<file name="$sourcedir/ScheduledTasks.php">
		<operation>
			<search position="end" />
			<add><![CDATA[
// Check once a day for account birthdays, and give them reputation :)
function scheduled_karma_birthdays()
{
	global $smcFunc, $modSettings;

	// If we aren't going to give anything in the first place, just return true
	if(($modSettings['karmaBirthday'] <= 0) || empty($modSettings['karmaMode']))
		return true;

	// 86400 is a day's worth of seconds, fyi
	$today = time();
	$todayBegin = $today - ($today % 86400);
	$todayEnd = $todayBegin + 86400;

	// Were they born today?
	$request = $smcFunc['db_query']('', '
		SELECT karma_good, id_member
		FROM {db_prefix}members
		WHERE date_registered >= {string:todayBegin}
		AND date_registered < {string:todayEnd}',
		array(
			'todayBegin' => $todayBegin,
			'todayEnd' => $todayEnd
		)
	);

	while ($row = $smcFunc['db_fetch_assoc']($request))
	{
		$karmaGood = $row['karma_good'] + $modSettings['karmaBirthday'];
		updateMemberData($row['id_member'], array('karma_good' => $karmaGood));
	}

	$smcFunc['db_free_result']($request);

	return true;
}]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Stats.php">
		<operation>
			<search position="replace"><![CDATA[
function DisplayStats()
{
	global $txt, $scripturl, $modSettings, $user_info, $context, $smcFunc;]]></search>
			<add><![CDATA[
function DisplayStats()
{
	global $txt, $scripturl, $modSettings, $user_info, $context, $smcFunc, $settings;]]></add>
		</operation>

		<operation>
			<search position="after"><![CDATA[
	// Format the numbers nicely.]]></search>
			<add><![CDATA[
	if(!empty($modSettings['karmaMode']))
	{
		$descriptions = preg_split("/(\r)?\n/", $modSettings['karmaDescriptions']);

		$result = $smcFunc['db_query']('', '
			SELECT (karma_good - karma_bad) AS karma, id_member, real_name
			FROM {db_prefix}members
			WHERE karma_good > karma_bad
			ORDER BY karma DESC
			LIMIT 10',
			array()
		);

		while($row = $smcFunc['db_fetch_assoc']($result))
		{
			$rep_bars = '';

			$points = $row['karma'];
			$bars = ($points - ($points % $modSettings['karmaBarPoints'])) / $modSettings['karmaBarPoints'];
			$bars = $bars < 1 ? 1 : (($bars > $modSettings['karmaMaxBars']) ? $modSettings['karmaMaxBars'] : $bars);
			$description = $descriptions[$bars - 1];

			for($i = 0; $i < $bars; $i++)
				$rep_bars .= '<img src="' . $settings['images_url'] . '/karma_good_' . ($i < ($modSettings['karmaSuperBar'] - 1) ? 'basic' : 'super') . '.gif" title="' . $row['real_name'] . ' ' . $description . '" alt="' . $row['real_name'] . ' ' . $description . '" />';

			$context['reputation_best'][] = array(
				'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>',
				'reputation_bars' => $rep_bars,
				'amount' => '+' . $row['karma'],
			);
		}

		$smcFunc['db_free_result']($result);

		$result = $smcFunc['db_query']('', '
			SELECT (karma_bad - karma_good) AS karma, id_member, real_name
			FROM {db_prefix}members
			WHERE karma_bad > karma_good
			ORDER BY karma DESC
			LIMIT 10',
			array()
		);

		while($row = $smcFunc['db_fetch_assoc']($result))
		{
			$rep_bars = '';

			$points = $row['karma'];
			$bars = ($points - ($points % $modSettings['karmaBarPoints'])) / $modSettings['karmaBarPoints'];
			$bars = $bars < 1 ? 1 : (($bars > $modSettings['karmaMaxBars']) ? $modSettings['karmaMaxBars'] : $bars);

			for($i = 0; $i < $bars; $i++)
				$rep_bars .= '<img src="' . $settings['images_url'] . '/karma_bad_' . ($i < ($modSettings['karmaSuperBar'] - 1) ? 'basic' : 'super') . '.gif" title="' . $row['real_name'] . ' ' . $modSettings['karmaNegativeDescription'] . '" alt="' . $row['real_name'] . ' ' . $modSettings['karmaNegativeDescription'] . '" />';

			$context['reputation_worst'][] = array(
				'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>',
				'reputation_bars' => $rep_bars,
				'amount' => '-' . $row['karma'],
			);
		}

		$smcFunc['db_free_result']($result);
	}
]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Subs-Members.php">
		<operation>
			<search position="before"><![CDATA[
		'openid_uri' => (!empty($regOptions['openid']) ? $regOptions['openid'] : ''),]]></search>
			<add><![CDATA[
		'karma_good' => ($modSettings['karmaRegistration'] > 0) ? $modSettings['karmaRegistration'] : 0,
		'karma_bad' => 0,]]></add>
		</operation>
	</file>

	<file name="$sourcedir/Xml.php">
		<operation>
			<search position="before"><![CDATA[
		'messageicons' => array(
			'function' => 'ListMessageIcons',
		),]]></search>
			<add><![CDATA[
		'reputation' => array(
			'function' => 'Reputation',
		),]]></add>
		</operation>

		<operation>
			<search position="end" />
			<add><![CDATA[
// Pfft, reloading is for old people!
function Reputation()
{
	global $context, $modSettings, $txt, $user_info, $smcFunc;

	// If the mod is disabled, show an error.
	if (empty($modSettings['karmaMode']))
		fatal_lang_error('feature_disabled', true);

	// If you're a guest or can't do this, blow you off...
	is_not_guest();
	isAllowedTo('karma_edit');

	checkSession('request');

	loadLanguage('Errors');

	// We're gonna do things in a different order here, to facilitate errors.
	$uid = (int) $_POST['uid'];
	$message_id = (int) $_POST['m'];
	$topic_id = (int) $_POST['topic'];
	$points = $user_info['karma_good'] - $user_info['karma_bad'];
	$power = ($points - ($points % $modSettings['karmaBarPower'])) / $modSettings['karmaBarPower'];
	$power = (int) (($power > 0) ? $power : 0);
	$comment = (strlen($_POST['reputation_comment']) > 300) ? substr($_POST['reputation_comment'], 0, 300) : $_POST['reputation_comment'];
	$yesterday = time() - 86400;
	$longtimeago = time() - (60 * 60 * ($modSettings['karmaWaitTime']));
	$hoursAgo = ($modSettings['karmaWaitTime'] < 24) ? $yesterday : $longtimeago;
	$context['error_txt'] = '';

	// If you don't have enough posts, tough luck.
	if ($user_info['posts'] < $modSettings['karmaMinPosts'])
		$context['error_txt'] .= "\n" . sprintf($txt['not_enough_posts_karma'], $modSettings['karmaMinPosts']);

	// And you can't modify your own, punk! (use the profile if you need to, admins!)
	else if (empty($uid) || $uid == $user_info['id'])
		$context['error_txt'] .= "\n" . $txt['cant_change_own_karma'];
	
	// I fart in your general direction!
	else if (strtolower($comment) == 'your mother was a hamster and your father smelt of elderberries!')
		$context['error_txt'] .= "\n...and Saint Attila raised the hand grenade up on high, saying, \"O Lord, bless this Thy hand grenade that with it Thou mayest blow Thine enemies to tiny bits, in Thy mercy.\" And the Lord did grin and the people did feast upon the lambs and sloths and carp and anchovies and orangutans and breakfast cereals, and fruit bats and large chu... *ahem* And the Lord spake, saying, \"First shalt thou take out the Holy Pin, then shalt thou count to three, no more, no less. Three shall be the number thou shalt count, and the number of the counting shall be three. Four shalt thou not count, neither count thou two, excepting that thou then proceed to three. Five is right out. Once the number three, being the third number, be reached, then lobbest thou thy Holy Hand Grenade of Antioch towards thy foe, who being naughty in my sight, shall snuff it.\" Amen.";

	// Applauding or smiting? Don't try to do a cheap javascript injection on me...
	switch ($_POST['type'])
	{
		case 'agree':
			if(!allowedTo('positive_karma'))
				$context['error_txt'] .= "\n" . $txt['karma_cant_agree'];
			$karma_which = 'karma_good';
			break;
		case 'disagree':
			if(!allowedTo('negative_karma'))
				$context['error_txt'] .= "\n" . $txt['karma_cant_disagree'];
			$karma_which = 'karma_bad';
			break;
		default:
			// Should never get here
			$context['error_txt'] .= "\n" . $txt['karma_choose_action'];
	}

	// Going in order of permissions... it only gets added if it passes all of the tests!

	// Used up all of their $modSettings['karmaMaxPerDay'] ?
	if (!empty($modSettings['karmaMaxPerDay']) && ($modSettings['karmaMaxPerDay'] > 0))
	{
		// Find out if this user has done this in the past 24 hours.
		$request = $smcFunc['db_query']('', '
			SELECT log_time
			FROM {db_prefix}log_karma
			WHERE id_executor = {int:current_member}
				AND log_time >= {int:yesterday}
			LIMIT 1',
			array(
				'current_member' => $user_info['id'],
				'yesterday' => $hoursAgo,
			)
		);

		if ($smcFunc['db_num_rows']($request) >= $modSettings['karmaMaxPerDay'])
			$context['error_txt'] .= "\n" . sprintf($txt['karma_maxed_out'], $modSettings['karmaMaxPerDay']);

		$smcFunc['db_free_result']($request);
	}

	// Haven't waited long enough?
	if (!empty($modSettings['karmaWaitTime']) && (!empty($modSettings['karmaTimeRestrictAdmins']) || !allowedTo('moderate_forum')) && $modSettings['karmaWaitTime'] > 0)
	{
		// Find out if this user has done this in the past $longenough.
		$request = $smcFunc['db_query']('', '
			SELECT log_time
			FROM {db_prefix}log_karma
			WHERE id_executor = {int:current_member}
				AND log_time >= {int:waittime}
			LIMIT 1',
			array(
				'current_member' => $user_info['id'],
				'waittime' => $longtimeago,
			)
		);

		if ($smcFunc['db_num_rows']($request) > 0)
		{
			// Give them approximate minutes until they can, to be nice ;)
			list ($log_time) = $smcFunc['db_fetch_row']($request);
			$log_time_wait = ($log_time + (60 * 60 * $modSettings['karmaWaitTime'])) - time(); // seconds
			$log_time_wait = ($log_time_wait - ($log_time_wait % 60)) / 60; // minutes
			$context['error_txt'] .= "\n" . sprintf($txt['karma_please_wait'], $modSettings['karmaWaitTime'], $log_time_wait);
		}

		$smcFunc['db_free_result']($request);
	}

	// Need to spread it around a bit? No, not the flu, silly!
	if (!empty($modSettings['karmaSpreadAround']) && ($modSettings['karmaSpreadAround'] > 0))
	{
		// Grab the latest karmaSpreadAround actions - if the target is in there, throw an error!
		$request = $smcFunc['db_query']('', '
			SELECT id_target
			FROM {db_prefix}log_karma
			WHERE id_executor = {int:current_member}
			ORDER BY log_time DESC
			LIMIT {int:spread}',
			array(
				'current_member' => $user_info['id'],
				'spread' => $modSettings['karmaSpreadAround'],
			)
		);

		if ($smcFunc['db_num_rows']($request) > 0)
			while($row = $smcFunc['db_fetch_assoc']($request))
				if($row['id_target'] == $uid)
					$context['error_txt'] .= "\n" . $txt['karma_spread_around'];

		$smcFunc['db_free_result']($request);
	}

	// One last test - have they already sent rep to this particular post?
	$request = $smcFunc['db_query']('', '
		SELECT log_time
		FROM {db_prefix}log_karma
		WHERE id_executor = {int:executor}
			AND message = {string:message}
		LIMIT 1',
		array(
			'executor' => $user_info['id'],
			'message' => $message_id
		)
	);

	if($smcFunc['db_num_rows']($request) != 0)
		$context['error_txt'] .= "\n" . $txt['karma_sent_twice'];

	$smcFunc['db_free_result']($request);

	// Finally! Now do an update if there's no error
	if($context['error_txt'] == "")
	{
		$request = $smcFunc['db_query']('', '
			UPDATE {db_prefix}members
			SET {raw:which} = {raw:which} + {int:power}
			WHERE id_member = {int:uid}',
			array(
				'power' => $power,
				'uid' => $uid,
				'which' => $karma_which,
			)
		);

		if(!$request)
			$context['error_txt'] .= "\n" . $txt['karma_didnt_update'];

		$action_type = ($power != 0) ? $karma_which : 'karma_disabled';

		$request = $smcFunc['db_query']('', '
			SELECT subject
			FROM {db_prefix}messages
			WHERE id_msg = {int:id_message}
			LIMIT 1',
			array(
				'id_message' => $message_id,
			)
		);

		list ($title) = $smcFunc['db_fetch_row']($request);

		$smcFunc['db_free_result']($request);

		// Log this new action!
		$smcFunc['db_insert']('replace',
			'{db_prefix}log_karma',
			array('action' => 'int', 'id_target' => 'int', 'id_executor' => 'int', 'log_time' => 'int', 'comment' => 'string', 'action_type' => 'string', 'message' => 'int', 'topic' => 'int', 'title' => 'string'),
			array($power, $uid, $user_info['id'], time(), $comment, $action_type, $message_id, $topic_id, $title),
			array('id_target', 'id_executor')
		);
	}

	$context['sub_template'] = 'reputation';
}
]]></add>
		</operation>
	</file>

</modification>
