/*--------------

NG EDITS: had to change $( to $rpm( to avoid conflict with Atlas Framework
Applies to prmPrototype.js, rpmMisc.js and rpmBlocks.js, rpmControls.js, rpmDragDrop.js, rpmEffects.js

-------------*/



// ===========================================================================
// SETTINGS
// ===========================================================================

var hoverExitDelay = 600
var slideDuration = 0.2
var lastHoverTimer = null
var lastHoverCommand = null

function clearCurrentHover() {
  if(!lastHoverTimer) return
  clearTimeout(lastHoverTimer)
  eval(lastHoverCommand)
  lastHoverTimer = null
  lastHoverCommand = null
}

function hoverEndWith(command) {
  lastHoverCommand = command
  lastHoverTimer = setTimeout(command, hoverExitDelay)
}

function showElement(element, options) {
  if($rpm(element) && !Element.visible(element)) {
    options = options || {}
    new Effect.BlindDown(element, {duration: slideDuration,
      afterFinish: function() {
        try { Element.undoClipping(element) } catch(e) {}
        $rpm(element).style.width = "auto"
        $rpm(element).style.height = "auto"
        if(options.afterFinish) options.afterFinish()
        Element.scrollTo($rpm(element))
      }})
  }
}

function hideElement(element, options) {
  if($rpm(element) && Element.visible(element)) {
    options = options || {}
    new Effect.BlindUp(element, {duration: slideDuration,
      afterFinish: function() {
        try { Element.undoClipping(element) } catch(e) {}
        Element.hide(element)
        if(options.afterFinish) options.afterFinish()
      }})
  }
}

// ===========================================================================
// NOTES BLOCK MANAGER
// ===========================================================================

var proceduresBlock = {
  show: function() {
    Element.hideIf('procedures_link_off', 'blank_slate')
    Element.showIf('procedures_link_on')
    showElement('procedures_block')
  },

  isEmpty: function() {
    return Element.empty('procedures')
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_procedure_' + id, 'edit_procedure_' + id + '_link')
        },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("proceduresBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_procedure_' + id, 'edit_procedure_' + id + '_link')
    }
  },

  hide: function() {
    Element.hideIf('procedures_link_on')
    Element.showIf('procedures_link_off')
    hideElement('procedures_block')
  },

  setReorderLink: function() {
    if (this.notesCount < 2) {
      Element.removeClassName('addprocedure', 'withreorder')
      Element.hide('reorder_procedures', 'addprocedure_separator')
    } else {
      Element.addClassName('addprocedure', 'withreorder')
      Element.show('reorder_procedures', 'addprocedure_separator')
    }
  },

  display: function(id) {
    this.show()
    Element.showIf('addprocedure')
    Element.hideIf('procedures_indicator', 'addproceduredialog')

    this.setReorderLink()

    if(id) {
      Element.hideIf('edit_procedure_' + id)
      Element.showIf('show_procedure_' + id)
      toggle_edit_link(false, 'show_procedure_' + id, 'edit_procedure_' + id + '_link')
    }
  },

  edit: {
    show: function(id) {
      proceduresBlock.show()
      if(id) {
        this.editExisting(id)
      } else {
        proceduresBlock.reorderComplete(
          document.getElementsByClassName('procedure_dragger'),
          document.getElementsByClassName('procedure_content')
        )
        this.addNew()
      }
    },

    addNew: function() {
      Element.showIf('addproceduredialog')
      Element.hideIf('addprocedure', 'procedures_indicator')
      Field.clear('new_procedure_title', 'new_procedure_count', 'new_procedure_input')
      // this bizarre little hack is to prevent FF from scrolling to the top of
      // the notes block when the new_note_title field is focused (reported by
      // Marc Hedlund)
      setTimeout("Field.focus('new_procedure_input')",10)
    },

    editExisting: function(id) {
      Element.hideIf('addprocedure', 'addproceduredialog', 'show_procedure_' + id)
      Element.showIf('edit_procedure_' + id)
      Field.focus('procedure_title_' + id)
    }
  },

  processing: function() {
    Element.showIf('procedures_indicator')
  },

  checkEmpty: function(skip_display) {
    if(this.isEmpty()) {
      this.hide()
      pageManager.checkEmpty()
      return true
    } else if(!skip_display) {
      this.display()
      return false
    }
  },

  addCompleted: function(request) {
    this.proceduresCount += 1
    /* ---- NG Edit this once async is set up  ----------*/
    id = 'note_' + request.getResponseHeader('BackpackNoteID')
    scrollWindowTo(id)
    new Effect.Highlight(id)
    this.display()
  },

  procedureDeleted: function() {
    this.proceduresCount -= 1
    this.checkEmpty()
  },

  reorder: function() {
    controls = document.getElementsByClassName('procedure_dragger')
    contents = document.getElementsByClassName('procedure_content')
    if(!controls) return

    this.makeDraggable()

    if(!Element.visible(controls[0])) {
      toggle_edit_link_possible = false
      this.reorderBegin(controls, contents)
    } else {
      toggle_edit_link_possible = true
      this.reorderComplete(controls, contents)
    }
  },

  reorderBegin: function(controls, contents) {
    Element.activate('reorder_procedures', true)
    Element.hide('add_procedure_link', 'addprocedure_separator')
    Element.showAll(controls)
    Element.hideAll(contents)
  },

  reorderComplete: function(controls, contents) {
    Element.activate('reorder_procedures', false)
    Element.show('add_procedure_link', 'addprocedure_separator')
    Element.hideAll(controls)
    Element.showAll(contents)
  },

  makeDraggable: function() {
    if ($rpm('procedures').sortable_tag) {
      return true;
    } else {
      Sortable.create('procedures', {
        tag: 'div',
        handle:'dragger',
        onUpdate:function(element) { 
          new Ajax.Request(
            noteReorderUrl,
            { parameters:Sortable.serialize('procedures'), asynchronous:true }
          )
        }
      });  
    }
  }
}











