(function($) {
  $.fn.postform = function(options) {
    var settings = jQuery.extend({
      hidden: false,
      hidden_class: 'is_hidden',
      photo_upload_url: '/',
      selector: '.add_post_selector ul a',
      toggle: '.hidden_field',
      use_wmd: true
    }, options);
    
    hide_fields = function(fields) {
      $(fields).each(function() {
        var field = $(this);
        var label = field.find("label").text();
        var expand_link = '<p><a class="expand-link" href="#">Add ' + label +'</a></p>';
        
        field.prepend(expand_link)
          .find("label, input, textarea, div")
          .addClass(settings.hidden_class);
        field.find(".expand-link")
          .bind("click", { label: label }, expand_field);
      });
    };
    
    
    expand_field = function(e) {
      var target = $(e.target);
      var label = e.data.label;
      
      e.preventDefault();
      target.closest("li").find("label, input, textarea, div")
        .toggleClass(settings.hidden_class);
      (target.text() === 'Add ' + label) ? target.text('Hide ' + label) : target.text('Add ' + label);
    };
    
    
    function LinkAttachment(defaults) {
      this.defaults = jQuery.extend({
        'textarea_id': 'textarea',
        'attachment_list': '#attachment_list',
        'label': 'Attachment object'
      }, defaults);
      
      var options = this.defaults,
          textarea = $("#" + options.textarea_id),
          attachment_list = $(options.attachment_list),
          wrapper = attachment_list.parent(),
          label = options.label,
          link = render();
      
      function render() {
        var link = $('<li><a href="#attach">' + label + '</a></li>');
        
        attachment_list.append(link);
        link.find("a").bind('click', function (e) {
          e.preventDefault();
          showLinkForm(label);
        });
      }
      
      function showLinkForm(label) {
        var input = '<li><input id="attach_link" name="attach-link" type="text"></li>',
            control = '<li><button type="submit">Attach</button> or <a href="#cancel" class="cancel-link">cancel</a></li>',
            help_text = "<p class=\"help_text\">Have a photo or video you want \
            to use here? If it's from one of <a href=\"/sister-sites/\" target=\"_blank\">our \
            sister sites</a> or <a href=\"/oembed-provider-sites/\" target=\"_blank\">big sites \
            like flickr.com or youtube.com</a>, simply copy the page URL of \
            the photo or video and paste it here. \
            <a class=\"expand-link\" href=\"#more\">Read more.</a></p> \
            <div class=\"post-instructions expand-content " + settings.hidden_class +"\">\n\
            <h4>Detailed instructions</h4>\n\
            <ol>\n\
            <li>Find the content you want to share. It can be from \
            <a href=\"/sister-sites/\" target=\"_blank\">our sister sites</a> or \
            <a href=\"/oembed-provider-sites/\" target=\"_blank\">big sites like flickr.com or \
            youtube.com</a>.</li>\n\
            <li> \
              Select the URL and copy it. \
              <img class=\"screenshot\" src=\"http://media.ljworld.com/static/worldonline_defaults/images/screenshots/copy.png\" width=\"450px\"> \
            </li>\n\
            <li> \
              Paste it above and then click \"Attach.\"<br /> \
              <img class=\"screenshot\" src=\"http://media.ljworld.com/static/worldonline_defaults/images/screenshots/attach.png\" width=\"365px\"> \
            </li>\n\
            </ol>\n\
            </div>";
            var form = $('<h5>' + label + '</h5><form><ul class="form">' + input + control + '</ul></form>' + help_text);
            
        attachment_list.hide().after(form);
        form.wrapAll("<div/>");
        
        wrapper.find(".expand-link").click(function (e) {
          e.preventDefault();
          $(e.target).remove();
          wrapper.find(".expand-content").toggleClass(settings.hidden_class);
        });
        
        $("input[name='attach-link']")
          .val("http://")
          .click(function() {
            var txt = $(this).val();
            
            $(this).val("");
          })
          .blur(function() {
            if ($(this).val() == '') {
              $(this).val("http://");
            }
          });
        
        attachment_list.parent().find(".cancel-link")
          .bind("click", function (e) {
            e.preventDefault();
            $(e.target).closest("div").remove();
            attachment_list.show();
          }
        );
        
        form.submit(function (e) {
          var input = $("input[name='attach-link']"),
              val = input.val();
          e.preventDefault();
          
          if ((val.length == 0) || (val == 'http://')) {
            textarea.parent().find('.errorlist').remove();
            textarea.parent().find(".form").removeClass("has_errors").addClass("has_errors");
            input.parent()
              .append('<ul class="errorlist"><li>A link is required.</li></ul>');
            input.trigger("focus");
          } else {
            updateText(textarea, val);
            
            textarea.parent().find(".cancel-link")
              .trigger("click");
            textarea
              .trigger("paste")
              .trigger("focus");
          }
          
          return false;
        });
      }
    }
    
    
    function UploadAttachment(defaults) {
      this.defaults = jQuery.extend({
        'textarea_id': 'textarea',
        'attachment_list': '#attachment_list',
        'upload_url': '/wolmedia/upload/'
      }, defaults);
      
      var options = this.defaults,
          textarea = $("#" + options.textarea_id),
          attachment_list = $(options.attachment_list),
          wrapper = attachment_list.parent(),
          upload_url = options.upload_url,
          link = render();
          
      function render() {
        var link = $('<li><a href="#upload">Upload a photo</a></li>');
        
        attachment_list.append(link);
        link.find("a").bind('click', function (e) {
          e.preventDefault();
          
          $(e.target).hide().after('<span class="ajax-status">Loading form...</span>');
          
          loadUploadForm();
        });
      }
      
      function loadUploadForm() {
        $.get(options.upload_url, function(data) {
          attachment_list.after('<div class="form-container" />');
          attachment_list.hide()
            .parent().find(".form-container")
            .prepend(data);
          
          var upload_form = wrapper.find(".form");
          
          hide_fields(wrapper.find(".formrow_tags, .formrow_caption, .formrow_credit"));
          
          // Add an option to cancel uploading the photo
          upload_form.find(".submitrow")
            .append('or <a class="remove-link" href="#">cancel</a>');
          
          upload_form.find(".remove-link").click(function (e) {
            e.preventDefault();
            wrapper.find(".form-container").remove();
            attachment_list.show();
          });
          
          // Setup the form to submit using ajaxForm()
          wrapper.find("form").ajaxForm({
            beforeSubmit: handleRequest,
            success: handleResponse,
            url: options.upload_url,
            dataType: 'json'
          });
          
          wrapper.find(".attachment-options *").show();
          wrapper.find(".attachment-options .ajax-status").remove();
        });
      }
      
      function handleRequest() {
        wrapper.find(".submitrow").wrapInner("<span/>").find("span").toggleClass(settings.hidden_class);
        wrapper.find(".submitrow").append('<span class="ajax-status">Submitting form...</span>');
      }
      
      function handleResponse(responseText) {
        var data = responseText;
        
        wrapper.find(".ajax-status").remove();
        
        if (data['success']) {
          // Close the photo form
          textarea.closest(".formrow")
            .find(".remove-link")
            .trigger("click");
          updateText(textarea, data['url']);
          
          // This is a bit of a hack, but it connects to one of the listeners
          // on wmd in order to update the preview box.
          textarea
            .trigger("paste")
            .trigger("focus");
        } else {
          // Check the form for any error classes or messages and remove them,
          // otherwise they will be rendered twice.
          wrapper.find(".submitrow .ajax-status").remove();
          wrapper.find(".submitrow *").removeClass(settings.hidden_class);
          textarea.closest(".form")
            .find("li").removeClass("has_errors")
            .find(".errorlist").remove();
            
          // Loop over all the error messages.
          $.each(data['errors'], function(key, val) {
            var fieldError = wrapper.find('.formrow_' + key);
            var errorTxt = '<li>' + val + '</li>';
            
            fieldError.addClass("has_errors");
            fieldError.find("label")
              .after('<ul class="errorlist">' + errorTxt + '</ul>');
          });
        }
      }
    }
    
    function updateText(elem, txt) {
      var currTxt = $(elem).val();
      var newTxt = '';
      
      if (currTxt != '') {
        newTxt = currTxt + '\n\n' + txt;
      } else {
        newTxt = txt;
      }
      $(elem).val(newTxt);
    }
    
    append_attachment_list = function(fields) {
      $(fields).each(function() {
        var field = $(this),
            form = $("#" + field.closest("form").attr("id")),
            attachment_list_id = field.attr("id") +'-attachment_list',
            attachment_list = '<ul id="'+ attachment_list_id + '" class="attachment-options"></ul>';
        
        // Insert the attachment options list after the field.
        field.after(attachment_list);
        $('#' + attachment_list_id).wrap('<div class="attachment-wrapper"></div>');
        
        var photo_upload = new UploadAttachment({
          textarea_id: field.attr("id"),
          attachment_list: '#' + attachment_list_id,
          upload_url: settings.photo_upload_url
        });
        
        var attachment_link = new LinkAttachment({
          textarea_id: field.attr("id"),
          attachment_list: '#' + attachment_list_id,
          label: 'Link to a photo or video'
        });
        
        // Check to see if the element to add the list to is being hidden,
        // if it is, append the hidden class to the list wrapper div.
        if (field.hasClass(settings.hidden_class)) {
          $('#' + attachment_list_id).closest(".attachment-wrapper")
            .addClass(settings.hidden_class);
        }
      });
    };
    
    
    return this.each(function() {
      // select for form from it's ID
      var form = $("#" + $(this).attr("id"));
      var postform = form.find('.form');
      
      // Hide comment fields on each form. This is being hidden until
      // comments on post revisions are properly implemented.
      form.find(".formrow_comment").hide();
      
      // Initialize the wmd editor tools with oembed support.
      if (settings.use_wmd && !form.hasClass('no-wmd')) {
        form.find("textarea").wmd({
          preview_preprocess: get_oembed_processor()
        });
      }
      
      var hidden_fields = form.find(settings.toggle);
      
      // As long as hidden fields contain no data, hide them until opened
      if (hidden_fields.find("input, textarea").text() == '') {
        hide_fields(hidden_fields);
      }
      
      append_attachment_list(form.find("textarea"));
      
      // This handles the hiding and showing of the main post forms. This
      // could be refactored to be more portable.
      if (settings.hidden) {
        form.find('a.cancellink').click(function (e) {
          e.preventDefault();
          form.slideUp(function() {
            $(settings.selector).parent().fadeIn(function() {
              $(this).parent()
                .closest(".add_post_selector")
                .css("display", "block");
            });
          });
        });

        $(settings.selector).click(function (e) {
          var button = $(this);
          
          e.preventDefault();
          
          // Hide the clicked button so the user cannot reopen the form.
          button.closest(".add_post_selector").css("display", "none");
          
          if (button.attr('href').indexOf('#') != -1) {
            $(button.attr('href')).hide()
              .css("position", "static")
              .css("visibility", "visible")
              .show(1000);
          }
        });
      }
    });
  };
})(jQuery);

