function quote_process_reactions(data, status) {
	if(status != 'success')
		return;
	if(data.need_login) {
		if(data.post_login)
			quotes_start_login(null, data.target, data.reason, function() {
		    	$.getJSON(data.post_login, quote_process_reactions);
			});
		else
			quotes_start_login(null, data.target, data.reason);
		return false;
	}
    $('#error').remove();
    $('#hint').remove();
	if(data.error) {
        $('#voting').append('<div id="error">' + data.error + '</div>');
		return;
	}
	$('#quote_vote_up_count_world_value').text(data.up > 0 ? '+' + data.up : data.up);
	$('#quote_vote_up_count_world').attr('title', 'This quote has received ' + data.up_word + ' ' + (data.up == 1 ? 'vote' : 'votes') + ' worth of positive reactions.');
	$('#quote_vote_down_count_world_value').text(data.down);
	$('#quote_vote_down_count_world').attr('title', 'This quote has received ' + data.down_word + ' ' + (data.down == -1 ? 'vote' : 'votes') + ' worth of negative reactions.');
	if(data.user_reaction == 0) {
		$('#quote_vote_up_icon').rollover_low();
		$('#quote_vote_up_icon').rollover();
		$('#quote_vote_down_icon').rollover_low();
		$('#quote_vote_down_icon').rollover();
		$('#quote_vote_up_count_world_label').hide();
		$('#quote_vote_down_count_world_label').hide();
		$('#quote_vote_up_count_self').attr('title', 'You have not voted for this quote.');
		$('#quote_vote_up_count_self').hide();
		$('#quote_vote_down_count_self').attr('title', 'You have not voted against this quote.');
		$('#quote_vote_down_count_self').hide();
	} else if(data.user_reaction > 0) {
		$('#quote_vote_up_icon').rollover_high();
		$('#quote_vote_up_icon').removeClass('rollover');
		$('#quote_vote_down_icon').rollover_low();
		$('#quote_vote_down_icon').rollover();
		$('#quote_vote_up_count_self_value').text('+' + data.user_reaction);
		$('#quote_vote_up_count_self').attr('title', 'You have voted for this quote ' + data.user_reaction_word + ' ' + (data.user_reaction == 1 ? 'time' : 'times') + '.');
		$('#quote_vote_up_count_self').show();
		$('#quote_vote_up_count_world_label').show();
		$('#quote_vote_down_count_world_label').hide();
		$('#quote_vote_down_count_self').hide();
		$('#quote_vote_down_count_self').attr('title', 'You have not voted against this quote.');
	} else {
		$('#quote_vote_up_icon').rollover_low();
		$('#quote_vote_up_icon').rollover();
		$('#quote_vote_down_icon').rollover_high();
		$('#quote_vote_down_icon').removeClass('rollover');
		$('#quote_vote_up_count_world_label').hide();
		$('#quote_vote_up_count_self').hide();
		$('#quote_vote_up_count_self').attr('title', 'You have not voted for this quote.');
		$('#quote_vote_down_count_self_value').text(data.user_reaction);
		$('#quote_vote_down_count_self').attr('title', 'You have voted against this quote ' + data.user_reaction_word + ' ' + (data.user_reaction == -1 ? 'time' : 'times') + '.');
		$('#quote_vote_down_count_self').show();
		$('#quote_vote_down_count_world_label').show();
	}
    if(data.hint)
        $('#voting').append('<div id="hint">' + data.hint + '</div>');
}