// ===========================================================================
// TAGS BLOCK MANAGER
// ===========================================================================

var tagsBlock = {
  show: function() {
    Element.hide('tag_indicator', 'add_tags')
    Element.show('tag_submit', 'add_tags_link')
    sharesBlock.displayBug()
  },

  edit: function() {
    Element.show('add_tags')
    Element.hide('tagsMatches', 'add_tags_link', 'sharing_bug')
    Field.focus('edit_tags')
  },

  display: function() {
    this.show()
  },

  showPages: function(path, id) {
    Element.hide('sharing_bug')
    Element.show('tags_spinner')
    new Ajax.Updater('tagsMatches', path + "/" + id, {asynchronous:true,
      onComplete: function() {
        Element.hide('tags_spinner')
        showElement('tagsMatches')
      }})
  },

  hidePages: function() {
    hideElement('tagsMatches',
      {afterFinish: function() { sharesBlock.displayBug() }}
    )
  }
}

// ===========================================================================
// BODY BLOCK MANAGER
// ===========================================================================

var bodyBlock = {
  show: function() {
    Element.hideIf('blank_slate_top')
    Element.showIf('body_block')

    if(this.isEmpty()) {
      Element.show('body_link_off')
      Element.hide('body_link_on')
    } else {
      Element.show('body_link_on')
      Element.hide('body_link_off')
    }
    Element.hide('body_link_edit')
  },

  isEmpty: function() {
    return Element.empty('description')
  },

  edit: function() {
    this.editing = true
    this.show()
    Element.hide('body_link_off')
    Element.show(this.isEmpty() ? 'body_link_edit' : 'body_link_on')
    Element.hide('description')
    showElement('edit_body', {afterFinish: function() {
      Field.focus('edit_description_textarea')
    }})
  },

  display: function() {
    this.editing = false
    hideElement('edit_body', {afterFinish: function() {
      bodyBlock.show()
      Element.show('description')
      toggle_edit_link(false, 'description')
    }})
  },

  toggleEdit: function() {
    if(this.editing) {
      this.display()
    } else {
      this.edit()
    }
  }
}
bodyBlock.editing = false

// ===========================================================================
// LISTS BLOCK MANAGER
// ===========================================================================

