// TO DO needs error handling
HEARST.comments = function() {

	// TODO Get requirement structure established
	if (HEARST.require('user', 'utils') === false) return;

	// TODO Requests and responses should go into array(s) so that they can be back-referenced. _request should maybe be a constructor
	var _request = {
			api: {
				articleID: (HEARST.site.article && HEARST.site.article.id) || '',
				articleTypePrefix: (HEARST.site.article && HEARST.site.article.type.prefix) || '',
				commentID: '',
				commentTitle: '',
				commentText: '',
				email: HEARST.user && HEARST.user.email,
				origin: '',
				page: 1,
				perPage: 10,
				userName: ''
			},
			data: {},
			dataType: 'json',
			error: [],
			success: [],
			url: ''
		},
		_response = {
			list: [],
			count: 0
		},
		_lastRequest = HEARST.utils.beget(_request),
		_init = false,
		_apiPath = (HEARST.user.logged_in) ? '/api/js/' : '/api_static/js/' ;

	// Updates any missing properties in 'current' with those of '_request' -- TO DO this can be done differently
	function update(current, old) {
		var i,
			old = old || _request;
		for (i in old) {
			if (typeof current[i] === typeof old[i]) {
				if (typeof current[i] === 'object') {
					update(current[i], old[i]);
				} else {
					current[i] = current[i] || old[i];
				}
			} else if (current[i] && old[i] instanceof Array) {
				current[i] = [].concat(current[i]);
			} else {
				current[i] = old[i];
			}
		}

		return current;
	}

	// Wraps an array of callbacks into a function
	function enqueue(a) {
		var i;
		return function(data) {
			for (i=0; i<a.length; i++) {
				a[i](data);
			}
		};
	}

	function request(req, type) {
		var api = req.api;

		req = update(req);
		req.type = type;

		switch (req.type + api.call) {
			case 'GETsingle':
				req.url = req.url || _apiPath + 'Comment/' + api.commentID;
				break;
			case 'GETmultiple':
				// If paging info is provided then concatenate it onto url. Else just add the article ID
				(!!api.page && !!api.perPage)
					? req.url = _apiPath + 'CommentsByArticle/' + [api.articleID, api.page, api.perPage].join('_')
					: req.url = _apiPath + 'CommentsByArticle/' + api.articleID;
				req.success.splice(0, 0, function(data) {
					_response.list = data;
				});
				break;
			case 'GETcount':
				req.url = _apiPath + 'CommentsByArticle/' + api.articleID + '_count';
				req.success.splice(0, 0, function(data) {
					_response.count = Number(data.count);
				});
				break;
			case 'POSTcomment':
				req.url = _apiPath + 'Comment/';
				req.dataType = 'text';
				req.data = {
					article_id: api.articleID,
					comment_title: api.commentTitle,
					comment_text: api.commentText,
					per_page: api.perPage,
					email: api.email,
					origin: 'comments'
				};
				req.success.splice(0, 0, function(data) {
					
					
				});
				break;
			default:
				return false;
		}

		req.error = enqueue(req.error);
		req.success = enqueue(req.success);

		if (type === 'GET' && HEARST.user.logged_in) {
			req.data.cachebust = HEARST.utils.cacheBust();
		}

		if (HEARST.utils.getQueryVariable('ha')) {
			req.data.ha = 1;
		}

		_lastRequest = req;

		return $.ajax(req);
	}

	// Initialize this object
	if (HEARST.site.article) {
		request({
			api: {
				call: 'multiple'
			}
		}, 'GET');
		request({
			api: {
				call: 'count'
			},
			success: function(data) {
				var test = 'new';
			}
		}, 'GET');
	}

	return {
		count: function() {
			return _response.count;
		},

		get: function(req) {
			var req = req || _request,
				type = 'GET';
			return request(req, type);
		},

		list: function() {
			return _response.list;
		},

		page: function(n) {
			if (typeof n === 'number') {
				_request.api.page = n;
				return _request.api.page;
			} else {
				return _lastRequest.api.page;
			}
		},

		perPage: function(n) {
			if (typeof n === 'number') {
				_request.api.perPage = n;
				return _request.api.perPage;
			} else {
				return _lastRequest.api.perPage;
			}
		},

		post: function(req) {
			var req = req || _request,
				type = 'POST';
			if (HEARST.user.logged_in) {
				return request(req, type);
			} else {
				return false;
			}
		},

		report: function(commentID) {
			var url = (mag_user && mag_user.logged_in) ? '/comments/report-this' + document.location.pathname : '/comments_report_abuse_login/',
				name = 'reportWindow',
				parameters = 'width=490,height=400,scrollbars=no,menubar=no,location=no,toolbar=no,chrome=yes,centerscreen=yes,status=no,dependent=no';

			url += '?comment_id=' + commentID + '&purl=' + document.location.pathname;

			HEARST.utils.windowOpen(url, name, parameters);
		}
	}
}( );

