Topic = Class.create();
Topic.prototype = {
  initialize: function(topic_url, data_url, style) {
    this.topic_url                  = topic_url;
    this.data_url                   = data_url;
    this.style                      = style;
    this.creator                    = false;
    this.official                   = false;
    this.can_delete                 = false;
    this.can_edit                   = false;
    this.replies                    = $A();
    
    if (page.logged_in()) {
      this.request_data();
    }
  },
  
  promoted_reply_container: function() {
    return $('promoted_replies');
  },
  
  reply_container: function() {
    return $('full_conversation');
  },
  
  reply_form: function() {
    return $('topic_reply_box').select('form').first();
  },

  comment_container: function() {
    return $('reply_comment_box');
  },
  
  request_data: function() {
    new Ajax.Request(this.data_url, {
      method: 'get',
      onSuccess: function(transport) { // response contains callback: this.apply_data
        eval(transport.responseText);
      }.bind(this) 
    });
  },
  
  apply_data: function(user_state) {
	  this.creator      = user_state['creator'];
	  this.official     = user_state['official'];
    this.can_delete   = user_state['can_delete'];
    this.can_edit     = user_state['can_edit'];
    this.can_moderate = user_state['can_moderate'];
    this.replies      = $A(user_state['replies']);
    
    if(this.can_moderate) {
      $('conversation').select('.remove_link').invoke('show');
      $('conversation').select('.restore_link').invoke('show');
    }
    
    this.update_topic();
    this.update_replies();

    Tag.reload_list(user_state['tags'], $('topic_tags_list'));
    page.notify('user_data_loaded');
  },
  
  update_topic: function() {
    this.update_creator_actions_under($('page').select('.topic_tools').first(), {
      'can_edit': this.can_edit, 
      'can_delete': this.can_delete
    });
    if (this.official) {
      var status_options = this.reply_form().select('.official_status_options').first();
      if (status_options) { status_options.show(); }
      var best_options = this.reply_form().select('.official_best_options').first();
      if (best_options) { best_options.show(); }
    };
  },
    
  update_creator_actions_under: function(outer_element, options) {
    if (!outer_element) { return };
    creator_actions = outer_element.select('.creator_actions').first();
    if (!creator_actions) { return };
    
    var can_delete = options['can_delete'];
    var can_edit   = options['can_edit'];
    
    if (can_edit || can_delete) {
      var creator    = options['creator'];
      var or_visible = can_edit && can_delete;
      if (or_visible) { // short circuit !!
        creator_actions.show()
        creator_actions.select('*').invoke('show');
        creator_actions.select('.countdown').invoke('hide');
        if (!creator) return;
      };
      var edit_time  = options['edit_time'] * 1;
      if (can_edit) {
        creator_actions.select('.edit_link').invoke('show');
        if (edit_time > 0) {
          var countdown  = creator_actions.select('.countdown');
          if (countdown.first()) {
            creator_actions.select('.n').first().update(Math.floor(edit_time));
            countdown.invoke('show')
          }
        }
      } else {
        creator_actions.select('.edit_link').invoke('hide');
        creator_actions.select('.countdown').invoke('hide');
        creator_actions.select('.or').invoke('hide');
      }
      
      creator_actions.select('.delete_link').invoke(can_delete ? 'show' : 'hide');
      creator_actions.show();
    } else {
      creator_actions.hide();
    }
  },
  
  update_topic_status: function(reply_data) {
    var status_content = reply_data['status'];
    var topic_status = $('topic_status');
    if (topic_status && !status_content.strip().blank()) {
      topic_status.update(status_content);
    }
  },
  
  fade_action_link: function(parent_or_dom_id, link_selector) {
    var parent = $(parent_or_dom_id);
    if (parent) {
      var action_link = parent.select(link_selector).first();
      if (action_link) { new Effect.Fade(action_link, {duration: 0.6}); }
    }
  },
  
  hide_action_link: function(parent_or_dom_id, link_selector) {
    var parent = $(parent_or_dom_id);
    if (parent) {
      var action_link = parent.select(link_selector).first();
      if (action_link) { action_link.hide(); }
    }
  },
  
  cancel_fade_action_link: function(parent_or_dom_id, link_selector) {
    var parent = $(parent_or_dom_id);
    if (parent) {
      var action_link = parent.select(link_selector).first();
      if (action_link) { action_link.show().setOpacity(1); }
    }
  }

}