var listsBlock = {
  isEmpty: function() {
    return this.count < 1
  },

  checkEmpty: function(skip_display) {
    if(this.isEmpty()) {
      this.block.hide()
      pageManager.checkEmpty()
      return true
    } else if(!skip_display) {
      this.block.display()
      return false
    }
  },

  skip_confirm: {},

  checkCollapsable: function() {
    if(this.count < 1) {
      this.block.hide();
      pageManager.checkEmpty()
      return true
    }
    
    if(this.count == 1) {
      var lists = $rpm('lists')
      var list = lists.getElementsByTagName("DIV")[0]
      var id = parseInt(list.id.match(/\d+/))
      if(itemsBlock.isEmpty(id)) {
        this.skip_confirm[id] = true
        $rpm('delete_list_' + id + '_link').onclick()
        return true
      }
    }
    
    return false
  },

  setReorderLink: function() {
    if(this.count < 2) {
      Element.removeClassName('addlist', 'withreorder')
      Element.hide('addlist_separator', 'reorder_lists')
    } else {
      Element.addClassName('addlist', 'withreorder')
      Element.show('addlist_separator', 'reorder_lists')
    }
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_list_' + id, 'edit_list_' + id + '_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("listsBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_list_' + id, 'edit_list_' + id + '_link')
    }
  },

  block: {
    show: function() {
      Element.hideIf('lists_link_off', 'blank_slate')
      Element.showIf('lists_link_on')
      showElement('lists_block')
    },

    hide: function() {
      Element.hideIf('lists_link_on')
      Element.showIf('lists_link_off')
      hideElement('lists_block')
    },

    display: function() {
      this.show()
      listsBlock.edit.show()
    }
  },

  add: {
    before: function() {
      Element.show('lists_indicator')
      if($rpm('lists_item_indicator')) Element.show('lists_item_indicator')
    },

    failure: function(request) {
      Element.hide('lists_indicator')
      if($rpm('lists_item_indicator')) Element.hide('lists_item_indicator')
      alert("The request could not be completed. Please try again.")
    },

    success: function(request) {
      listsBlock.count += 1
      Element.hide('lists_indicator')
      if($rpm('lists_item_indicator')) Element.hide('lists_item_indicator')
      listsBlock.edit.hide()
      var list_id = request.getResponseHeader("X-List-Id")
      new Insertion.Bottom('lists', request.responseText)
      new Effect.Highlight('list_' + list_id)
      listsBlock.setReorderLink()
      itemsBlock.edit.show(list_id)
      Element.show('create_new_list')
      Element.hideIf('create_new_list_from_item')
      if(listsBlock.count == 2) {
        var first_id = $rpm('lists').getElementsByTagName("DIV")[0].id.replace(/\D/g, "")
        Element.show('list_head_' + first_id)
      }
    }
  },

  edit: {
    hide: function() {
      listsBlock.checkEmpty(true)
      Element.show('addlist')
      Element.hide('addlistdialog')
    },

    show: function(id) {
      id ? this.showList(id) : this.showAdd()
    },

    showList: function(id) {
      this.hide()
      listsBlock.hover.end(id)
      Element.hide('show_list_' + id)
      Element.show('edit_list_' + id)
      Field.focus('list_name_' + id)
    },

    showAdd: function() {
      if($rpm('lists').reordering) listsBlock.reorder.toggle()
      Element.hide('addlist')
      Element.show('addlistdialog')
      Field.focus('new_list_name')
    },

    before: function(id) {
      Element.show('save_list_' + id)
    },

    failure: function(id, request) {
      Element.hide('save_list_' + id)
      alert("There was a problem processing your request. Please try again.")
    },

    success: function(id, request) {
      new Effect.Highlight("list_head_" + id)
    }
  },

  deleted: {
    complete: function(list_id, request) {
      Element.remove('list_' + list_id)
      listsBlock.count -= 1
      listsBlock.checkCollapsable()
      listsBlock.setReorderLink()
      if(listsBlock.count == 1) {
        var first_id = $rpm('lists').getElementsByTagName("DIV")[0].id.replace(/\D/g, "")
        Element.hide('list_head_' + first_id)
      }
    }
  },

  reorder: {
    toggle: function() {
      clearCurrentHover()
      
      controls = document.getElementsByClassName('list_dragger')
      if(!controls) return
      contents = document.getElementsByClassName('list_content')

      this.makeDraggable()

      if(!$rpm('lists').reordering) {
        $rpm('lists').reordering = true
        toggle_edit_link_possible = false
        this.begin(controls, contents)
      } else {
        $rpm('lists').reordering = false
        toggle_edit_link_possible = true
        this.complete(controls, contents)
      }
    },
    
    begin: function(controls, contents) {
      Element.hide('list_add_toggle', 'addlist_separator')
      Element.activate('reorder_lists', true)
      Element.showAll(controls)
      Element.hideAll(contents)
    },

    complete: function(controls, contents) {
      Element.show('list_add_toggle', 'addlist_separator')
      Element.activate('reorder_lists', false)
      Element.hideAll(controls)
      Element.showAll(contents)
    },

    makeDraggable: function() {
      if($rpm('lists').sortable_tag) {
        return true;
      } else {
        Sortable.create('lists', {
          tag: 'div',
          handle:'dragger',
          onUpdate:function(element) { 
            new Ajax.Request(
              listsBlock.reorder.url,
              { parameters:Sortable.serialize('lists'), asynchronous:true }
            )
          }
        });  
      }
    } // makeDraggable()
  } // reorder
}

// ===========================================================================
// ITEMS BLOCK MANAGER
// ===========================================================================

