   addEmojiButton "licking-lips", "/images/emoji/ziggy/licking-lips.gif"
   addEmojiButton "deal-with-it", "/images/emoji/ziggy/deal-with-it.gif"
 
-  # Uploads
-  uploadBanner = (file) -> "[Uploading \"#{file.name}\"...]"
-
-  startUpload = (file) ->
-    replaceSelection("", uploadBanner(file) + "\n", "")
-
-  finishUpload = (file, response) ->
-    replacedText = $(textarea).val().replace(uploadBanner(file), decorator.image(response.url).join(""))
-    $(textarea).val(replacedText)
-
-  if Sugar.Configuration.uploads
-    $(textarea).filedrop
-      allowedfiletypes: ['image/jpeg', 'image/png', 'image/gif']
-      maxfiles: 25
-      maxfilesize: 2
-      paramname: "upload[file]"
-      url: "/uploads.json"
-      headers:
-        "X-CSRF-Token": Sugar.authToken($(textarea).closest("form"))
-      uploadStarted: (i, file, len) ->
-        startUpload file
-      uploadFinished: (i, file, response, time) ->
-        finishUpload file, response
-
-  textarea.richtext = true
-
+  bindUploads(textarea, decorator) if Sugar.Configuration.uploads
 
 $(Sugar).bind 'ready modified', ->
   $('textarea.rich').each -> new Sugar.RichTextArea(this)

Sugar.RichTextArea = (textarea, options) ->

  return this if textarea.richtext

  markdownDecorator =
    bold: (str)       -> ["**", str, "**"]
    emphasis: (str)   -> ["_", str, "_"]
    link: (url, name) -> ["[", name, "](#{url})"]
    image: (url)      -> ["![](", url, ")"]
    blockquote: (str) -> ["", ("> " + line for line in str.split("\n")).join("\n"), ""]
    spoiler: (str)    -> ["<div class=\"spoiler\">", str, "</div>"]

    code: (str, language) ->
      ["```#{language}\n", str, "\n```"]

    quote: (text, html, username, permalink) ->
      wrapInBlockquote = (str) ->
        ("> " + line for line in str.split("\n")).join("\n")
      cite = if permalink
        "Posted by [#{username}](#{permalink}):"
      else
        "Posted by #{username}:"
      quotedPost = wrapInBlockquote("<cite>#{cite}</cite>\n\n#{html}")
      ["", quotedPost + "\n\n", ""]

  htmlDecorator =
    bold: (str)       -> ["<b>", str, "</b>"]
    emphasis: (str)   -> ["<i>", str, "</i>"]
    link: (url, name) -> ["<a href=\"#{url}\">", name, "</a>"]
    image: (url)      -> ["<img src=\"", url, "\">"]
    blockquote: (str) -> ["<blockquote>", str, "</blockquote>"]
    spoiler: (str)    -> ["<div class=\"spoiler\">", str, "</div>"]

    code: (str, language) ->
      ["```#{language}\n", str, "\n```"]

    quote: (text, html, username, permalink) ->
      cite = if permalink
        "Posted by <a href=\"#{permalink}\">#{username}</a>:"
      else
        "Posted by #{username}:"
      content = html.replace(/\n/g, "").replace(/<br[\s\/]*>/g, "\n")
      quotedPost = "<blockquote><cite>#{cite}</cite>#{content}</blockquote>"
      ["", quotedPost + "\n\n", ""]

  decorator = markdownDecorator

  if $(textarea).data('formats')
    formats = $(textarea).data('formats').split(" ")

    name = if selection.length > 0 then selection else "Link text"
    url = if url.length > 0 then url else "http://example.com/"
    url = url.replace(/^(?!(f|ht)tps?:\/\/)/, 'http://')
    decorator().link(url, name)

  # Image tag
  addButton "Image", "picture", (selection) ->
    url = if selection.length > 0 then selection else prompt("Enter image URL", "")
    decorator().image(url)

  # Block Quote
  addButton "Block Quote", "quote-left", (selection) -> decorator().blockquote(selection)

  # Code button
  addButton "Code", "code", (selection) ->
    lang = prompt("Enter language (leave blank for no syntax highlighting)", "")
    decorator().code(selection, lang)

  # Spoiler button
  addButton "Spoiler", "warning-sign", (selection) -> decorator().spoiler(selection)

  # Emoticons
  addButton "Emoticons", "smile", (selection) ->