Object.extend(Topic.prototype, {
  activate_reply_form: function() {
    Element.scrollTo(this.reply_form());
    this.reply_form().focusFirstElement();
  },
  
  reset_reply_form: function(form) {
    this.reenable_button(form);
    EmotionPicker.cancel_emotitagging(form.down('.emotitagger'));
    form.reset();
    form.down('.status').hide();
    form.down('.pt_tool').hide();
    form.select('.pt_tab').invoke('removeClassName', 'on');
  },
  
  post_reply: function(reply_form, method) {
    new Ajax.Request(reply_form.action, { // Success: this.add_reply, Failure: this.display_errors
      method: method ? method : 'post',
      parameters: Form.serialize(reply_form),
      onComplete: function(transport) {
        try      { eval(transport.responseText); }
        catch(e) { this.reenable_button(reply_form); }
      }.bind(this)
    });
    return false;
  },
  
  submit_reply_with_profanity: function(reply_form, method) {
    form_data = $(reply_form).serialize(true)
    
    new Ajax.Request(page.profanity_path, {
      method: 'post',
      asynchronous:true, 
      parameters: {"content[reply content]":form_data["reply[content]"], "content[emotion]":form_data["reply[emotitag][feeling]"] },
      evalScripts:true,
      onSuccess: function(response){ this.submit_reply(reply_form, method); }.bind(this)
    });
    return false;
  },
  
  submit_reply: function(reply_form, method) {
    var submit_link = $(reply_form).select('.submit_link').first();
    this.disable_button_for_submit(submit_link, 'Posting reply...');

    var me = this;
    page.async(function() { // async allows other observers to work first
      page.login_and_do(submit_link, me.post_reply.bind(me, $(reply_form), method), {
        fail:         me.reenable_button.bind(me, $(reply_form)),
        cancel_login: me.reenable_button.bind(me, $(reply_form)),
        prompt: 'post your reply'
      })
    });

    return false;
  },
  
  add_reply: function(reply_data) {
    var dom_id           = reply_data['dom_id'];
    var reply_content    = reply_data['content'];
    var official         = reply_data['official'];
    var sponsor          = reply_data['sponsor'];
    var company_promoted = reply_data['company_promoted'];
    var sponsor_promoted = reply_data['sponsor_promoted'];
    var edit_time        = reply_data['edit_time'];
    
    var new_reply_data   = Object.extend(this.new_reply_data(dom_id), {sponsor: sponsor, official: official, edit_time: edit_time});
    var reply_form       = $('editing_' + dom_id) || this.reply_form();
    
    var reply = $(dom_id);
    if (reply) { // reply already present: editing
      reply_form.up('li').remove();
      this.replies.without(this.reply_data_for_dom_id(dom_id)).push(new_reply_data);
      reply.replace(reply_content);
    } else {
      this.reset_reply_form(reply_form);
      this.replies.push(new_reply_data);
      new Insertion.Bottom(this.reply_container(), reply_content);
    };

    page.async(function() {
      var new_reply = $(dom_id);
      this.update_creator_actions_under(new_reply, new_reply_data);
      this.update_reply_promotion_link(new_reply, new_reply_data);
      this.update_company_promotion_link(new_reply, new_reply_data);
      this.update_sponsor_promotion_link(new_reply, new_reply_data);
      new Effect.Highlight(new_reply);
      this.update_topic_status(reply_data);
    }.bind(this));
    
    if (company_promoted) { this.reload_promoted_replies(); }
  },
  
  delete_reply: function(url, dom_id) {
    var reply_data = this.reply_data_for_dom_id(dom_id);
    var confirmation_message = "Are you sure you want to delete this? This cannot be undone!";
    var error_message = "There was an error trying to delete this. Perhaps you don't have permission?";
    if (reply_data.can_delete && confirm(confirmation_message)) {
      new Ajax.Request(url, {
        method: 'delete',
        on401: function(transport) { alert(error_message); },
        on500: function(transport) { alert(error_message); },
        onSuccess: function(transport) {
          this.replies = this.replies.without(reply_data);
          var li = $(dom_id);
          var previous = false;
          var comment = li.hasClassName('comment');
          if (comment) { previous = li.previous('.reply'); }
          li.remove();
        }.bind(this),
        on403: function(request) {
          page.safe_redirect(request.responseText);
        }
      });
    }
  },
  
  edit_reply: function(url, edit_link) {
    var reply               = edit_link.up('.reply');
    var form_content        = page.reply_container_template;
    var active_form_content = '<li class="reply form">' + form_content + "</li>";
    
    reply.hide();
    new Insertion.After(reply, active_form_content);
    
    var edit_reply_li = reply.next();
    var reply_form = edit_reply_li.down('form');
    var text_area = reply_form.down('textarea');
    
    if (this.official) {
      var status_options = reply_form.select('.official_status_options').first();
      if (status_options) { status_options.show(); }
    };
    
    text_area.value = 'Loading your reply...';
    text_area.disable();
    
    new Ajax.Request(url + '/edit', {
      method: 'get',
      onSuccess: function(request) {
        try {
          reply_data = eval(request.responseText);
          text_area.enable();
          text_area.value = reply_data.content;

          reply_form.down('.emotitagger_feeling').value = reply_data.emotitag.feeling;
          reply_form.down('.emotitagger_intensity').value = reply_data.emotitag.intensity;
          emotion_picker = EmotionPicker.find_in(reply_form);
          emotion_picker.set_face(reply_data.emotitag.face);
          emotion_picker.set_punctuation();
          text_area.focus();
          new Effect.Highlight(text_area);
        } catch(e) { this.cancel_editing(reply_form); }
      }.bind(this),
      onFailure: function(request) {
        try { eval(request.responseText); }
        finally { this.cancel_editing(reply_form); }
      }.bind(this)
    });
    
    reply.addClassName('editing');
    reply_form.action = url;
    reply_form.id = 'editing_' + reply.id;
    reply_form.onsubmit = function() { return this.submit_reply(reply_form, 'put') }.bind(this);
    reply_form.down('.submit_link').value = 'Update reply';
    reply_form.down('.reply_label').update('Edit your reply');
    var cancel_link = reply_form.down('.cancel_link').show();
    cancel_link.onclick = function() { this.cancel_editing(reply_form, true); return false; }.bind(this);
    cancel_link.update('Cancel editing this reply');    
  },
  
  cancel_editing: function(inner_el, should_confirm) {
    if(should_confirm == null){ should_confirm = false; }
    var li = inner_el.match('li.form') ? inner_el : inner_el.up('li.form')
    
    if(!should_confirm || this.confirm_when_nonblank(li, "Are you sure you want to cancel this comment?")) {
      this.unhide_editing(li);
      li.remove();
    }
  },
  
  confirm_when_nonblank: function(el, message) {
    var has_editted = false;
    if(content_el = $(el).down(".content")) {
      if(!$F(content_el).blank()) { has_editted = true; }
    }
    
    if(!has_editted){ return true; } // if the user hasn't typed anything, go ahead and cancel
    
    if(confirm(message)) {
      return true;
    } else {
      return false;
    }
  },
    
  promote_reply: function(activated_by, reply_data) {
    page.login_and_do(activated_by, function() {
        Object.extend(reply_data, this.reply_data_for_dom_id(reply_data.dom_id) || {});
        if (!reply_data.creator && !reply_data.starred) { this.apply_star_promotion(reply_data, 'promote'); }
      }.bind(this),
      {prompt: 'promote this reply'}
    );
    return false;
  },
  
  demote_reply: function(reply_data) {
    Object.extend(reply_data, this.reply_data_for_dom_id(reply_data.dom_id) || {});
    if (!reply_data.creator && reply_data.starred) { this.apply_star_promotion(reply_data, 'demote'); }
  },
  
  company_promote_reply: function(reply_data) {
    Object.extend(reply_data, this.reply_data_for_dom_id(reply_data.dom_id) || {});
    if (reply_data.official && !reply_data.company_promoted) { this.apply_company_promotion(reply_data, 'promote'); }
  },
  
  company_demote_reply: function(reply_data) {
    Object.extend(reply_data, this.reply_data_for_dom_id(reply_data.dom_id) || {});
    if (reply_data.official && reply_data.company_promoted) { this.apply_company_promotion(reply_data, 'demote'); }
  },  
  
  sponsor_promote_reply: function(reply_data) {
    Object.extend(reply_data, this.reply_data_for_dom_id(reply_data.dom_id) || {});
    if (reply_data.sponsor && !reply_data.sponsor_promoted) { this.apply_sponsor_promotion(reply_data, 'promote'); }
  },
  
  sponsor_demote_reply: function(reply_data) {
    Object.extend(reply_data, this.reply_data_for_dom_id(reply_data.dom_id) || {});
    if (reply_data.sponsor && reply_data.sponsor_promoted) { this.apply_sponsor_promotion(reply_data, 'demote'); }
  },
  
  // Internal stuff
  apply_star_promotion: function(reply_data, action) {
    var url; var method; var starred;
    if (action == 'promote') {
      this.fade_action_link(reply_data.dom_id, '.promotion_link');
      url = "\/stars";
      method = 'post';
      starred = true;
    } else if (action == 'demote') {
      this.fade_action_link(reply_data.dom_id, '.demotion_link');
      url = "\/stars\/remove";
      method = 'delete';
      starred = false;
    }
    new Ajax.Request(url, {
      method: method,
      parameters: {reply_id: reply_data.reply_id},
      onFailure: function(request) {
        var currently_starred = this.reply_data_for_dom_id(reply_data.dom_id).starred;
        if (action == 'promote' && !currently_starred) {
          // promotion failed => re-show the promotion_link unless the reply is actually starred, and hide the opposite!
          this.cancel_fade_action_link(reply_data.dom_id, '.promotion_link');
          this.hide_action_link(reply_data.dom_id, '.demotion_link');
        } else if (action == 'demote' && currently_starred) {
          // demotion failed => re-show the demotion_link if the reply is still starred, and hide the opposite!
          this.cancel_fade_action_link(reply_data.dom_id, '.demotion_link');
          this.hide_action_link(reply_data.dom_id, '.promotion_link');
        }
      }.bind(this),
      onSuccess: function(request) {
        reply_data = this.reply_data_for_dom_id(reply_data.dom_id);
        reply_data.starred = starred;
        if (action == 'promote') {
          // promotion succeeded => show the demotion_link and make sure it's opaque, and hide the opposite!
          this.cancel_fade_action_link(reply_data.dom_id, '.demotion_link');
          this.hide_action_link(reply_data.dom_id, '.promotion_link');
        } else if (action == 'demote') {
          // demotion succeeded => show the promotion_link and make sure it's opaque, and hide the opposite!
          this.cancel_fade_action_link(reply_data.dom_id, '.promotion_link');
          this.hide_action_link(reply_data.dom_id, '.demotion_link');
        }
        this.update_promo_language($(reply_data.dom_id), reply_data);
        var promoted_reply = $("promoted_"+reply_data.dom_id);
        if (promoted_reply) { this.update_promo_language(promoted_reply, reply_data); }
      }.bind(this)
    });
  },

  apply_company_promotion: function(reply_data, action) {
    var url; var method;
    if (action == 'promote') {
      this.fade_action_link(reply_data.dom_id, '.company_promotion_link');
      url = "\/company_picks";
      method = 'post';
    } else if (action == 'demote') {
      this.fade_action_link('promoted_'+reply_data.dom_id, '.company_promotion_link');
      url = "\/company_picks\/remove";
      method = 'delete';
    }
    new Ajax.Request(url, { // Success: this.update_promoted_replies
      method: method,
      parameters: {reply_id: reply_data.reply_id},
      onSuccess: function(transport) {
        try      { eval(transport.responseText); }
        catch(e) {
          var company_promoted = this.reply_data_for_dom_id(reply_data.dom_id).company_promoted;
          if (action == 'promote') {
            // company promotion failed => show the company_promotion_link
            if (!company_promoted) { this.cancel_fade_action_link(reply_data.dom_id, '.company_promotion_link'); }
          } else if (action == 'demote') {
            // company demotion failed => show the demotion link on the promoted reply
            if (company_promoted) { this.cancel_fade_action_link("promoted_"+reply_data.dom_id, '.company_promotion_link'); }
          }
        }
      }.bind(this),
      onFailure: function(transport) {
        var company_promoted = this.reply_data_for_dom_id(reply_data.dom_id).company_promoted;
        if (action == 'promote') {
          // company promotion failed => show the company_promotion_link
          if (!company_promoted) { this.cancel_fade_action_link(reply_data.dom_id, '.company_promotion_link'); }
        } else if (action == 'demote') {
          // company demotion failed => show the demotion link on the promoted reply
          if (company_promoted) { this.cancel_fade_action_link("promoted_"+reply_data.dom_id, '.company_promotion_link'); }
        }
      }.bind(this)
    });
    return false;
  },
  
  apply_sponsor_promotion: function(reply_data, action) {
    var url; var method;
    if (action == 'promote') {
      this.fade_action_link(reply_data.dom_id, '.sponsor_promotion_link');
      url = "\/sponsored_picks";
      method = 'post';
    } else if (action == 'demote') {
      this.fade_action_link('promoted_'+reply_data.dom_id, '.sponsor_promotion_link');
      url = "\/sponsored_picks\/remove";
      method = 'delete';
    }
    new Ajax.Request(url, { // Success: this.update_promoted_replies
      method: method,
      parameters: {reply_id: reply_data.reply_id},
      onSuccess: function(transport) {
        try      { eval(transport.responseText); }
        catch(e) {
          var sponsor_promoted = this.reply_data_for_dom_id(reply_data.dom_id).sponsor_promoted;
          if (action == 'promote') {
            // company promotion failed => show the company_promotion_link
            if (!company_promoted) { this.cancel_fade_action_link(reply_data.dom_id, '.sponsor_promotion_link'); }
          } else if (action == 'demote') {
            // company demotion failed => show the demotion link on the promoted reply
            if (company_promoted) { this.cancel_fade_action_link("promoted_"+reply_data.dom_id, '.sponsor_promotion_link'); }
          }
        }
      }.bind(this),
      onFailure: function(transport) {
        var sponsor_promoted = this.reply_data_for_dom_id(reply_data.dom_id).sponsor_promoted;
        if (action == 'promote') {
          // company promotion failed => show the company_promotion_link
          if (!company_promoted) { this.cancel_fade_action_link(reply_data.dom_id, '.sponsor_promotion_link'); }
        } else if (action == 'demote') {
          // company demotion failed => show the demotion link on the promoted reply
          if (company_promoted) { this.cancel_fade_action_link("promoted_"+reply_data.dom_id, '.sponsor_promotion_link'); }
        }
      }.bind(this)
    });
    return false;
  },
  
  update_replies: function() {
    if (this.replies.size < 1) { return; }
    
    this.replies.async_each(function(reply_data) {
      var reply = $(reply_data.dom_id);
      this.update_creator_actions_under(reply, reply_data);
      if (reply.hasClassName('reply')) {
        this.update_company_promotion_link(reply, reply_data);
        this.update_sponsor_promotion_link(reply, reply_data);
        
        if (reply_data.starred) {
          this.update_reply_promotion_link(reply, reply_data);
          this.update_promo_language(reply, reply_data, true);
        }
        if (reply_data.creator) {reply.select('.star_link').invoke('hide')};
      }
      
    }.bind(this));
    
    var promoted_replies = this.promoted_reply_container().select('.promoted_reply');
    promoted_replies.async_each(function(promoted_reply) {
      var reply_data = this.reply_data_for_dom_id(promoted_reply.id.sub('promoted_',''));
      if (reply_data.starred) { this.update_promo_language(promoted_reply, reply_data, true); }
    }.bind(this));
  },
  
  reload_promoted_replies: function(attribute) {
    new Ajax.Updater('promoted_replies', this.topic_url + '/replies', {method: 'get'});
  },
  
  update_promoted_replies: function(promoted_reply_data) {
    
    var reply                  = $(promoted_reply_data.dom_id);
    var company_promotion_link = reply.down('.company_promotion_link');
    var sponsor_promotion_link = reply.down('.sponsor_promotion_link');
    
    var promoted_reply_container = this.promoted_reply_container();
    var promoted_replies       = promoted_reply_data.content;
    var company_promoted       = promoted_reply_data.company_promoted;
    var sponsor_promoted       = promoted_reply_data.sponsor_promoted;
    
    this.reply_data_for_dom_id(promoted_reply_data.dom_id).company_promoted = promoted_reply_data.company_promoted;
    this.reply_data_for_dom_id(promoted_reply_data.dom_id).sponsor_promoted = promoted_reply_data.sponsor_promoted;
    reply_data = Object.extend(promoted_reply_data, this.reply_data_for_dom_id(promoted_reply_data.dom_id));
    
    promoted_reply_container.update(promoted_replies);
    if (promoted_replies.blank()) {
      promoted_reply_container.hide();
    } else {
      var officially_promoted_replies = promoted_reply_container.down('.officially_promoted');
      if (officially_promoted_replies) {
        var officially_promoted_header  = officially_promoted_replies.down('h2');
        if (officially_promoted_header) {
          officially_promoted_replies.visible() ? officially_promoted_header.show() : officially_promoted_header.hide();
        }
      };      
      
      var sponsor_promoted_replies = promoted_reply_container.down('.sponsor_promoted');
      if (sponsor_promoted_replies) {
        var sponsor_promoted_header  = sponsor_promoted_replies.down('h2');
        if (sponsor_promoted_header) {
          sponsor_promoted_replies.visible() ? sponsor_promoted_header.show() : sponsor_promoted_header.hide();
        }
      };
      
      var star_promoted_replies = promoted_reply_container.down('.star_promoted');
      if (star_promoted_replies) {
        var star_promoted_header = star_promoted_replies.down('h2');
        if (star_promoted_header) {
          star_promoted_replies.visible() ? star_promoted_header.show() : star_promoted_header.hide();
        }
      }
      
      promoted_reply_container.select('.promoted_reply').each(function(promoted_reply) {
        this.update_promo_language(promoted_reply, this.reply_data_for_dom_id(promoted_reply_data.dom_id), true);
      }.bind(this));
      promoted_reply_container.show();
      
      this.update_promo_language(reply, this.reply_data_for_dom_id(promoted_reply_data.dom_id));
    }
    
    if(company_promotion_link) company_promoted ? company_promotion_link.hide() : company_promotion_link.show();
    if(sponsor_promotion_link) sponsor_promoted ? sponsor_promotion_link.hide() : sponsor_promotion_link.show();
  },
  
  update_reply_promotion_link: function(reply, reply_data) {
    var promotion_link = reply.select('.promotion_link').first();
    var demotion_link = reply.select('.demotion_link').first();
    if (promotion_link && demotion_link) {
      if (reply_data.creator) {
        promotion_link.hide();
        demotion_link.hide();
      } else {
        if (reply_data.starred) {
          promotion_link.hide();
          demotion_link.show();
        } else {
          promotion_link.show();
          demotion_link.hide();
        }
      }
    }
  },
  
  update_company_promotion_link: function(reply, reply_data) {
    if (this.official && reply_data.official && !reply_data.company_promoted) {
      var promo_link = reply.select('.company_promotion_link').first();
      if (promo_link) { promo_link.show(); }
    }
  },
    
  update_sponsor_promotion_link: function(reply, reply_data) {
    if (reply_data.sponsor && !reply_data.sponsor_promoted) {
      var promo_link = reply.select('.sponsor_promotion_link').first();
      if (promo_link) { promo_link.show(); }
    }
  },
    
  update_promo_language: function(reply, reply_data, initial_load) {
    var promo_summary = reply.down('.promotion_summary');
    if (!promo_summary) { return; }
    var count = promo_summary.down('.count');
    var promoted_by_you = reply_data.starred;
    var total_promoters = count ? parseInt(count.innerHTML) : 0;
    var other_promoters = initial_load && promoted_by_you ? total_promoters - 1 : total_promoters;
    
    //  Who promoted this?
    //    y: you
    //    c: the company
    //    0: no other people
    //    m: one or many other people
    var promoters = promoted_by_you ? "y" : "";
    promoters += reply_data.company_promoted ? "c" : "";
    promoters += other_promoters == 0 ? "0" : "m";
    
    var substitutions = {
      say: this.style == "idea" ? "think" : "say",
      n: other_promoters,
      people: other_promoters == 1 ? "person" : "people"
    }
    
    var phrase = "";
    switch (promoters) {
      case 'm':
        phrase = "<span class=\"count\">#{n}</span> #{people} #{say}" + (other_promoters == 1 ? "s" : "");
        break;
      case 'c0':
        phrase = "The company #{say}s";
        break;
      case 'cm':
        phrase = "The company and <span class=\"count\">#{n}</span> other #{people} #{say}";
        break;
      case 'y0':
        phrase = "<span class=\"you\">You #{say}</span>";
        break;
      case 'yc0':
        phrase = "<span class=\"you\">You</span> and the company #{say}";
        break;
      case 'ym':
        phrase = "<span class=\"you\">You</span> and <span class=\"count\">#{n}</span> other #{people} #{say}";
        break;
      case 'ycm':
        phrase = "<span class=\"you\">You</span>, the company, and <span class=\"count\">#{n}</span> other #{people} #{say}";
        break;
    }
    promo_summary.down('.phrase').update(new Template(phrase).evaluate(substitutions));
    phrase.blank() ? promo_summary.hide() : promo_summary.show();
  },
    
  disable_button_for_submit: function(button, message) {
    if (message === undefined) { message = 'Submitting...'; }
    button.setAttribute('originalValue', button.value);
    button.value = message;
    button.disable();
  },
  
  reenable_button: function(form) {
    var button = form.select('.submit_link').first();
    button.value = button.readAttribute('originalValue') == null ? button.value : button.readAttribute('originalValue');
    button.enable();
  },
  
  unhide_editing: function(inner_el) {
    var li = inner_el.match('li.form') ? inner_el : inner_el.up('li.form')
    var hidden_el = li.previous('.editing');
    if (hidden_el) { return hidden_el.show().removeClassName('editing'); }
  },
  
  reply_data_for_dom_id: function(dom_id) {
    return this.replies.find(function(r) { return r.dom_id == dom_id });
  },
  
  new_reply_data: function(dom_id) {
    return {
      'creator': true, 
      'can_delete': true, 
      'can_edit': true,
      'edit_time': 15,
      'dom_id': dom_id
    };
  },
  
  display_errors: function(errors) {
    this.reenable_button(this.reply_form());
    error_messages = errors.content;
    alert(error_messages.join("\n")); // TODO: Make prettier
    page.async(function(){ 
      this.update_topic_status(errors);
    }.bind(this));
  }
});