var itemsBlock = {
  incompleteItemCount: {},
  completedItemCount: {},
  reorderUrls: {},

  isEmpty: function(list_id) {
    list_id = parseInt(list_id)
    return this.incompleteItemCount[list_id] == 0 &&
           this.completedItemCount[list_id] == 0
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_item_' + id, 'edit_item_' + id + '_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("itemsBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_item_' + id, 'edit_item_' + id + '_link')
    }
  },

  edit: {
    show: function(list_id, id) {
      listsBlock.block.show()
      if(id) {
        this.editExisting(list_id, id)
      } else {
        itemsBlock.reorder.complete()
        this.addNew(list_id)
      }
    },

    editExisting: function(list_id, id) {
      Element.showIf('edit_item_' + id)
      Element.hideIf('additemdialog_' + list_id, 'additem_' + list_id, 'show_item_' + id)
      Field.focus('edit_input_' + id)
    },

    addNew: function(list_id) {
      Element.hideIf('additem_' + list_id)
      Element.showIf('additemdialog_' + list_id)
      Field.focus('new_item_content_' + list_id)
    }
  },

  display: function(list_id, id) {
    listsBlock.block.show()
    Element.hide('edit_list_' + list_id)
    Element.show('show_list_' + list_id)
    Element.showIf('additem_' + list_id, 'list_edit_toggle_' + list_id)
    Element.hideIf('additemdialog_' + list_id)
    Element.activate('add_item_cancel_' + list_id, false)
    if(this.incompleteItemCount[list_id] < 2) {
      Element.hide('reorder_items_' + list_id, 'additem_separator_' + list_id)
    } else {
      Element.show('reorder_items_' + list_id, 'additem_separator_' + list_id)
    }
    if(id) {
      Element.showIf('show_item_' + id)
      Element.hideIf('edit_item_' + id, 'saving_item_' + id)
      toggle_edit_link(false, 'show_item_' + id, 'edit_item_' + id + '_link')
    }
  },

  saving: function(id) {
    Element.showIf('saving_item_' + id)
  },

  reorder: {
    setSeparator: function(list_id) {
      if(itemsBlock.incompleteItemCount[list_id] > 1) {
        Element.show('additem_separator_' + list_id)
        Element.show('reorder_items_' + list_id)
      } else {
        Element.hide('reorder_items_' + list_id)
        Element.hide('additem_separator_' + list_id)
      }
    },

    previousSiblingId: function(list_id) {
      list = $rpm('list_' + list_id)
      prev = Element.previousSibling(list, "DIV")
      return (prev ? prev.id.replace(/^list_/, "") : null)
    },
    
    nextSiblingId: function(list_id) {
      list = $rpm('list_' + list_id)
      next = Element.nextSibling(list, "DIV")
      return (next ? next.id.replace(/^list_/, "") : null)
    },
    
    getControls: function() {
      var controls = []
      for(var i = 0; i < arguments.length; i++)
        if(arguments[i])
          controls = controls.concat(
            document.getElementsByClassName('item_' + arguments[i] + '_dragger'))
      return controls
    },
    
    toggle: function(list_id) {
      if(!$rpm('lists').reorderTarget) {
        this.begin(list_id)
      } else {
        this.complete()
      }
    },

    begin: function(list_id) {
      toggle_edit_link_possible = false
      $rpm('lists').reorderTarget = list_id
      listsBlock.block.show()
    
      var prev = this.previousSiblingId(list_id)
      var next = this.nextSiblingId(list_id)
      neighbors = ['incomplete_items_list_' + list_id]    
      if(prev) neighbors.push('incomplete_items_list_' + prev)
      if(next) neighbors.push('incomplete_items_list_' + next)
      
      Element.showIf('additem_' + list_id)
      Element.showAll(this.getControls(prev, list_id, next));
      [list_id, prev, next].each(function(id) {
        if(!id) return
        itemsBlock.reorder.makeDraggable(id, neighbors)
        Element.hide('completed_items_' + id)
        Element.activate('reorder_items_' + id, true)
      })
    },

    complete: function() {
      toggle_edit_link_possible = true
      list_id = $rpm('lists').reorderTarget
      if(!list_id) return
      $rpm('lists').reorderTarget = null
      
      var prev = this.previousSiblingId(list_id)
      var next = this.nextSiblingId(list_id)

      listsBlock.block.show()
      Element.hideAll(this.getControls(prev, list_id, next));
      [list_id, prev, next].each(function(id) {
        if(!id) return
        var container = 'incomplete_items_list_' + id
        Sortable.destroy(container)
        document.getElementsByClassName("dragger", container).each(function(item) {
          item.className = "dragger item_" + id  + "_dragger"
        })
        Element.show('completed_items_' + id)
        Element.activate('reorder_items_' + id, false)
      })
    },

    makeDraggable: function(list_id, neighbors) {
      options = { 
        handle:'dragger',
        dragOnEmpty:true,
        containment:neighbors,
        onUpdate:function(container) {
          var container_id = container.id.replace(/\D/g, "")
          var list = $A(container.getElementsByTagName('LI'))
          itemsBlock.incompleteItemCount[container_id] = list.select(function(item) { return item.id }).length
          itemsBlock.reorder.setSeparator(container_id)
          var items = Sortable.serialize(container, {name: 'incomplete_items_list'})
          new Ajax.Request(
            itemsBlock.reorderUrls[container_id],
            { parameters:items, asynchronous:true }
          )
        }
      }
      Sortable.create('incomplete_items_list_' + list_id, options);  
    }
  },

  beforeAdd: function(list_id) {
    Element.show('items_indicator_' + list_id)
  },

  afterAdd: function(list_id) {
    Element.activate('add_item_cancel_' + list_id, true)
    Field.clear('new_item_content_' + list_id)
    Field.focus('new_item_content_' + list_id)
  },

  addCompleted: function(request, list_id) {
    count = this.incompleteItemCount[list_id] || 0
    this.incompleteItemCount[list_id] = count + 1
    Element.hide('items_indicator_' + list_id)
    item_id = request.getResponseHeader("BackpackItemID")
    $rpm('incomplete_items_' + list_id).innerHTML = request.responseText
    new Effect.Highlight('content_for_item_' + item_id) 
    setTimeout("$rpm('content_for_item_" + item_id + "').style.background = 'transparent'", 2100)
  },

  incompleteItemDeleted: function(list_id) {
    this.incompleteItemCount[list_id] -= 1
    listsBlock.checkCollapsable()
  },

  completedItemDeleted: function(list_id) {
    this.completedItemCount[list_id] -= 1
    listsBlock.checkCollapsable()
  }
}

