// Requires jQuery 1.4.
// Requires jquery-regex-selector plugin.

jQuery.fn.threaded_comments = function(options) {

	// Settings
	settings = jQuery.extend({
		collapsed_class: 'collapsed',
		thread_selector: '.replies',
		comment_selector: '.comment',
		comment_wrapper_selector: '.comment_content_wrapper',
		reply_link_selector: '.replylink',
		depth_limit: 2
	}, options);
	
	// If the browser is IE6 kill the script. Kill it dead!
	if (jQuery.browser.msie && jQuery.browser.version == '6.0') { return false; }

	add_collapse_link = function(comment) {
	  $(comment).find('.collapse_link').remove();
		var collapse_link = $('<a href="#" class="collapse_link button" title="Collapse this thread.">collapse</a>')
		collapse_link.bind('click', collapse_click);
		collapse_link.clone(true).prependTo($(comment));
	}

  // This collapses at the OL level.
	collapse_threads = function(threads) {
		threads.find(settings.comment_selector).each(function() {
	    collapse($(this));
    });
	} 
	
	// This is its own function rather than a part of collapse_click() because
	// When the page initially loads we call this to do the initial collapsing.
	collapse = function(comment) {
	  comment.each(function() {
  		// Mark as collapsed, yo!
  		$(this).addClass('.collapsed_thread')
  		$(this).find(settings.comment_wrapper_selector).first().addClass(settings.collapsed_class);

  		// Remove collapse thread link (if one, which there will not
  		// be initially).
  		$(this).find('.collapse_link').remove();

  		// Add click handler to the collapsed comment.
  		$(this).find('.comment_content_wrapper').bind('click', expand_click);	    
	  });
	}

	collapse_click = function(e) {

		// Don’t do anything unexpected.
		e.preventDefault();

		// Collapse this thread and its children threads.
		var parent = $(this).parent(settings.comment_selector)
		collapse(parent.find(settings.comment_selector).andSelf());
	}
	
	expand = function(comment) {
	  var comment = $(comment);
		comment.removeClass('.collapsed_thread')
		comment.find(settings.comment_wrapper_selector).first().removeClass(settings.collapsed_class);

		// Remove the click handler from the comment. Remember that we added
		// a handler to almost the entire comment. We want the user to be
		// able to interact with the comment now, so we must unbind.
		comment.find('.comment_content_wrapper').first().unbind('click', expand_click);

		// Add collapse thread link.
		add_collapse_link(comment);
	}

	expand_click = function(e) {

		// If they happend to click on a link, don’t follow it; just
		// expand the comment.
		e.preventDefault();

		var parent = $(this).parent(settings.comment_selector)
		return parent.find(settings.comment_selector).andSelf().each(function() {
      expand(this)
		});
	}

	reply_click = function(e) {

		// Wait! Don’t go anywhere …
		e.preventDefault();

		// … we’ll bring the form to you!
		var link = $(this);
		var comment = link.closest(settings.comment_selector);

		// But first remove any other reply forms.
		cancel_click(e);

		if (comment.data('form')) {
			// This block currently unused because the code that populates
			// comment.data('form') is currently commented out.
			prep_reply(comment.data('form'));
		}
		else {

			// Give the user some feedback if there is any latency.
			link.text('form loading…');
			comment.addClass('reply_form_loading');

			// AJAX!
			$.get(link.attr('href'), function(data) {
				var form = $(data);

				// Add a cancel button to the form.
				var cancel_link = $('<a href="#" class="cancel_link">cancel</a>');
				cancel_link.bind('click', cancel_click);
				form.find('.preview').append(' or ');
				form.find('.preview').append(cancel_link);

				prep_reply(form);

				// Remove our feedback bits.
				link.text('cancel reply');
				comment.removeClass('reply_form_loading');
			});
		}

		prep_reply = function(form) {
			link.closest('.comment_content_wrapper').after(form);

			// Switch the link to a cancel button.
			link.text('cancel reply');
			link.unbind('click', reply_click);
			link.bind('click', cancel_click);

			// Adjust width of the textarea.
			var textarea = form.find('textarea');
			var width = textarea.parent().width() - (textarea.outerWidth() - textarea.width());
			textarea.width(width);
		}
	}

	cancel_click = function(e) {

		e.preventDefault();

		$(settings.comment_selector + ' .comment_form_wrapper').each(function() {
			var form = $(this);
			var comment = form.closest(settings.comment_selector);
			var link = comment.find(settings.reply_link_selector).first();

			// Switch the from a cancel button back to a reply link.
			link.text('reply');
			link.unbind('click', cancel_click);
			link.bind('click', reply_click);

			// TODO: (pony) The idea here is to save the form that has been
			// loaded for the given comment. That saves us ajaxing again if
			// the user decides to reply, cancels, and then decides to reply
			// again. However, it is somehow causing problems. Let’s fix it.
			// comment.data('form', form);
			form.detach();			
		});
	}
	
	highlight = function(comment) {
	  $(settings.comment_selector).removeClass('highlighted_comment');
	  $(comment).addClass('highlighted_comment')
	}

	// For each comment list selected, thread it.
	return this.each(function() {

        var comment_list = $(this);

		// Collapse threads that need initial collapsing.
		// Create a selector like `.replies:regex(class,[2-9]+)'`.
		var threads_to_collapse = comment_list.find(settings.thread_selector + ':regex(class,[' + settings.depth_limit + '-9]+)');
		collapse_threads(threads_to_collapse);

		// Add collapse links to expanded threads.
		var expanded_threads = comment_list.find(settings.thread_selector).not(threads_to_collapse);
		expanded_threads.find(">" + settings.comment_selector).each(function() {
  		add_collapse_link(this);
		});

		// Ajaxify the reply form.
		comment_list.find(settings.reply_link_selector).bind('click', reply_click);
		
		$(settings.collapsed_class).hover(
		  function(){ $(this).addClass('collapsed_hover') },
		  function(){ $(this).removeClass('collapsed_hover') }
		  );
		
		// If this is a permalink to a comment make sure that comment is expanded and give it 
		// a class to highlight it
		if (document.location.hash) {
        expand($(document.location.hash));
        highlight($(document.location.hash));
    }
    
    // highlight any comment when you click the permalink
    $(settings.comment_selector + " .permalink").click(function(){
      highlight($(this).closest(settings.comment_selector));
    });
    
		
	});

}

