/*
 * comments.js
 *
 */
var Comment = (function($) {
  var c = {
    base_url: null,
    brand_name: null,
    section_name: null,
    board_name: null,
    board_url: null,
    board_resource_id: null,
	  _board_require_profile: null,
	  page_includes_form: null,
	  max_level: 3,

    /********************
    INITs
    *********************/
    init: function(options) {
      options = options || {};

      c.base_url = options["base_url"];
      c.brand_name = options["brand_name"];
      c.section_name = options["section_name"];
      c.board_name = encodeURIComponent(options["board_name"]);
      c.board_url = encodeURIComponent(options["board_url"]);
      c.board_resource_id = encodeURIComponent(options["board_resource_id"]);
      c.page_includes_form = $('#new_comment_form').length > 0;
      
      if(options.max_level) c.max_level = options.max_level;
      
      if(!c.page_includes_form){
        c.render_main_form();
      } else {
        c.init_form_behaviours();
      }
    },

    init_expand_replies_links: function() {
      $("#comments a.get.expand_replies_link").live("click", function() {
        var comment_id = $(this).parents(".comment").attr("id").split('_').last();
        c.render_children(comment_id);
        $(this).removeClass("get").addClass("toggle expanded");
        return false;
      });

      $("#comments a.toggle.expand_replies_link").live("click", function() {
        var comment_id = $(this).parents(".comment").attr("id").split('_').last();
        var replies = $("#comment_"+comment_id+" .replies:first");
        if(replies.is(":visible")) {
          replies.hide();
          $(this).removeClass("expanded");
        } else {
          replies.show();
          $(this).addClass("expanded");
          c.scroll_to(replies);
        }
        return false;
      });
    },

    init_add_reply_links: function() {
      $("#comments a.get.add_reply_link").live("click", function() {
        var comment_id = $(this).parents(".comment").attr("id").split('_').last();
        if($(this).parents(".comment").length < c.max_level) {
          var parent_id = comment_id;
        } else {
          var parent_id = $($(this).parents(".comment")[1]).attr("id").split('_').last();
        }
        reply_form = c.clone_form(parent_id);
        reply_form.appendTo("#comment_"+comment_id+" div.form:first");
        c.init_form_behaviours(comment_id);
        c.scroll_to(reply_form);
        $(this).removeClass("get").addClass("toggle");
        return false;
      });

      $("#comments a.toggle.add_reply_link").live("click", function() {
        var comment_id = $(this).parents(".comment").attr("id").split('_').last();
        var form_div = $("#comment_"+comment_id+" div.form:first");
        form_div.toggle();
        if(form_div.is(":visible")) c.scroll_to(form_div);
        return false;
      });
    },

    init_delete_comment_links: function() {
      $("#comments a.delete_comment").live("click", function() {
        var comment_id = $(this).closest(".comment").attr("id").split('_').last();
        $("<form/>").hide().append('<input type="hidden" name="_method" value="delete" />').appendTo($(document.body)).attr("action", c.comment_url(comment_id)).post_with_iframe({
          success: function(response) {
            var comment = $("#comment_"+response.comment.id);
            if(comment.siblings().size() == 0) {
              comment.parents(".comment:first").find(".expand_replies_link:first").removeClass("not_empty").addClass("empty");
            }
            comment.remove();
          }
        }).submit();
        return false;
      });
    },

    init_form_behaviours: function(id) {
      var form = id ? $("#comment_"+id+" form:first") : $("#new_comment_form");
      form.attr("action", c.comments_url()).disable_on_submit().post_with_iframe({
        success: function(response, f){if(response.comment){
            c.insert_comment(response.comment);
          } else if(response.notice) {
            c.render_message(response.notice);
          }
          f.enable_submit();
          c.reset_form(f, {hide: true});},
        failure: function(response, f){f.enable_submit(); c.render_comment_errors(response.errors, f);}
        });
    },

    init_get_board_details: function(callback){
      $.getJSON(c.board_details_url(), function(data){
        c._board_require_profile = data.comments_board["require_profile?"];
        if(callback != null) callback();
      });
    },

    init_report_inappropriate_links: function(){
      
      var flag_my_comment = function(me) {
        var comment_id = me.parents(".comment").attr("id").split('_').last();
        c.flag_comment(me, comment_id);
      }
      
      $("#comments a.get.report_inappropriate_link").live("click", function() {
        var me = $(this);
        Profile.logged_in({
          success: function(){flag_my_comment(me);},
          failure: function(){Profile.log_in();}
        });
        return false;
      });
      
      $("#comments a.flagged.report_inappropriate_link").live("click", function(){return false;})
    },

    /********************
    URLs
    *********************/
    // TODO: start here with a querystring builder function
    comments_url: function() {
      return c.build_url([c.board_resource_id, "comments"], ".json?page="+Url.get_param("page")+"&order="+Url.get_param("order")+"&expand_all="+Url.get_param("expand_all")+"&per_page="+Url.get_param("per_page")+"&board_name="+c.board_name+"&board_url="+c.board_url+"&callback=?");
    },

    comment_url: function(comment_id) {
      return c.build_url([c.board_resource_id, "comments", comment_id]);
    },
    
    flag_comment_url: function(comment_id) {
      return c.build_url([c.board_resource_id, "comments", comment_id, "flag"], ".json")
    },

    children_url: function(parent) {
      return c.build_url([c.board_resource_id, "comments", parent, "children"], ".json?board_name=" + c.board_name + "&board_url=" + c.board_url + "&callback=?");
    },

    top_boards_url: function() {
      return c.build_url([], ".json?callback=?");
    },

	  board_details_url: function() {
		  return c.build_url([c.board_resource_id], ".json?board_name="+c.board_name+"&board_url="+c.board_url+"&callback=?");
	  },

    featured_comment_url: function(options) {
      var options = options || {};
      var url = c.base_url + "/featured_comments.json?callback=?";

      switch(options["scope"]) {
      case 'brand':
        url += "&brand_name="+c.brand_name;
        break;
      case 'section':
        url += "&brand_name="+c.brand_name+"&section_name="+c.section_name;
        break;
      case 'board':
        url += "&brand_name="+c.brand_name+"&section_name="+c.section_name+"&board_resource_id="+c.board_resource_id+"&board_name="+c.board_name+"&board_url="+c.board_url;
        break;
      }
      return url;
    },

    comments_count_url: function() {
      var board_resource_ids = $.map($("a.comments_count"), function(link) { return link.rel; });
      if (board_resource_ids.length == 0) return;
      var url = c.base_url + "/brands/" + c.brand_name + "/sections/" + c.section_name + "/boards/comments_count?board_resource_id[]=" + board_resource_ids.join("&board_resource_id[]=") + "&callback=?";
      return url;
    },

    build_url: function(url_atoms, qs) {
      return [c.base_url, 'brands', c.brand_name, 'sections', c.section_name, 'boards'].concat(url_atoms).join('/') + qs;
    },
    
    build_url_from_path: function(path) {
      return c.base_url + path
    },

    /********************
    RENDERs
    *********************/
    render_comments_with_pagination: function(options) {
      Url.set_defaults(options);

      $.getJSON(c.comments_url(), function(data) {
        var pagination = data.pagination;
        Pagination.init(pagination);
        pagination.info = Pagination.pagination_info();
        pagination.links = Pagination.paginate();
        pagination.expand_all_or_collapse_all = c.expand_all_or_collapse_all_link();
        pagination.oldest_first = c.oldest_first_link_or_span();
        pagination.newest_first = c.newest_first_link_or_span();

        $("#comments").empty();
        $("#comments").before(Template.evaluate(c.top_pagination_template(), pagination));
        c.render_comments(data.comments, "#comments");
        $("#comments").after(Template.evaluate(c.bottom_pagination_template(), pagination));
        c.init_expand_replies_links();
        c.init_add_reply_links();
        c.init_report_inappropriate_links();
        c.init_delete_comment_links();
      });
    },

    render_comments: function(comments, container) {
      $.each(comments, function(i, obj) {
        var comment = c.convert_comment_path_to_urls(obj);
        $(container).append(Template.evaluate(c.comment_template(), comment));
        if(comment.comments && comment.comments.length > 0) {
          $("#toggle_replies_"+comment.id).removeClass("get").addClass("toggle expanded");
          c.render_comments(comment.comments, "#comment_"+comment.id+" .replies:first");
          if(comment.viewable_children_count > comment.comments.length) {
            $("#comment_"+comment.id+" .replies:first").append(Template.evaluate(c.more_comments_template(), {comments: comment.viewable_children_count, remaining_comments: comment.viewable_children_count-comment.comments.length }));
          }
        }
      });
    },

    render_comment_errors: function(errors, form) {
      var object = {};
      object.count = errors.length;
      object.errors = '';
      $.each(errors, function(i, error) {
        object.errors += error[0].capitalize() + " " + error[1] + "<br />";
      });
      form.find("div.errors").empty().append(Template.evaluate(c.comment_errors_template(), object));
    },

    render_message: function(response) {
      message = $("<div/>").attr("class", "comment").append(response);
      $("#comments").append(message);
      c.scroll_to(message);
    },

    render_children: function(parent, options) {
      options = options || {};
      $.getJSON(c.children_url(parent), function(data) {
        var container = $("#comment_"+parent+" .replies:first");
        container.empty();
        c.render_comments(data, container);
        c.scroll_to(container);
        if(options.highlight) c.highlight("#comment_"+options.highlight);
      });
    },

    render_top_boards: function() {
      $.getJSON(c.top_boards_url(), function(data) {
  		if(data.length > 0) {
  		  var top_boards = '';
          $.each(data, function(i, obj) {
            top_boards += Template.evaluate(c.top_board_template(), obj.board);
          });
          $("#top_boards").append(Template.evaluate(c.top_boards_template(), {top_boards: top_boards}));
  		}
      });
    },

    render_featured_comment: function(options) {
      $.getJSON(c.featured_comment_url(options), function(data) {
        if(data){
            var comment = c.convert_comment_path_to_urls(data.comment);
            $("#featured_comment").append(Template.evaluate(c.featured_comment_template(), comment));
        }
      });
    },

    render_comments_count: function() {
      $.getJSON(c.comments_count_url(), function(data) {
        $("a.comments_count").each(function() {
          board_resource_id = $(this).attr("rel");
          object = {count: data[board_resource_id]};
          if (object.count > 0) $(this).html(Template.evaluate(c.comments_count_template(), object));
        });
      });
    },

	  render_main_form: function() {
	    if($('.comment_form').length > 0)
		    c.render_comments_form("new_comment_form", function(html){$(".comment_form").html(html); c.init_form_behaviours();});
	  },
	
	  render_comments_form: function(id, insert_template_function){
		  c.require_profile({
			  yes: function(){
				  Profile.logged_in({
					  success: function(){var form = c.build_form_var_map(id, true); insert_template_function(Template.evaluate(c.require_profile_comment_form_logged_in_template(), form));},
					  failure: function(){var form = c.build_form_var_map(id, false); insert_template_function(Template.evaluate(c.require_profile_comment_form_logged_out_template(), form));}
				})
				
			  },
			  no: function(){
				  Profile.logged_in({
					  success: function(){var form = c.build_form_var_map(id, true); insert_template_function(Template.evaluate(c.anonymous_comment_form_logged_in_template(), form));},
					  failure: function(){var form = c.build_form_var_map(id, false); insert_template_function(Template.evaluate(c.anonymous_comment_form_logged_out_template(), form));}
				  })		
			  }
		  })
	  },

    /********************
    HELPERs
    *********************/
    insert_comment: function(comment) {
      order = Url.get_param("order") || 'ASC';
      comment = c.convert_comment_path_to_urls(comment);
      
      if ($("#comments").size() == 0) {
        window.location = Url.new_url({order: "DESC"}, decodeURIComponent(c.board_url));
      } else if (comment["parent_id"] > 0) {
        if ($("#toggle_replies_"+comment.parent_id).hasClass("get.expand_replies_link.not_empty")) {
          c.render_children(comment.parent_id, {highlight: comment.id});
        } else {
          var replies = $("#comment_"+comment["parent_id"]+" .replies:first");
          replies.append(Template.evaluate(c.comment_template(), comment));
          if (replies.is(":hidden")) replies.show();
          c.scroll_to_and_highlight("#comment_"+comment["id"]);
        }
        $("#toggle_replies_"+comment.parent_id).removeClass("get").addClass("toggle expanded");
        c.update_replies_count(comment.parent_id);
      } else if (order == "ASC") {
        if (Pagination.current_page == Pagination.total_pages) {
          $("#comments").append(Template.evaluate(c.comment_template(), comment));
          c.scroll_to_and_highlight("#comment_"+comment["id"]);
        } else {
          window.location = Url.new_url({page: Pagination.total_pages});
        }
      } else if (order == "DESC") {
        if (Pagination.current_page == 1) {
          $("#comments").prepend(Template.evaluate(c.comment_template(), comment));
          c.scroll_to_and_highlight("#comment_"+comment["id"]);
        } else {
          window.location = Url.new_url({page: 1});
        }
      }
    },

    clone_form: function(comment_id) {
      var reply_form = $("#new_comment_form").clone();
      reply_form.removeAttr("id");
      reply_form.append('<input type="hidden" name="comment[parent_id]" value="'+comment_id+'" />');
      reply_form.find(".form_title").text("Reply");
      c.reset_form(reply_form);
      return reply_form;
    },

    scroll_to: function(element) {
      scroll_to_if_necessary(element);
    },

    highlight: function(comment) {
      $(comment).effect("highlight", {}, 3000);
    },

    scroll_to_and_highlight: function(comment) {
      c.scroll_to(comment);
      c.highlight(comment);
    },

    reset_form: function(form, options) {
      options = options || {};
      form = $(form);

      form.find("input#comment_user_name").val("");
      form.find("textarea").val("");
      form.find("div.errors").empty();
      if (form.attr("id") != "new_comment_form" && options.hide) form.parent().hide();
    },

    update_replies_count: function(id) {
      var tag = $("#comment_"+id+" .expand_replies_link:first");
      tag.text(tag.text().replace(/([\d]+)/, function(i) {return parseInt(i)+1;}));
      if(tag.hasClass("empty")) tag.removeClass("empty").addClass("not_empty");
      if(tag.hasClass("get_comment_replies")) tag.removeClass("get_comment_replies").addClass("toggle_replies");
    },
	
	  //// Used after a user log's in to reset all the forms correctly
	  //rerender_all_forms: function(){
		//  c.render_comments_form("new_comment_form", function(new_html){$('#new_comment_form').replaceWith(new_html);});
		//
		//  $('#comments form').each(function(f){
		//	  form = $(this);
		//	  parent_id = form.children("[name = comment[parent_id]]").attr("value");
		//	  result = c.clone_form(parent_id);
		//	  form.replaceWith(result);
		//  })
	  //},
	
	  // This is a cheat method that will check if the board details
	  // have already been pulled from the server. If it hasn't it will
	  // go ahead and do that.
	  require_profile: function(callbacks){
		  if(c._board_require_profile == null){
			  c.init_get_board_details(function(){
				  if(c._board_require_profile){
					  if(callbacks.yes) callbacks.yes();
				  }else{
					  if(callbacks.no) callbacks.no();
				  }		
			  })
		  }else if(c._board_require_profile){
			  if(callbacks.yes) callbacks.yes();
		  }else{
			  if(callbacks.no) callbacks.no();
		  }
	  },
	
	  convert_comment_path_to_urls: function(comment) {
	    comment = comment.comment ? comment.comment : comment;
      var comment_additions = {};
      comment_additions["profile_url"] = comment.profile == null ? "#" : c.build_url_from_path(comment.profile.path);
      jQuery.extend(comment, comment_additions);
      return comment;
	  },

    build_form_var_map: function(form_id, signed_in) {
      if(signed_in){
        return {form_id: form_id, user_name: Profile.profile.name, small_photo_url: Profile.profile.photos.small, medium_photo_url: Profile.profile.photos.medium, large_photo_url: Profile.profile.photos.large, profile_url: Profile.my_profile_url()}
      } else {
        return {form_id: form_id}
      }
    },
	
	  flag_comment: function(link, comment_id) {
	    $("<form/>").hide().appendTo($(document.body)).attr("action", c.flag_comment_url(comment_id)).post_with_iframe({
	      success: function(response, form) {link.removeClass("flag").addClass("flagged").html(response.notice)},
	      failure: function() { alert('Error trying to flag comment.'); }
	    }).submit();
	  },
	  
	  /*
	  // This function scans
	     build_comment_html: function(comment) {
	       
	       var load_image = function(url){ 
	         var profile_img = new Image();
	         profile_img.src = url;
	       }     
	       var reg_mapping = {small_photo_url: /#{\s*small_photo_url/, medium_photo_url: /#{\s*medium_photo_url/, large_photo_url: /#{\s*large_photo_url/};
	       
	       for(var key in reg_mapping) {
	         // if the template uses this image
	         if(reg_mapping[key].exec(c.comment_template())){
	           load_image(comment[key])
	         }
	       } 
	       return Template.evaluate(c.comment_template(), comment);
	     },*/
	  
	
	  
    /********************
    LINKs
    *********************/
    expand_all_or_collapse_all_link: function() {
      if(Url.get_params().expand_all == 'true') {
        return '<a class="collapse" href="'+Url.new_url({expand_all: 'false'})+'">Collapse all replies</a>';
      } else {
        return '<a class="expand" href="'+Url.new_url({expand_all: 'true'})+'">Expand all replies</a>';
      }
    },

    oldest_first_link_or_span: function() {
      return c.link_or_span('Oldest first', Url.new_url({page: 1, order: 'ASC'}), Url.get_params().order == 'DESC')
    },

    newest_first_link_or_span: function() {
      return c.link_or_span('Newest first', Url.new_url({page: 1, order: 'DESC'}), Url.get_params().order != 'DESC')
    },

    link_or_span: function(text, link, needs_link) {
      if(needs_link) {
        return '<a href="'+link+'">'+text+'</a>';
      } else {
        return '<span>'+text+'</span>';
      }
    },

    /********************
    TEMPLATEs
    *********************/
    comment_template: function() {
      // return '<li class="comment" id="comment_#{id}"><span class="author">#{user_name}</span><span class="date">#{created_at:Format.iso_date}</span>#{body:Format.text}<p class="comment-tools"><a href="#" class="get add_reply_link" id="toggle_add_reply_#{id}">Add reply</a><a href="#" class="get expand_replies_link #{viewable_children_count:Format.quantity_class_name}" id="toggle_replies_#{id}">Replies (#{viewable_children_count})</a></p><div class="form"></div><ul class="replies"><li/></ul></li>';
      return '<li class="comment" id="comment_#{id}"><img src=#{small_photo_url} /><span class="author">#{user_name}</span><span class="date">#{created_at:Format.iso_date}</span>#{body:Format.text}<div class="options"><a href="#" class="get expand_replies_link #{viewable_children_count:Format.quantity_class_name}" id="toggle_replies_#{id}">Read replies (#{viewable_children_count})</a> <a href="#" class="get add_reply_link" id="toggle_add_reply_#{id}">Add reply</a><a href="#{profile_url}" class="get view_profile">View profile</a><a href="#" class="get report_inappropriate_link" id="report_inappropriate_link#{id}">Report as inappropriate?</a></div><div class="form"></div><ul class="replies"><li/></ul></li>';
    },

    top_pagination_template: function() {
      return '<div class="top_pagination"><div class="pagination_row1"><div class="left"><b>COMMENTS</b> (#{info})</div><div class="right">#{expand_all_or_collapse_all} <a href="#new_comment_form">Add comment</a></div></div><div class="pagination_row2"><div class="left"><span class="label">Sort by:</span> #{newest_first} | #{oldest_first}</div><div class="right"><span class="label">Page:</span><div class="pagination">#{links}</div></div></div></div>';
    },

    bottom_pagination_template: function() {
      return '<div class="bottom_pagination"><div class="right"><span class="label">Page:</span><div class="pagination">#{links}</div></div></div>';
    },

    top_boards_template: function() {
      return '<h1>Most talked about boards</h1>#{top_boards}';
    },

    top_board_template: function() {
      return '<div class="top_board"><a href="#{url}">#{name}</a> | <a href="#{url}">Comments (#{viewable_comments_count})</a></div>';
    },

    comments_count_template: function() {
      return 'Replies (#{count})';
    },

    more_comments_template: function() {
      return '<li>There are <a href="#" class="get expand_replies_link">#{remaining_comments}</a> more comments</li>';
    },

    featured_comment_template: function() {
      return '<h3>You Said It…</h3><h4>…about <a href="#{board.url}" class="link-to-article">#{board.name}</a></h4><a href="#{board.url}" class="link-to-comments">Comments (#{board.viewable_comments_count})</a><a href="#{board.url}#add-your-comment" class="link-to-comments">Add comment</a><div class="comment-body"><div class="ldquo">“</div><p>#{body}</p><div class="rdquo">”</div><span class="mdash">—</span><span class="author">#{user_name}</span></div>';
    },

    comment_errors_template: function() {
      return '#{count} errors:<br/>#{errors}';
    },

	  require_profile_comment_form_logged_in_template: function() {
	    return '<form id="#{form_id}" action=""><h1 class="form_title">Add new comment</h1><div class="errors"></div><img src="#{small_photo_url}" /><p><label for="comment_user_name">Name</label><br/><span>#{user_name}</span></p><p><label for="comment_body">Comment</label><br/><textarea id="comment_body" name="comment[body]" cols="50" rows="10"></textarea></p><p><input type="submit" value="Add comment"/></p></form>';
	  },
	
	  require_profile_comment_form_logged_out_template: function() {
	    return '<form id="#{form_id}" action=""><h1 class="form_title">Please sign up or log in to comment.</h1><div class="errors"></div><p><label for="comment_user_name">Name</label><br/><span>Annonymous</span></p><p><label for="comment_body">Comment</label><br/><textarea id="comment_body" name="comment[body]" cols="50" rows="10"></textarea></p><p><input type="submit" value="Add comment"/></p></form>';
	  },
	
	  anonymous_comment_form_logged_in_template: function(){
		  return '<form id="#{form_id}" action=""><h1 class="form_title">Add new comment</h1><div class="errors"></div><img src="#{small_photo_url}" /><p><label for="comment_user_name">Name</label><br/><span>#{user_name}</span></p><p><label for="comment_body">Comment</label><br/><textarea id="comment_body" name="comment[body]" cols="50" rows="10"></textarea></p><p><input type="submit" value="Add comment"/></p></form>';
	  },
	
	  anonymous_comment_form_logged_out_template: function(){
		  return '<form id="#{form_id}" action=""><h1 class="form_title">Add new comment</h1><div class="errors"></div><p><label for="comment_user_name">Name</label><br/><input type="text" id="comment_user_name" name="comment[user_name]" /></p><p><label for="comment_body">Comment</label><br/><textarea id="comment_body" name="comment[body]" cols="50" rows="10"></textarea></p><p><input type="submit" value="Add comment"/></p></form>';
	  }
	
	
  };
  return(c);
})(jQuery);