// ===========================================================================
// NOTES BLOCK MANAGER
// ===========================================================================

var notesBlock = {
  show: function() {
    Element.hideIf('notes_link_off', 'blank_slate')
    Element.showIf('notes_link_on')
    showElement('notes_block')
  },

  isEmpty: function() {
    return Element.empty('notes')
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_note_' + id, 'edit_note_' + id + '_link')
        },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("notesBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_note_' + id, 'edit_note_' + id + '_link')
    }
  },

  hide: function() {
    Element.hideIf('notes_link_on')
    Element.showIf('notes_link_off')
    hideElement('notes_block')
  },

  setReorderLink: function() {
    if (this.notesCount < 2) {
      Element.removeClassName('addnote', 'withreorder')
      Element.hide('reorder_notes', 'addnote_separator')
    } else {
      Element.addClassName('addnote', 'withreorder')
      Element.show('reorder_notes', 'addnote_separator')
    }
  },

  display: function(id) {
    this.show()
    Element.showIf('addnote')
    Element.hideIf('notes_indicator', 'addnotedialog')

    this.setReorderLink()

    if(id) {
      Element.hideIf('edit_note_' + id)
      Element.showIf('show_note_' + id)
      toggle_edit_link(false, 'show_note_' + id, 'edit_note_' + id + '_link')
    }
  },

  edit: {
    show: function(id) {
      notesBlock.show()
      if(id) {
        this.editExisting(id)
      } else {
        notesBlock.reorderComplete(
          document.getElementsByClassName('note_dragger'),
          document.getElementsByClassName('note_content')
        )
        this.addNew()
      }
    },

    addNew: function() {
      Element.showIf('addnotedialog')
      Element.hideIf('addnote', 'notes_indicator')
      Field.clear('new_note_title', 'new_note_body')
      // this bizarre little hack is to prevent FF from scrolling to the top of
      // the notes block when the new_note_title field is focused (reported by
      // Marc Hedlund)
      setTimeout("Field.focus('new_note_title')",10)
    },

    editExisting: function(id) {
      Element.hideIf('addnote', 'addnotedialog', 'show_note_' + id)
      Element.showIf('edit_note_' + id)
      Field.focus('note_title_' + id)
    }
  },

  processing: function() {
    Element.showIf('notes_indicator')
  },

  checkEmpty: function(skip_display) {
    if(this.isEmpty()) {
      this.hide()
      pageManager.checkEmpty()
      return true
    } else if(!skip_display) {
      this.display()
      return false
    }
  },

  addCompleted: function(request) {
    this.notesCount += 1
    id = 'note_' + request.getResponseHeader('BackpackNoteID')
    scrollWindowTo(id)
    new Effect.Highlight(id)
    this.display()
  },

  noteDeleted: function() {
    this.notesCount -= 1
    this.checkEmpty()
  },

  reorder: function() {
    controls = document.getElementsByClassName('note_dragger')
    contents = document.getElementsByClassName('note_content')
    if(!controls) return

    this.makeDraggable()

    if(!Element.visible(controls[0])) {
      toggle_edit_link_possible = false
      this.reorderBegin(controls, contents)
    } else {
      toggle_edit_link_possible = true
      this.reorderComplete(controls, contents)
    }
  },

  reorderBegin: function(controls, contents) {
    Element.activate('reorder_notes', true)
    Element.hide('add_note_link', 'addnote_separator')
    Element.showAll(controls)
    Element.hideAll(contents)
  },

  reorderComplete: function(controls, contents) {
    Element.activate('reorder_notes', false)
    Element.show('add_note_link', 'addnote_separator')
    Element.hideAll(controls)
    Element.showAll(contents)
  },

  makeDraggable: function() {
    if ($rpm('notes').sortable_tag) {
      return true;
    } else {
      Sortable.create('notes', {
        tag: 'div',
        handle:'dragger',
        onUpdate:function(element) { 
          new Ajax.Request(
            noteReorderUrl,
            { parameters:Sortable.serialize('notes'), asynchronous:true }
          )
        }
      });  
    }
  }
}