function quote_tag_process(data, status) {
	if(status != 'success')
		return;
	if(data.need_login) {
		if(data.post_login)
			quotes_start_login(null, data.target, data.reason, function() {
		    	$.getJSON(data.post_login, quote_tag_process);
			});
		else
			quotes_start_login(null, data.target, data.reason);
		return false;
	}
    $('#error').remove();
    $('#hint').remove();
	if(data.error) {
        $('#tags').append('<div id="error">' + data.error + '</div>');
		return;
	}
    var tag = $('#quote_tag_' + data.id);
	var count = tag.find('.voting .count');
    var explain = 'This tag has';
    if(data.up)
        explain += ' been voted appropriate to this quote ' + data.up_word + ' ' + (data.up == 1 ? 'time' : 'times');
    else
        explain += ' not been voted appropriate to this quote';
    explain += ' and has';
    if(data.down)
        explain += ' been voted inappropriate ' + data.down_word + ' ' + (data.down == -1 ? 'time' : 'times');
    else
        explain += ' not been voted inappropriate';
	tag.attr('quote_tag_user_reaction', data.user_reaction);
	if(data.user_reaction == 0) {
        explain += '.  You have not voted on it';
		tag.find('.voting .up .icon').rollover_low();
		tag.find('.voting .up .icon').rollover();
		tag.find('.voting .down .icon').rollover_low();
		tag.find('.voting .down .icon').rollover();
		tag.find('.voting .up').show();
		tag.find('.voting .down').show();
	} else if(data.user_reaction > 0) {
        explain += '.  You have voted it appropriate';
		tag.find('.voting .up .icon').rollover_high();
		tag.find('.voting .up .icon').removeClass('rollover');
		tag.find('.voting .up').show();
		tag.find('.voting .down').hide();
	} else {
        explain += '.  You having voted it inappropriate';
		tag.find('.voting .down .icon').rollover_high();
		tag.find('.voting .down .icon').removeClass('rollover');
		tag.find('.voting .up').hide();
		tag.find('.voting .down').show();
	}
    explain += '.';
    var balance = parseInt(data.up) + parseInt(data.down);
	count.text(balance > 0 ? '+' + balance : balance);
	count.attr('title', explain);
    if(data.hint)
        $('#tags').append('<div id="hint">' + data.hint + '</div>');
}

function quote_attribution_process(data, status) {
	if(status != 'success')
		return false;
	if(data.need_login) {
		if(data.post_login)
			quotes_start_login(null, data.target, data.reason, function() {
		    	$.getJSON(data.post_login, quote_attribution_process);
			});
		else
			quotes_start_login(null, data.target, data.reason);
		return false;
	}
	$('#error').remove();
	$('#hint').remove();
	if(data.error) {
		$('.attributions .editing .controls').after('<div id="error" style="margin-top: 5px">' + data.error + '</div>');
		return false;
	}
	var attribution = $('#quote_attribution_' + data.id);
    if(attribution.length) {
        attribution.find('.content').html(data.content);
    } else {
        attribution = $(document.createElement('div'));
        attribution.attr('id', 'quote_attribution_' + data.id);
        attribution.attr('quote_attribution_id', data.id);
        attribution.attr('quote_attribution_user_reaction', data.user_reaction);
        attribution.addClass('attribution');
        var hr = document.createElement('hr');
        $(hr).attr('width', '98%');
        if(!$('.attributions hr').length)
            $(hr).attr('display: none');
        attribution.append(hr);
        var voting = document.createElement('div');
        $(voting).addClass('voting');
        var edit = document.createElement('edit');
        $(edit).addClass('edit');
        $(edit).text('edit');
        $(edit).attr('title', 'Edit this attribution');
        $(edit).attribution_edit();
        $(voting).append(edit);
        var del = document.createElement('delete');
        $(del).addClass('delete');
        $(del).text('delete');
        $(del).attr('title', 'Delete this attribution');
        $(del).attribution_delete();
        $(voting).append(del);
        var up = document.createElement('span');
        $(up).addClass('up');
        var up_img = document.createElement('img');
        $(up_img).addClass('icon');
        $(up_img).addClass('rollover');
        $(up_img).attr('width', 16);
        $(up_img).attr('height', 16);
        $(up_img).attr('alt', 'Up');
        $(up_img).attr('src', url_prefix + '/images/thumbsup_16x16_low.png');
        $(up).append(up_img);
        $(voting).append(up);
        var count = document.createElement('span');
        $(count).addClass('count');
        $(voting).append(count);
        var down = document.createElement('span');
        $(down).addClass('down');
        var down_img = document.createElement('img');
        $(down_img).addClass('icon');
        $(down_img).addClass('rollover');
        $(down_img).attr('width', 16);
        $(down_img).attr('height', 16);
        $(down_img).attr('alt', 'Down');
        $(down_img).attr('src', url_prefix + '/images/thumbsdown_16x16_low.png');
        $(down).append(down_img);
        $(voting).append(down);
        attribution.append(voting);
        var source = document.createElement('div');
        $(source).addClass('source');
        $(source).text('submitted by ' + data.source_identify + ', ' + data.source_date);
        attribution.append(source);
        var content = document.createElement('div');
        $(content).addClass('content');
        $(content).html(data.content);
        attribution.append(content);
        attribution.hide();
        var label = $('.attributions .label');
        label.after(attribution);
        if(label.text() == 'Attribution:')
            label.text('Attributions:');
        else if(label.text() == 'Attributions: None')
            label.text('Attribution:');
        attribution.show('slow');
    }
    attribution.attr('quote_attribution_source', encodeURIComponent(data.source));
	var explain = 'This attribution has';
	if(data.up)
		explain += ' been voted up ' + data.up_word + ' ' + (data.up == 1 ? 'time' : 'times');
	else
		explain += ' not been voted up';
	explain += ' and has';
	if(data.down)
		explain += ' been voted down ' + data.down_word + ' ' + (data.down == -1 ? 'time' : 'times');
	else
		explain += ' not been voted down';
	attribution.attr('quote_attribution_user_reaction', data.user_reaction);
	if(data.user_reaction == 0) {
		explain += '.  You have not voted on it';
		attribution.find('.voting .up .icon').rollover_low();
		attribution.find('.voting .up .icon').rollover();
		attribution.find('.voting .up .icon').attr('title', 'Vote this attribution up');
		attribution.find('.voting .down .icon').rollover_low();
		attribution.find('.voting .down .icon').rollover();
		attribution.find('.voting .down .icon').attr('title', 'Vote this attribution down');
		attribution.find('.voting .up').show();
		attribution.find('.voting .down').show();
	} else if(data.user_reaction > 0) {
		explain += '.  You have voted it up';
		attribution.find('.voting .up .icon').rollover_high();
		attribution.find('.voting .up .icon').removeClass('rollover');
		attribution.find('.voting .up .icon').attr('title', 'You have voted this attribution up; click to cancel');
		attribution.find('.voting .up').show();
		attribution.find('.voting .down').hide();
	} else {
		explain += '.  You having voted it down';
		attribution.find('.voting .down .icon').rollover_high();
		attribution.find('.voting .down .icon').removeClass('rollover');
		attribution.find('.voting .down .icon').attr('title', 'You have voted this attribution down; click to cancel');
		attribution.find('.voting .up').hide();
		attribution.find('.voting .down').show();
	}
	explain += '.';
    var balance = parseInt(data.up) + parseInt(data.down);
	var count = attribution.find('.voting .count');
	count.text(balance > 0 ? '+' + balance : balance);
	count.attr('title', explain);
	if(data.hint)
		$('#attributions').append('<div id="hint">' + data.hint + '</div>');
    return true;
}