Object.extend(Topic.prototype, {
  find_last_comment_for: function(reply) {
    var last_comment;
    reply.nextSiblings().find(function(c) {
      if (c.hasClassName('reply')) {
        return true;
      } else {
        if (!c.hasClassName('editing')) { last_comment = c; }
        return false;
      }
    });
    return last_comment = last_comment === undefined ? reply : last_comment;
  },
  
  reveal_comment_form: function(parent_id, name, activated_by) {
    var reply = $(activated_by).up('li');
    var last_comment = this.find_last_comment_for(reply);
    if (last_comment.hasClassName('form')) {
      last_comment.down('form').focusFirstElement();
      page.adjust_scroll_position(last_comment, 14);
      return
    }
    
    var active_form_content = '<li class="comment form">' + page.comment_container_template + "</li>";
    new Insertion.After(last_comment, active_form_content);
    
    var comment_li = last_comment.next();
    var comment_form = comment_li.down('form');
    comment_form.getInputs('hidden', 'comment[parent_id]').first().value = parent_id;
    comment_form.down('.name').update(name.possessify());
    comment_form.focusFirstElement();
    page.adjust_scroll_position(comment_form, 14);
  },
  
  edit_comment: function(url, edit_link, parent_id) {
    var comment             = edit_link.up('li');
    var reply               = comment.previous('.reply');
    var form_content        = page.comment_container_template;
    var active_form_content = '<li class="comment form">' + form_content + "</li>";
    comment.hide();
    new Insertion.After(comment, active_form_content);
    
    var edit_comment_li = comment.next();
    var comment_form = edit_comment_li.down('form');
    var cancel_link = comment_form.down('.cancel_link');

    var text_area = comment_form.down('textarea');
    text_area.value = 'Loading your comment...';
    text_area.disable();
    
    comment_form.getInputs('hidden', 'comment[parent_id]').invoke('disable');
    page.adjust_scroll_position(comment_form, 80);
      
    new Ajax.Request(url + '/edit', {
      method: 'get',
      onSuccess: function(request) {
        try {
          comment_data = eval(request.responseText);
          text_area.enable();
          text_area.value = comment_data.content;
          text_area.focus();
          new Effect.Highlight(text_area);
        } catch(e) { this.cancel_editing(comment_form); }
      }.bind(this),
      onFailure: function(request) {
        try { eval(request.responseText); }
        finally { this.cancel_editing(comment_form); }
      }.bind(this)
    });

    comment.addClassName('editing');
    comment_form.action = url;
    comment_form.onsubmit = function() { return this.submit_comment(comment_form, 'put') }.bind(this);
    comment_form.down('.submit_link').value = 'Update comment';
    comment_form.down('.comment_label').update('Edit your comment');
    cancel_link.update('Cancel editing this comment');  
  },
  
  post_comment: function(form, method) {
    new Ajax.Request(form.action, { // Success: this.add_comment, Failure: this.display_errors
      method: method ? method : 'post',
      parameters: Form.serialize(form),
      onComplete: function(transport) {
        try      { eval(transport.responseText); }
        catch(e) { this.reenable_button(form); }
      }.bind(this),
      onFailure: function() { this.reenable_button(form); }.bind(this)
    });
    return false;
  },
  
  submit_comment: function(comment_form, method) {
    var submit_link = $(comment_form).down('.submit_link');
    this.disable_button_for_submit(submit_link, 'Posting comment...');
    page.login_and_do(submit_link, this.post_comment.bind(this, comment_form, method), {
      fail:         this.reenable_button.bind(this, comment_form),
      cancel_login: this.reenable_button.bind(this, comment_form),
      prompt:       'post your comment'
    });
    return false;
  },
  
  
  submit_comment_with_profanity: function(comment_form, method) {
    form_data = $(comment_form).serialize(true)

    new Ajax.Request(page.profanity_path, {
      method: 'post',
      asynchronous:true, 
      parameters: { "content[comment]":form_data["comment[content]"] },
      evalScripts:true,
      onSuccess: function(response){ this.submit_comment(comment_form, method); }.bind(this)
    });
    return false;
  },
  
  add_comment: function(comment_data) {
    var dom_id               = comment_data['dom_id'];
    var comment_content      = comment_data['content'];
    var parent               = $(comment_data['parent_dom_id']);
    var editing_form         = parent.next('li.form');
    var new_comment_data     = this.new_reply_data(dom_id);
    if (comment_data['edit_time']) {
      new_comment_data.edit_time = comment_data['edit_time'];
    }
    
    Object.extend(this.reply_data_for_dom_id(comment_data['parent_dom_id']), {can_delete: false, can_edit: false})
    var comment = $(dom_id);
    if (comment) { // comment already present: editing
      Object.extend(this.reply_data_for_dom_id(dom_id), new_comment_data);
      comment.replace(comment_content);
      editing_form.remove();
    } else {
      var insert_comment_after = editing_form.previous();
      this.replies.push(new_comment_data);
      editing_form.remove();
      new Insertion.After(insert_comment_after, comment_content);
    };
    
    var new_comment = $(dom_id);
    page.async(function() {
      this.update_creator_actions_under(parent, this.reply_data_for_dom_id(comment_data['parent_dom_id']));
      this.update_creator_actions_under(new_comment, new_comment_data);
      new Effect.Highlight(new_comment.down('.content'));
    }.bind(this));
  }
});


