App = {
  onload: function(cb){
    var self = this
    jQuery(function($){
      cb.apply(self, [self])
    })
  },
  
  init: function(opts) {
    this.current_person = {
      id: (opts.current_person_id || null)
    }
    
    this.initUserInfo()
    
    $('#search-members input[type!=submit][title]').innerLabel()
    $('#filter-members input[type!=submit][title]').innerLabel()
    $('#person-menu input[type!=submit][title]').innerLabel()
    $('#newsletter-block input[type!=submit][title]').innerLabel()
    $('#newsletter-floating-block input[type!=submit][title]').innerLabel()
    
    this.animateNotice()
    
    if (this.current_person.admin)
    {
      this.initPageContentBlocks()
      this.initDblClickByHover()
    }
  },
  
  expandCutText: function(ahref, id) {
    var ahref = $(ahref)
    var div = $("#" + id)
    ahref.after(div.html())
    div.remove()
    ahref.hide()
    return false
  },
  
  initDblClickByHover: function(delay){
    var delay = delay || 1000
    var hoverFor = function(block, links)
    {
      var reset = function() {
        var a = $(this)
        var t = a.data("hover-timeout")
        a.removeData("hover-timeout")
        if (t) clearTimeout(t)
      }
      links.hover(function() {
        var a = $(this)
        var t = a.data("hover-timeout")
        if (!t)
        {
          t = setTimeout(function() { block.dblclick() }, delay)
          a.data("hover-timeout", t)
        }
      }, reset)
      links.click(reset)
      links.dblclick(reset)
      block.click(reset)
      block.dblclick(reset)
    }
    
    $(".page-content-chunk:has(a)").each(function(){
      hoverFor($(this), $("a", $(this)))
    })
    $("a > .page-content-chunk").each(function(){
      hoverFor($(this), $(this).parent())
    })
  },
  
  initUserInfo: function() {
    var form = $('#current-person-info')
    this.current_person.id    = $("input[name=current-person-id]", form).val() || null
    this.current_person.admin = $("input[name=current-person-admin]", form).val() == "1" || null
  },
  
  animateNotice: function(){
    $("#user-notice").hide().fadeIn("slow", function(){
      var e = $(this)
      setTimeout(function() { e.fadeOut("slow") }, 2000);
    })
  },
  
  showNotice: function(msg) {
    // placeholder is present when no notice generated on server side
    $("#user-notice-placeholder").attr("id", "user-notice")
    $("#user-notice").text(msg)
    this.animateNotice()
  },
  
  initPageContentBlocks: function(){
    
    $(".empty-page-content").css("display","inline")
    
    var rawToEditable = function(html) {
      return html.replace(/[\s\r\n]+/ig, " ").
                  replace(/<br\s*\/?>/ig, "\n").
                  replace(/<!--.*-->/ig, "").
                  replace(/(<\/?(li|ul|ol)>)/ig, "$1\n")
    }
    var editableToRaw = function(text) {
      return text.replace(/(<\/?(li|ul|ol)>)[\s\r\n]+/ig, "$1").
                  replace(/\n/ig, "<br/>")
    }    
    
    var biggerButNotVeryMuch = function(v1, v2, coef) {
      return (v2 > v1 && v2 < v1*(1 + (coef || 0.1))) ? v2 : v1;
    }
    
    $(".page-content-chunk").dblclick(function(){
      
      var block    = $(this)
      var block_id = block.attr("id").replace(/^pcc-/, "")
      
      var editor   = $("#page-content-template form").clone()
      var textarea = $('textarea', editor)
      
      $('body').append(editor)
      
      // prevent repeated dblclick-driven object creation
      // submit on double click
      editor.dblclick(function(){
        $(this).submit()
        return false
      })
      
      var container = block.parent()
      
      var css_parent = container
      
      if (this.tagName != "DIV") 
      {
        textarea.css({
          "font-family":      css_parent.css("font-family"),
          "font-size":        css_parent.css("font-size"),
          "font-weight":      css_parent.css("font-weight"),
          "text-transform":   css_parent.css("text-transform"),
          "text-align":       css_parent.css("text-align"),
          "letter-spacing":   css_parent.css("letter-spacing")
        })
      }
      
      // original width and height
      var b = block.is(":only-child") ? container : block;
      var bw = b.width()
      var bh = b.height()
      
      var forceCSS = function(elem, prop) {
      	return elem[0] && parseInt(jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
      }
      
      var resizeCallback = function() {
        editor.css("width",  (Math.max(b.width(),  bw)  + 3) + "px")
        editor.css("height", (Math.max(b.height(), bh)  + 0) + "px")
        var offset = b.offset()
        // padding adjust
        var top  = offset.top  + forceCSS(b, "paddingTop")
        var left = offset.left + forceCSS(b, "paddingLeft")
        editor.css({ top: top, left: left })
      }
      resizeCallback()
      
      var autoresizer = function() {
        var html = editableToRaw(textarea.val())
        block.html(html.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;") + " &nbsp;")
        resizeCallback()
      }
      var autoresizer_t = setInterval(autoresizer, 100)
      
      // remove empty marker before giving inner html away
      $(".empty-page-content", block).remove()
      var html = block.html()
      
      textarea.val(rawToEditable(html))
      textarea.focus()
      textarea.select()
      
      $(window).bind("resize", resizeCallback)
      textarea.blur(function(){
        editor.submit()
      })
      
      editor.submit(function(){
        // release resources
        $(window).unbind("resize", resizeCallback)
        clearInterval(autoresizer_t)
        
        // update data
        var html = $.trim(editableToRaw($.trim(textarea.val())))
        block.html(html != "" ? html : "<span class=\"empty-page-content\" style=\"display:inline\">— empty —</span>")
        // TODO: ajax update request with (html)
        $.post( 
          editor.attr("action").replace(/:id/, block_id),
          {
            _method: "put",
            id:       block_id,
            body:     html
          }, 
          function(data, textStatus){
            App.showNotice("Text was saved!")
          },
          "json"
        )
        $(this).remove()
        return false
      }) // editor.submit
      
      return false
      
    }) // $(".page-content-chunk")
  } // initPageContentBlocks
   
}

App.onload(function(){ 
   this.init({}) 
})