function quote_attribution_add(where) {
	var attributions = $(where).parents('.attributions');
	var quote_id = attributions.attr('quote_id');
	var add = document.createElement('div');
	$(add).addClass('editing');
	$(add).css('visibility', 'hidden');
	$(where).parent().find('.label').after(add);
	var wmd = wmd_create(function(element) {
		$(add).append(element);
	});
	add.editor = wmd;
	$(wmd.textarea).after(wmd.preview);
	var ctl = document.createElement('div');
	$(ctl).addClass('controls');
	var submit = document.createElement('input');
	$(submit).attr('type', 'button');
	$(submit).addClass('control');
	$(submit).addClass('submit');
	$(submit).attr('value', 'submit attribution');
	$(submit).click(function() {
		var text = $(add.editor.textarea).val();
		if(!text) {
			add.editor.textarea.focus();
			return;
		}
		var html = $(add.editor.preview).html();
		$.ajax({
			url: url_prefix + '/connectors/quote_attribution_add',
			type: 'POST',
			dataType: 'json',
			data: {
				id: quote_id,
				text: text,
				html: html
			},
			success: function(data, status) {
				var res = quote_attribution_process(data, status);
				if(res) {
					$(add).hide('normal', function() {
						wmd_remove(add.editor);
						$(ctl).remove();
					});
					$('.attributions .add').show('normal');
					var hrs = $('.attributions hr');
					if(hrs.length == 1)
						hrs.hide();
				}
			}
		});
	});
	$(ctl).append(submit);
	var cancel = document.createElement('input');
	$(cancel).attr('type', 'button');
	$(cancel).addClass('control');
	$(cancel).addClass('cancel');
	$(cancel).attr('value', 'cancel');
	$(cancel).click(function() {
		$(add).hide('normal', function() {
			wmd_remove(add.editor);
			$(ctl).remove();
		});
		$('.attributions .add').show('normal');
		var hrs = $('.attributions hr');
		if(hrs.length == 1)
			hrs.hide();
	});
	$(ctl).append(cancel);
	$(wmd.preview).after(ctl);
	$(where).hide('normal');
	$(add).hide();
	$(add).css('visibility', 'visible');
	$(add).show('fast', function() {
		wmd.textarea.focus();
	});
	$('.attributions hr:first').show();
	return false;
}