// ===========================================================================
// EMAILS BLOCK MANAGER
// ===========================================================================

var emailsBlock = {
  isEmpty: function() {
    return !$rpm('emails') || Element.empty('emails')
  },

  hide: function() {
    hideElement('emails')
  },

  display: function() {
    showElement('emails')
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_email_' + id, 'edit_email_' + id + '_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("emailsBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_email_' + id, 'edit_email_' + id + '_link')
    }
  },

  checkEmpty: function() {
    if(this.isEmpty()) {
      this.hide()
      pageManager.checkEmpty()
      return true
    } else {
      this.display()
      return false
    }
  }
}

// ===========================================================================
// ATTACHMENTS BLOCK MANAGER
// ===========================================================================

var filesBlock = {
  isEmpty: function() {
    return !$rpm('attachments')
  },

  show: function() {
    Element.hideIf('attachments_link_off', 'blank_slate')
    Element.showIf('attachments_link_on')
    showElement('attachments_block')
  },

  hide: function() {
    Element.hideIf('attachments_link_on')
    Element.showIf('attachments_link_off')
    hideElement('attachments_block')
  },

  display: function(id) {
    this.show()
    Element.showIf('addfile')
    Element.hideIf('addfiledialog')
    if(id) {
      Element.show('file_details_' + id)
      Element.hide('file_rename_' + id)
      Element.hide('edit_attachment_' + id + '_link')
      toggle_edit_link(false, 'show_attachment_' + id,
        'edit_attachment_' + id + '_link')
    }
  },

  edit: {
    show: function() {
      filesBlock.show()
      Element.hideIf('addfile')
      Element.showIf('addfiledialog')
    }
  },

  hover: {
    begin: function(id) {
      if(Element.visible('file_rename_' + id)) return
      clearCurrentHover()
      toggle_edit_link(true, 'show_attachment_' + id,
        'edit_attachment_' + id + '_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("filesBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_attachment_' + id,
          'edit_attachment_' + id + '_link')
    }
  },

  checkEmpty: function(skip_display) {
    if(this.isEmpty()) {
      this.hide()
      pageManager.checkEmpty()
      return true
    } else if(!skip_display) {
      this.display()
      return false
    }
  },

  rename: function(id) {
    Element.hide('file_details_' + id)
    Element.show('file_rename_' + id)
    toggle_edit_link(false, 'show_attachment_' + id,
      'edit_attachment_' + id + '_link')
  },

  hideConditions: function() {
    Element.hideIf('file_conditions')
    this.checkEmpty()
  },

  beforeUpload: function() {
    showElement('uploadStatusContainerForAttachments')
  },

  afterUpload: function(list_url) {
    new Ajax.Updater(
      { success:'attachments_block' }, 
      list_url, 
      { onComplete:function(request) { filesBlock.checkEmpty() }, asynchronous: true }
    )
    hideElement('uploadStatusContainerForAttachments')
  }
}

// ===========================================================================
// IMAGES BLOCK MANAGER
// ===========================================================================

var imagesBlock = {
  isEmpty: function() {
    return !$rpm('images')
  },

  show: function() {
    Element.hideIf('images_link_off', 'blank_slate')
    Element.showIf('images_link_on')
    showElement('images_block')
  },

  hide: function() {
    Element.hideIf('images_link_on')
    Element.showIf('images_link_off')
    hideElement('images_block')
  },

  display: function(id) {
    this.show()
    Element.showIf('addimage')
    Element.hideIf('addimagedialog')
    if(id) {
      Element.showIf('edit_image_' + id + '_link', 'image_description_' + id)
      Element.hideIf('edit_image_' + id)
      toggle_edit_link(false, 'show_image_' + id, 'edit_image_' + id + '_link')
    }
  },

  edit: {
    show: function(id) {
      imagesBlock.show()
      if(id) {
        this.editExisting(id)
      } else {
        this.addNew()
      }
    },

    editExisting: function(id) {
      Element.hideIf('addimage', 'addimagedialog')
      Element.hideIf('edit_image_' + id + '_link', 'image_description_' + id)
      Element.showIf('edit_image_' + id)
      Field.focus('edit_image_' + id + '_input')
    },

    addNew: function() {
      Element.hideIf('addimage')
      Element.showIf('addimagedialog')
    }
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_image_' + id, 'edit_image_' + id + '_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("imagesBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_image_' + id, 'edit_image_' + id + '_link')
    }
  },

  checkEmpty: function(skip_display) {
    if(this.isEmpty()) {
      this.hide()
      pageManager.checkEmpty()
      return true
    } else if(!skip_display) {
      this.display()
      return false
    }
  },

  hideConditions: function() {
    Element.hideIf('image_conditions')
    this.checkEmpty()
  }
}