// INIT/RENDER COMMENTS - TO DO needs reworking
(function() {
	var nextURL = HEARST.utils.getQueryVariable('next_url') || HEARST.site.urlPath,
		loginStateClass = (HEARST.user.logged_in) ? 'logged_in' : 'not_logged_in',
		HTML = {
			comment: '\
				<li id="cid_{{ comment_id }}" comment_id="{{ comment_id }}" class="comment">\n\
					<h6>{{ comment_title }}</h6>\n\
					<div class="time">{{ post_time }}</div>\n\
					<div class="date">{{ post_date }}</div>\n\
					<div class="posted">Posted by: <span>{{ user_name }}</span></div>\n\
					<div class="abuse"><a href="javascript: void (HEARST.comments.report({{ comment_id }}))">Report Abuse</a></div>\n\
					<p>{{ comment_text }}</p>\n\
				</li>\n',
	
			commentPostForm: '\
				<div id="post_comment" class="r2_gLGR">\n\
					<div class="cbt"><div class="cbl"></div><div class="cbr"></div></div>\n\
					<div class="cbc">\n\
						<h6 class="two_face with_rule"><em>post a</em><strong>comment</strong></h6>\n\
						<form class="post_comment_form" method="post" action="">\n\
							<div class="user field">\n\
								<label for="comment_user">User:</label>\n\
								<input id="comment_user" readonly="readonly" value="{{ comment_user_name }}" />\n\
								<a href="/registration/?next_url=' + nextURL + '" class="edit_profile">Edit Profile</a>\n\
								<a href="/registration/logout/?next_url=' + nextURL + '">Log Out</a>\n\
							</div>\n\
							<div class="subject field">\n\
								<label for="comment_subject">Subject:</label>\n\
								<input id="comment_subject" class="text" type="text" />\n\
							</div>\n\
							<div class="comment field">\n\
								<label for="comment_text">Comment:</label>\n\
								<textarea id="comment_text" class="text" rows="4"></textarea>\n\
							</div>\n\
							<div class="characters"><span>{{ comment_chars_remaining }}</span> Characters left</div>\n\
							<div class="button">\n\
								<input type="submit" class="submit" value="Post Comment" />\n\
							</div>\n\
						</form>\n\
						<div class="clear"></div>\n\
					</div>\n\
					<div class="cbb"><div class="cbl"></div><div class="cbr"></div></div>\n\
				</div>\n',
	
			commentLoginForm: '\
				<div id="post_comment" class="r2_gLGR">\n\
					<div class="cbt"><div class="cbl"></div><div class="cbr"></div></div>\n\
					<div class="cbc">\n\
						<h6 class="two_face with_rule"><em>post a</em><strong>comment</strong></h6>\n\
						<p>You must be registered on ' + HEARST.site.prefix + '.com to post comments.<br />If you don\'t have an account, <a href="/registration/?next_url=' + nextURL + '">join now for free</a>.</p>\n\
						<form name="login" id="login" action="/registration/login?next_url=' + nextURL + '" method="post">\n\
							<img id="ur_track_img" src="' + HEARST.site.trackImage + '" style="display:none" />\n\
							<input type="hidden" name="login" value="1" />\n\
							<input type="hidden" name="remember_me" value="1" />\n\
							<label class="required" for="user_name">Username or email:</label>\n\
							<input name="user_name" id="user_name" type="text" class="text" value="" />\n\
							<label class="required" for="password">Password:</label>\n\
							<input name="password" id="password" type="password" class="password" />\n\
							<p class="forgot_password">Click <a href="/registration/forgotPassword.html?next_url=' + nextURL + '">here</a> if you forgot your username or password.</p>\n\
							<div class="button">\n\
								<input type="submit" class="submit" value="Sign in" />\n\
							</div>\n\
						</form>\n\
						<div class="clear"></div>\n\
					</div>\n\
					<div class="cbb"><div class="cbl"></div><div class="cbr"></div></div>\n\
				</div>\n',
	
			commentWrapper: '\
				<div id="comments" class="' + loginStateClass + '">\n\
					<div class="comment_info">\n\
						<div class="heading">\n\
							<span class="count">{{ comment_count }}</span>\n\
							<a href="#post_comment">Post a comment</a>\n\
						</div>\n\
						<span class="pages">{{ comment_pagination }}</span>\n\
						<div class="clear"></div>\n\
					</div>\n\
					<ul>{{ comment_list }}</ul>\n\
					<div class="comment_info">\n\
						<div class="pages">{{ comment_pagination }}</div>\n\
						<div class="clear"></div>\n\
					</div>\n\
					{{ comment_form }}\n\
				</div>\n'
		};

	function render($o) {
		var $commentsContainer = $('#comments'),
			thisID = '#' + $o.attr('id');
		
		if ($commentsContainer.is(thisID)) {
			$commentsContainer.replaceWith($o);
		} else {
			$commentsContainer.find(thisID).replaceWith($o);
		}
	}

	function writeComment(o) {
		var comment = HTML.comment || '';

		o.comment_title = o.comment_title || '(no subject)';
		return comment.templateReplace(o);
	}

	function writeCommentList() {
		var i, j,
			list = list || HEARST.comments.list(),
			commentList = '';
	
		for (i=0; i<list.length; i++) {
			commentList += writeComment(list[i]);
		}
	
		return commentList;
	}

	function writePagination() {
		var count = HEARST.comments.count(),
			limit = HEARST.comments.perPage(),
			currentPage = HEARST.comments.page(),
			totalPages = Math.ceil(count/limit),
			page,
			commentPagination = '';
	
		if (totalPages > 1) {
			commentPagination += 'Page';
			for (page = 1; page <= totalPages; page += 1) {
				if (page === currentPage) {
					commentPagination += '<span>' + page + '</span>';
				} else {
					commentPagination += '<a page="' + page + '">' + page + '</a>';
				}
			}
		}
	
		return commentPagination;
	}
	
	function writeCommentForm() {
		var commentForm = '',
			commentPost = HTML.commentPostForm || '',
			commentLogin = HTML.commentLoginForm || '',
			characterLimit = 1700;
	
		if (HEARST.user.logged_in) {
			commentForm = commentPost.templateReplace({
				comment_user_name: HEARST.user.user_name,
				comment_chars_remaining: characterLimit
			});
		} else {
			commentForm = commentLogin;
		}
	
		return commentForm;
	}

	function getNewComment(data) {
		var req = { 
				api: { call: 'single' },
				url: data,
				success: addNewComment
			};

		function addNewComment(data) {
			var $commentsContainer = $('#comments'),
				$commentsList = $commentsContainer.find('ul'),
				off = $commentsContainer.offset(),
				$newComment = $(writeComment(data)),
				// For the sake of animate we hide the new comment, insert it into the document context and record its height. We'll remove it soon.
				newCommentHeight = $newComment.prependTo($commentsList).height();

			scrollTo(off.left, off.top - 20);

			$newComment
				.height(0)
				.css('opacity', 0)
				.prependTo($commentsList)
				.animate({ height: newCommentHeight, opacity: 1 });
		}

		HEARST.comments.get(req);
	}

	function attachEvents(html) {
		var $jq = $(html);

		function pageEvents($o) {
			var $pages = $o.find('a[page]');

			$pages
				.each(function(j) {
					$(this).click(function(e) {
						var req = {
							api: {
								call: 'multiple',
								page: Number($(e.target).attr('page'))
							},
							success: initComments
						}

						$pages
							.unbind('click')
							.css('cursor','default');

						HEARST.comments.get(req);
					});
			   });
		}
	
		function listEvents($o) {
			$o.find('.comment')
				.each(function(j) {
					var commentID = $(this).attr('comment_id');
					$(this).find('.abuse a').click(function(e) {
						HEARST.comments.report(commentID);
					});
			   });
		}

		// TO DO needs error handling
		function postFormEvents($o) {
			$o.submit(function(e){
				var req = {
					api: {
						call: 'comment',
						userName: $('#comment_user').attr('value'),
						commentTitle: $('#comment_subject').attr('value'),
						commentText: $('#comment_text').attr('value'),
						email: HEARST.user.email
					},
					success: getNewComment
				}

				$(this)
					.addClass(e.type)
					.find(':enabled').attr('disabled','disabled').end()					
					.find('.button').animate({opacity:0.5});
				
				HEARST.comments.post(req);
				return false;
			})
			.find('#comment_text')
				.focus(function(){
					var charsLeft,
						$charLimit = $('#post_comment .characters span');
					$(this).bind('keyup.characters',function() {
						charsLeft = 1700 - $(this).attr('value').length;
						if (this.offsetHeight < this.scrollHeight) {
							$(this).height(this.scrollHeight);
						}
						$charLimit.text(charsLeft);
					});
				})
				.blur(function(){
					$(this).unbind('keyup.characters');
				})
	
		}

		if ($jq.is(':has([page])')) pageEvents($jq);
		if ($jq.is(':has(.comment)')) listEvents($jq);
		if ($jq.is(':has(form.post_comment_form)')) postFormEvents($jq);

		render($jq);
	}

	function initComments() {
		var count = HEARST.comments.count(),
			countDisplay = (count || 'No') + ' Comment' + ((count !== 1) ? 's' : ''),
			commentWrapper = HTML.commentWrapper || '',
			commentForm = writeCommentForm(),
			commentPagination = writePagination(),
			commentList = writeCommentList();
	
		commentWrapper = commentWrapper.templateReplace({
			comment_count: countDisplay,
			comment_pagination: commentPagination,
			comment_list: commentList,
			comment_form: commentForm
		});
	
		attachEvents(commentWrapper);
	}

	$(initComments);

})( );
// /INIT/RENDER COMMENTS