var Parrocchia = {
  
  changeColor: function(color, delta) {
    color = color.parseColor();
    var rgb = $R(0,2).map(function(i) {
      return parseInt(color.slice(i * 2 + 1, i * 2 + 3), 16);
    });
    var newRgb = rgb.map(function(x) {
      return Math.max(0, Math.min(parseInt(x) + delta, 255));
    });
    var newColor = $R(0,2).inject('#', function(m, v, i) {
      return m + newRgb[i].toColorPart();
    });
    return newColor;
  }
  
};
Parrocchia.AbstractMenu = Class.create(AbstractControl, {
  
  initialize: function($super, element, sito, layout, options) {
    this.sito = sito;
    this.layout = layout;
    var opt = {
      highlightDelta: 30
    };
    Object.extend(opt, options || {});
    $super(element, opt);
  },
  
  initDomReferences: function($super) {
    $super();
    this.ul = this.element.down('ul');
    if (this.ul) {
      this.liElements = this.ul.select('li');
      this.idCategorie = this.liElements.map(function(li) {
        return this.extractIdCategoria(li.id);
      }, this);
    }
  },
  
  addEventHandlers: function($super) {
    $super();
    this.element.observe('mouseover', this.handleOver.bindAsEventListener(this));
    this.element.observe('mouseout', this.handleOut.bindAsEventListener(this));
    this.liElements.each(function(li) {
      if (!li.id.endsWith('_new')) li.observe('click', this.handleClick.bindAsEventListener(this));
    }, this);
    this.categoriaChangedHandler = this.handleCategoriaChanged.bind(this);
    Pagina.registerCategoriaChangedHandler(this.categoriaChangedHandler);
  },
  
  removeEventHandlers: function($super) {
    $super();
    this.element.stopObserving('mouseover');
    this.element.stopObserving('mouseout');
    this.liElements.each(function(li) {
      if (!li.id.endsWith('_new')) li.stopObserving('click');
    }, this);
    Pagina.unregisterCategoriaChangedHandler(this.categoriaChangedHandler);
  },
  
  handleOver: function(e) {
    var li = e.element();
    if (!this.liElements.include(li)) return;
    li.fire('item:over');
    var idCategoria = this.extractIdCategoria(li.id);
    if (idCategoria != this.idCategoriaAttiva) {
      this.doHighlight(li);
    }
  },
  
  handleOut: function(e) {
    var li = e.element();
    if (!this.liElements.include(li)) return;
    li.fire('item:out');
    var idCategoria = this.extractIdCategoria(li.id);
    if (idCategoria != this.idCategoriaAttiva) {
      this.undoHighlight(li);
    }
  },
  
  handleClick: function(e) {
    var li = e.element();
    var idCategoria = this.extractIdCategoria(li.id);
    this.setIdCategoriaAttiva(idCategoria);
  },

  handleCategoriaChanged: function() {
    if (Pagina.sito != this.sito || Pagina.layout != this.layout) this.dispose();
    else {
      this.liElements.each(function(li) {
        this.undoHighlight(li);
      }, this);
      delete this.idCategoriaAttiva;
      Pagina.path.each(function(idCategoria) {
        this.setIdCategoriaAttiva(idCategoria, true);
      }, this);
    }
  },

  extractIdCategoria: function(s) {
    return String(s).replace(/^.*_categoria(\d+).*$/, '$1');
  },
  
  doHighlight: function(li) {
    if (li._highlighted) return;
    this.highlight(li, +this.options.highlightDelta);
    li._highlighted = true;
  },
  
  undoHighlight: function(li) {
    if (!li._highlighted) return;
    this.highlight(li, -this.options.highlightDelta);
    li._highlighted = false;
  },
  
  highlight: function(li, delta) {
    var color = li.getStyle('background-color');
    var newColor = color != 'transparent' ? Parrocchia.changeColor(color, delta) : color;
    li.setStyle({ 'backgroundColor': newColor });
  },
  
  setIdCategoriaAttiva: function(idCategoria, preventEvent) {
    var li = this.findElement(idCategoria);
    if (!li) return false;
    this.selectElement(li);
    //this.ul.setStyle({ 'background': li.getStyle('background-color') });
    var changed = idCategoria != this.idCategoriaAttiva;
    if (changed) {
      if (this.idCategoriaAttiva) {
        var liPrevious = this.findElement(this.idCategoriaAttiva);
        if (liPrevious) this.undoHighlight(liPrevious);
      }
      this.idCategoriaAttiva = idCategoria;
    }
    if (!preventEvent) this.element.fire('item:selected', this.idCategoriaAttiva);
    return changed;
  },
  
  findElement: function(idCategoria) {
    return this.liElements && this.liElements.find(function(li) {
      return this.extractIdCategoria(li.id) == idCategoria;
    }, this);
  },
  
  selectElement: function(li) {
    this.doHighlight(li);
  }
  
});
Parrocchia.Menu1 = Class.create(Parrocchia.AbstractMenu, {

  initialize: function($super, element, sito, layout, options) {
    var opt = {
      reloadUrl: 'parrocchia/menu1/reload.html'
    };
    Object.extend(opt, options || {});
    $super(element, sito, layout, opt);
  },

  initDomReferences: function($super) {
    $super();
    this.bottom = this.element.down('.bottom');
  },

  init: function($super, response) {
    $super(response);
    var w = this.element.up().getDimensions().width;
    var d = parseInt(w / this.liElements.length);
    var m = w % this.liElements.length;
    this.liElements.each(function(li, index) {
      li.setStyle({ width: (d + (index < m ? 1 : 0)) + 'px' });
    });
    this.element.setStyle({ visibility: 'visible' });
  },

  selectElement: function($super, li) {
    $super(li);
    this.bottom.setStyle({ background: li.getStyle('background-color') });
  }

});
Parrocchia.Menu2 = Class.create(Parrocchia.AbstractMenu, {

  initialize: function($super, element, sito, layout, livello, idCategoriaPadre, options) {
    this.livello = livello;
    this.idCategoriaPadre = idCategoriaPadre;
    var opt = {
      reloadUrl: 'parrocchia/menu2/reload.html'
    };
    Object.extend(opt, options || {});
    $super(element, sito, layout, opt);
  },

  handleCategoriaChanged: function($super) {
    $super();
    if (Pagina.sito == this.sito && Pagina.layout == this.layout) {
      var idCategoriaPadre = Pagina.path[this.livello - 1];
      if (idCategoriaPadre != this.idCategoriaPadre) this.reload({ idCategoria: Pagina.idCategoria });
    }
  }

});
Parrocchia.Sottomenu = Class.create(Parrocchia.AbstractMenu, {
  
  initialize: function($super, element, sito, layout, idCategoriaPadre, options) {
    this.idCategoriaPadre = idCategoriaPadre;
    var opt = {
      reloadUrl: 'parrocchia/sottomenu/reload.html'
    };
    Object.extend(opt, options || {});
    $super(element, sito, layout, opt);
  },
  
  initDomReferences: function($super) {
    $super();
    this.liParent = this.parent.findElement(this.idCategoriaPadre);
  },
  
  addEventHandlers: function($super) {
    $super();
    this.liParent.observe('item:over', function() {
      if (this.hideTimer) {
        clearTimeout(this.hideTimer);
        this.hideTimer = null;
      }
      this.show();
    }.bind(this));
    this.liParent.observe('item:out', function() {
      if (!this.hideTimer) this.hideTimer = setTimeout(this.hide.bind(this), 100);
    }.bind(this));
  },
  
  removeEventHandlers: function($super) {
    $super();
    this.liParent.stopObserving('item:over');
    this.liParent.stopObserving('item:out');
  },
  
  show: function() {
    var ul = this.element.down('ul');
    if (ul.firstChild) {
      this.element.clonePosition(this.liParent, { setWidth: false, setHeight: false, offsetLeft: this.liParent.getWidth() - 5 });
      this.element.setStyle({ display: 'block' });
      this.element.clonePosition(ul, { setLeft: false, setTop: false });
    }
  },
  
  handleOver: function($super, e) {
    $super(e);
    if (this.hideTimer) {
      clearTimeout(this.hideTimer);
      this.hideTimer = null;
    }
  },
  
  handleOut: function($super, e) {
    $super(e);
    if (!this.hideTimer) this.hideTimer = setTimeout(this.hide.bind(this), 100);
  },
  
  hide: function() {
    this.hideTimer = null;
    this.element.setStyle({ display: 'none' });
  }
  
});
Parrocchia.ShowHideAppuntamenti = Class.create({

  initialize: function(el) {
    this.el = $(el);
    this.initDomReferences();
    this.addEventHandlers();
    this.categoriaChangedHandler = this.handleCategoriaChanged.bind(this);
    Pagina.registerCategoriaChangedHandler(this.categoriaChangedHandler);
    this.layout();
  },

  initDomReferences: function() {
    this.p = this.el.down('.show-hide');
    this.show = this.p.down('a.show');
    this.hide = this.p.down('a.hide');
  },


  addEventHandlers: function() {
    if (this.show) this.show.observe('click', function(e) {
      e.stop();
      this.showAppuntamenti();
    }.bindAsEventListener(this));
    if (this.hide) this.hide.observe('click', function(e) {
      e.stop();
      this.hideAppuntamenti();
    }.bindAsEventListener(this));
  },

  handleCategoriaChanged: function(e) {
    if (e.memo.layout[1] == e.memo.layout[0]) this.hideAppuntamenti();
    else Pagina.unregisterCategoriaChangedHandler(this.categoriaChangedHandler);
  },

  showAppuntamenti: function() {
    if (this.colonnaElement) return;
    doAjaxUpdate(this.p, window._contextPath + '/appuntamenti/mostra.html', {
      method: 'get',
      parameters: { idCategoria: Pagina.idCategoria },
      insertion: 'after',
      evalScripts: true,
      onComplete: function() {
        this.show.hide();
        this.hide.show();
        this.colonnaElement = this.p.next('.colonna');
        this.colonnaElement.down('.appuntamenti').observe('control:inited', this.layout.bind(this));
      }.bind(this)
    });
  },

  hideAppuntamenti: function() {
    if (!this.colonnaElement) return;
    var appuntamenti = this.colonnaElement.down('.appuntamenti');
    if (appuntamenti) appuntamenti.stopObserving('control:inited');
    this.colonnaElement._control.dispose();
    this.colonnaElement.remove();
    this.colonnaElement = null;
    this.hide.hide();
    this.show.show();
    this.layout();
  },

  layout: function() {
    var maxHeight = $('left').getHeight() - $('head').getHeight();
    this.el.setStyle({ height: 'auto' });
    var elHeight = this.getHeight();
    if (this.colonnaElement/*elHeight > maxHeight*/) {
      elHeight = maxHeight;
      this.el.setStyle({ height: elHeight + 'px' });
    }
    var height = maxHeight - elHeight;
    [ 'content', 'right' ].each(function(el) {
      $(el).setStyle({ height: height + 'px', visibility: height > 0 ? 'visible' : 'hidden' });
    });
  },

  getHeight: function() {
    return !Prototype.Browser.IE ? this.el.getHeight() : ($('content').cumulativeOffset()[1] - this.el.cumulativeOffset()[1]);
  }

});
var Bakeka = Class.create(AbstractEditableControl, {

  initialize: function($super, element, id, options) {
    $super(element, id, Object.extend({
      reloadUrl: 'bakeka/reload.html',
      newEditor: function() {
        return new Bakeka.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    }, options || {}));
  },

  init: function($super, response) {
    $super(response);

    this.view = this.element.down('.view');
    this.detail = this.element.down('.bakeka-message');
    this.addMsg = this.element.down('a[name=addMessage]');
    this.msgs = this.element.select('.msg');
    this.ownedMsgs = this.msgs.filter(function(el) {
      return el.hasClassName('owned');
    });
    this.puntine = this.ownedMsgs.map(function(msg) {
      return msg.down('.puntina');
    });

    if (this.addMsg) this.addMsg.observe('click', this.handleAddMsg.bindAsEventListener(this));
    this.msgs.each(function(msg, index) {
      msg.observe('click', this.handleMsgClick.bindAsEventListener(this, msg));
    }, this);

    this.drags = this.ownedMsgs.map(function(item) {
      return new Drag(item.down('.puntina'), {
        self: true
      });
    });
    this.resizes = this.ownedMsgs.map(function(item) {
      return new Resize(item, {
        indicator: false,
        proportional: false,
        min: { w: 80, h: 60 },
        endResize: this.handleResize.bind(this)
      });
    }, this);
    if (this.drags.length) {
      this.drop = new Drop(this.view, {
        accept: '',
        mouseUp: function(d, p) {
          this.msg = p.up('.msg');
          this.handleMove();
        }.bind(this)
      });
    }
    if (this.detail) {
      this.detail.observe('msg:delete', this.handleMsgDelete.bind(this));
    }
  },

  uninit: function($super) {
    $super();

    if (this.addMsg) this.addMsg.stopObserving('click');
    this.msgs.each(function(msg) {
      msg.stopObserving('click');
    });

    this.drags.each(function(d) {
      d.destroy();
    });
    this.resizes.each(function(r) {
      r.destroy();
    });
    if (this.drop) this.drop.destroy();
    if (this.detail) this.detail.stopObserving('msg:delete');
  },

  handleAddMsg: function(e) {
    e.stop();
    new Bakeka.MessageEditor({
      saved: this.savedMsg.bind(this)
    }).openNew();
  },

  savedMsg: function(response, json) {
    if (json && json.idElemento) {
      doAjaxUpdate(new Element('div'), window._contextPath + '/bakeka/addMessage.html', {
        method: 'post',
        parameters: {
          id: this.id,
          msgId: json.idElemento
        },
        evalScripts: true,
        onComplete: this.reload.bind(this, { id: this.id })
      });
    }
  },

  handleMsgClick: function(e, msg) {
    this.msg = msg;
    if (this.msg.hasClassName('owned')) {
      Resizes.activate(this.msg);
    }
    this.detail._control.load(this.msg.id.replace(/^[^_]*_(\d+)$/, '$1'));
  },

  handleMove: function() {
    doAjaxUpdate(new Element('div'), window._contextPath + '/bakeka/message/move.html', {
      method: 'post',
      parameters: {
        messageId: this.msg.id.replace(/^[^_]*_(\d+)$/, '$1'),
        x: parseInt(this.msg.getStyle('left')),
        y: parseInt(this.msg.getStyle('top'))
      }
    });
  },

  handleResize: function(msg) {
    doAjaxUpdate(new Element('div'), window._contextPath + '/bakeka/message/resize.html', {
      method: 'post',
      parameters: {
        messageId: msg.id.replace(/^[^_]*_(\d+)$/, '$1'),
        width: parseInt(msg.getStyle('width')),
        height: parseInt(msg.getStyle('height'))
      }
    });
  },

  handleMsgDelete: function(e) {
    this.reload();
  }

});
var BakekaMessage = Class.create(AbstractControl, {

  initialize: function($super, element, options) {
    $super(element, Object.extend({ reloadUrl: 'bakeka/message/reload.html' }, options || {}));
  },

  init: function($super, response) {
    $super(response);
    this.delMsg = this.element.down('a[name=deleteMessage]');
    this.addComment = this.element.down('a[name=addComment]');
    if (this.delMsg) this.delMsg.observe('click', this.handleDelMsg.bindAsEventListener(this));
    if (this.addComment) this.addComment.observe('click', this.handleAddComment.bindAsEventListener(this));
  },

  uninit: function($super) {
    $super();
    if (this.addComment) this.addComment.stopObserving('click');
  },

  load: function(id) {
    this.id = id;
    this.reload({ id: id });
  },

  handleDelMsg: function(e) {
    e.stop();
    if (confirm("Eliminare il messaggio?")) {
      doAjaxUpdate(new Element('div'), window._contextPath + '/bakeka/message/delete.html', {
        method: 'post',
        parameters: {
          messageId: this.id.replace(/^[^_]*_(\d+)$/, '$1')
        },
        onComplete: function() {
          this.element.fire('msg:delete', { id: this.id });
        }.bind(this)
      });
    }
  },

  handleAddComment: function(e) {
    e.stop();
    new Comment.Editor({
      saved: this.savedComment.bind(this)
    }).openNew();
  },

  savedComment: function(response, json) {
    if (json && json.idElemento) {
      doAjaxUpdate(new Element('div'), window._contextPath + '/bakeka/message/addComment.html', {
        method: 'post',
        parameters: {
          id: this.id,
          commentId: json.idElemento
        },
        evalScripts: true,
        onComplete: this.reload.bind(this, { id: this.id })
      });
    }
  }

});