// ===========================================================================
// LINKS BLOCK MANAGER
// ===========================================================================

var linksBlock = {
  isEmpty: function() {
    return Element.empty('links')
  },

  show: function() {
    Element.hideIf('links_link_off', 'blank_slate')
    Element.showIf('links_link_on')
    showElement('links_block')
  },

  hide: function() {
    Element.hideIf('links_link_on')
    Element.showIf('links_link_off')
    hideElement('links_block')
  },

  display: function() {
    this.show()
    Element.showIf('addlink')
    Element.hideIf('addlinkdialog')
  },

  edit: {
    show: function() {
      linksBlock.show()
      Element.hideIf('addlink')
      Element.showIf('addlinkdialog')
    }
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_link_' + id, 'edit_link_' + id + '_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("linksBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_link_' + id, 'edit_link_' + id + '_link')
    }
  },

  checkEmpty: function(skip_display) {
    if(this.isEmpty()) {
      this.hide()
      pageManager.checkEmpty()
      return true
    } else if(!skip_display) {
      this.display()
      return false
    }
  }
}

// ===========================================================================
// SHARES BLOCK MANAGER
// ===========================================================================

var sharesBlock = {
  isEmpty: function() {
    return Element.empty('shares')
  },

  show: function() {
    Element.hideIf('shares_link_off', 'blank_slate')
    Element.showIf('shares_link_on')
    showElement('shares_block')
    this.displayBug()
  },

  displayBug: function() {
    if(this.isEmpty())
      Element.hideIf('sharing_bug')
    else
      Element.showIf('sharing_bug')
  },

  hide: function() {
    Element.hideIf('shares_link_on', 'sharing_bug')
    Element.showIf('shares_link_off')
    hideElement('shares_block')
  },

  display: function() {
    this.show()
    Element.showIf('addshare')
    Element.hideIf('addsharedialog')
  },

  edit: {
    show: function() {
      sharesBlock.show()
      Element.hideIf('addshare')
      Element.showIf('addsharedialog')
    }
  },

  hover: {
    beginShare: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_share_' + id, 'edit_share_' + id + '_link')
    },

    endShare: function(id, delay) {
      if(delay)
        hoverEndWith("sharesBlock.hover.endShare(" + id + ")")
      else
        toggle_edit_link(false, 'show_share_' + id, 'edit_share_' + id + '_link')
    },

    beginInvite: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_invitation_' + id, 'edit_invitation_' + id + '_link')
    },

    endInvite: function(id, delay) {
      if(delay)
        hoverEndWith("sharesBlock.hover.endInvite(" + id + ")")
      else
        toggle_edit_link(false, 'show_invitation_' + id, 'edit_invitation_' + id + '_link')
    }
  },

  checkEmpty: function(skip_display) {
    if(this.isEmpty()) {
      this.hide()
      pageManager.checkEmpty()
      return true
    } else if(!skip_display) {
      this.display()
      return false
    }
  }
}

// ===========================================================================
// PAGE MANAGER
// ===========================================================================

pageManager = {
  isEmpty: function() {
    return listsBlock.isEmpty() &&
           notesBlock.isEmpty() &&
           emailsBlock.isEmpty() &&
           filesBlock.isEmpty() &&
           imagesBlock.isEmpty() &&
           linksBlock.isEmpty() &&
           sharesBlock.isEmpty() &&
           writeboardsBlock.isEmpty()
  },

  checkEmpty: function() {
    if(this.isEmpty()) Element.showIf('blank_slate')
  },

  hover: {
    begin: function() {
      clearCurrentHover()
      toggle_edit_link(true, 'page_title', 'edit_title_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("pageManager.hover.end()")
      else
        toggle_edit_link(false, 'page_title', 'edit_title_link')
    }
  },

  edit: {
    show: function() {
      Element.show('edit_title')
      Element.hide('page_title', 'sharing_bug')
      Field.focus('edit_title_input')
    }
  },

  beforeSaveTitle: function() {
    Element.show('title_indicator')
  },

  display: function() {
    Element.hide('edit_title', 'title_indicator')
    Element.show('page_title')
    sharesBlock.displayBug()
    toggle_edit_link(false, 'page_title', 'edit_title_link')
  },

  titleUpdated: function(request, id) {
    this.display()
    new Effect.Highlight("page_title")
    var sidebar = $rpm('page_'+id)
    if(sidebar) sidebar.innerHTML = request.getResponseHeader("PageTitle")
  }
}

// ===========================================================================
// REMINDERS MANAGER
// ===========================================================================

remindersManager = {
  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_reminder_'+id, 'edit_reminder_'+id+'_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("remindersManager.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_reminder_'+id, 'edit_reminder_'+id+'_link')
    }
  },

  edit: {
    show: function(id) {
      Element.show('edit_reminder_' + id)
      Element.hide('show_reminder_' + id)
      Field.focus('reminder_content_' + id)
    }
  },

  display: function(id, keep_transient) {
    Element.show('show_reminder_' + id)
    Element.hide('edit_reminder_' + id)
    if(!keep_transient) $rpm('transient_' + id).value = "0"
    toggle_edit_link(false, 'show_reminder_'+id, 'edit_reminder_'+id+'_link')
  },

  afterAdd: function() {
  },

  addCompleted: function(request) {
    Element.hide('reminder_indicator')

    if(request.status == 200) {
      Field.clear('new_reminder_content')
      $rpm('period').selectedIndex = 0
      Field.focus('new_reminder_content')
      Element.hideIf('blank_slate')
      this.capCheck(request)
    } else if(this.errorCheck(request)) {
      Field.focus("new_reminder_content")
    }
  },

  editCompleted: function(id, request) {
    if(!this.errorCheck(request)) {
      this.display(id, true)
    }
  },

  errorCheck: function(request) {
    if(request.status != 200) {
      var error = request.getResponseHeader("X-Error")
      if(error == "PAST") {
        alert("Please specify a date in the future.")
      } else {
        alert("Your request could not be processed. Please try again.")
      }
      return true
    }
    
    return false
  },

  capCheck: function(request) {
    var capped = (request.getResponseHeader("RemindersCapped") == "YES")
    if(capped) {
      Element.hide('set_a_reminder')
      Element.show('reminder_cap')
    } else {
      Element.show('set_a_reminder')
      Element.hideIf('reminder_cap')
    }
  }
}