(function($) {

    $.fn.attribution_add = function() {
		$(this).click(function(ev) {
			if(quotes_login != null)
				return quote_attribution_add(this);
			var where = this;
			$.getJSON(url_prefix + '/connectors/check_login', function(data, status) {
				if(data.login) {
					quotes_login = data.email;
					quote_attribution_add(where);
				} else {
					quotes_start_login(null, quotes_target, 4, function() {
						quote_attribution_add(where);
					});
				}
			});
			return false;
		});
	};

    $.fn.attribution_delete = function() {
		$(this).click(function() {
			var attribution = $(this).parents('.attribution');
            var res = confirm('Are you sure you want to delete this attribution?');
            if(!res)
                return;
            $(this).hide('slow');
			var quote_attribution_id = attribution.attr('quote_attribution_id');
            $.getJSON(url_prefix + '/connectors/quote_attribution_delete', { id: quote_attribution_id }, function(data, status) {
            	if(data.id == quote_attribution_id) {
                	attribution.hide('slow');
                	attribution.remove();
				}
            });
		});
	};

    $.fn.attribution_edit = function() {
		$(this).click(function() {
			var attribution = $(this).parents('.attribution');
			attribution.find('.content').hide('fast');
			var quote_attribution_id = attribution.attr('quote_attribution_id');
			var quote_attribution_source = decodeURIComponent(attribution.attr('quote_attribution_source'));
			var edit = document.createElement('div');
			$(edit).addClass('editing');
			$(edit).css('visibility', 'hidden');
			attribution.append(edit);
			var wmd = wmd_create(function(element) {
				$(edit).append(element);
			});
			attribution[0].editor = wmd;
			$(wmd.textarea).val(quote_attribution_source);
			$(wmd.textarea).after(wmd.preview);
			var ctl = document.createElement('div');
			$(ctl).addClass('controls');
			var submit = document.createElement('input');
			$(submit).attr('type', 'button');
			$(submit).addClass('control');
			$(submit).addClass('submit');
			$(submit).attr('value', 'revise attribution');
			$(submit).click(function() {
				var text = $(attribution[0].editor.textarea).val();
				if(!text) {
					attribution[0].editor.textarea.focus();
					return;
				}
				var html = $(attribution[0].editor.preview).html();
				$.ajax({
					url: url_prefix + '/connectors/quote_attribution_edit',
					type: 'POST',
					dataType: 'json',
					data: {
						id: quote_attribution_id,
						text: text,
						html: html
					},
					success: function(data, status) {
						var res = quote_attribution_process(data, status);
						if(res) {
							$(edit).hide('normal', function() {
								wmd_remove(attribution[0].editor);
								$(ctl).remove();
							});
							attribution.find('.edit').show('normal');
							attribution.find('.content').show('normal');
						}
					}
				});
			});
			$(ctl).append(submit);
			var cancel = document.createElement('input');
			$(cancel).attr('type', 'button');
			$(cancel).addClass('control');
			$(cancel).addClass('cancel');
			$(cancel).attr('value', 'cancel');
			$(cancel).click(function() {
				$(edit).hide('normal', function() {
					wmd_remove(attribution[0].editor);
					$(ctl).remove();
				});
				attribution.find('.edit').show('normal');
				attribution.find('.content').show('normal');
			});
			$(ctl).append(cancel);
			$(wmd.preview).after(ctl);
			$(this).hide('normal');
			$(edit).hide();
			$(edit).css('visibility', 'visible');
			$(edit).show('fast', function() {
				wmd.textarea.focus();
			});
		});
	};

})(jQuery);