// ===========================================================================
// WRITEBOARDS MANAGER AND BLOCK
// ===========================================================================

/*
Object.prototype.inspect = function(){
  var info = [];
  for(property in this)
    if(typeof this[property]!="function") 
      info.push(property + ' => "' + this[property] + '"');
  return ("'" + this + "' #" + typeof this + 
    ": {" + info.join(", ") + "}");
}
*/

writeboardsManager = {
  afterComplete: function(request, origin) {
    this.login(request.getResponseHeader("login_url"), request.getResponseHeader("password"))
  },

  login: function(login_url, password) {
    $rpm('login_form').action    = login_url
    $rpm('login_password').value = password
    $rpm('login_form').submit()
  },

  importer: {
    complete: function(request) {
      Element.hide('import_writeboard_indicator')
    },

    success: function(request) {
      Field.clear('import_url', 'import_password')
      Element.hide('blank_slate')
      Element.toggle('newWriteboardBlock', 'importWriteboardBlock')
    },

    on409: function(request) {
      Flash.show('alert',
        'You can not create more Writeboards before you upgrade.')
    },

    on404: function(request) {
      Flash.show('alert',
        'Import failed. Did you enter the right password?')
    }
  }
}

var writeboardsBlock = {
  isEmpty: function() {
    return Element.empty('writeboards')
  },

  hover: {
    begin: function(id) {
      clearCurrentHover()
      toggle_edit_link(true, 'show_writeboard_' + id, 'edit_writeboard_' + id + '_link')
    },

    end: function(id, delay) {
      if(delay)
        hoverEndWith("writeboardsBlock.hover.end(" + id + ")")
      else
        toggle_edit_link(false, 'show_writeboard_' + id, 'edit_writeboard_' + id + '_link')
    }
  },

  show: function() {
    Element.hideIf('writeboards_link_off', 'blank_slate')
    Element.showIf('writeboards_block', 'writeboards_link_on')
  },

  edit: {
    show: function() {
      writeboardsBlock.show()
      Element.hideIf('addwriteboard')
      Element.showIf('addwriteboarddialog')
    }
  },

  hide: function() {
    Element.hideIf('writeboards_block', 'writeboards_link_on')
    Element.showIf('writeboards_link_off')
  },

  display: function() {
    this.show()
    Element.showIf('addwritebord')
    Element.hideIf('addwriteboarddialog')
  },

  checkEmpty: function(skip_display) {
    if($rpm('lists_block')) {
      if(this.isEmpty()) {
        this.hide()
        pageManager.checkEmpty()
        return true
      } else if(!skip_display) {
        this.display()
        return false
      }
    } else {
      if(this.isEmpty()) {
        Element.show('blank_slate')
      } else {
        Element.hide('blank_slate')
      }
    }
  }
}

// ===========================================================================
// FLASH
// ===========================================================================
var Flash = {
  show: function(type, text) {
    $rpm('flash').className = type
    $rpm('flash').innerHTML = text

    if (type == 'progress') {
      $rpm('flash').innerHTML += "&hellip;"
    }

    if (!Element.visible('flash')) {
      new Effect.Appear('flash')
    }

    if (type == 'notice' || type == 'alert') {
      setTimeout((function() { new Effect.Fade('flash') }).bind(this), type == 'notice' ? 2000 : 5000);
    }
  }
}

