window._contextPath = '';/** Checks date and time equality */
Date.prototype.equalsTo = function(date) {
  return ((this.getFullYear() == date.getFullYear()) && 
    (this.getMonth() == date.getMonth()) &&
    (this.getDate() == date.getDate()) &&
    (this.getHours() == date.getHours()) &&
    (this.getMinutes() == date.getMinutes()));
};

function date2string(date) {
  return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear();
}

function string2date(str) {
  var tokens = str.split('/');
  return new Date(parseInt(tokens[2]), parseInt(tokens[1]) - 1, parseInt(tokens[0]));
}

var ajaxSpinner = 0;

function showAjaxSpinner() {
  ajaxSpinner++;
  if (ajaxSpinner > 1) return;
  var loading = $('SGB_loading');
  if (!loading) {
    loading = new Element('div', { id: 'SGB_loading' });
    var container = $('container');
    if (container) container.insert({ after: loading });
  }
  var top = document.viewport.getScrollOffsets().top + 100;
  loading.setStyle({ top: top + 'px' });
  loading.show();
}

function hideAjaxSpinner() {
  ajaxSpinner--;
  if (ajaxSpinner > 0) return;
  var loading = $('SGB_loading');
  if (loading) loading.hide();
}

// funzione di convenienza per la gestione automatica dell'indicatore di loading (ajax spinner);
function doAjaxUpdate(container, url, options) {
  // override della callback
  options = Object.clone(options);
  var onComplete = options.onComplete;
  options.onComplete = (function(response, json) {
    hideAjaxSpinner();
    if (Object.isFunction(onComplete)) onComplete(response, json);
  }).bind(this);
  options.onFailure = (function(response, json) {
    hideAjaxSpinner();
    alert('failure!');
  }).bind(this);
  
  if (Prototype.Browser.IE) {
    options.requestHeaders = Object.clone(options.requestHeaders);
    Object.extend(options.requestHeaders, { 'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT' });
  }
  
  // indicatore di loading compare alla partenza della request, scompare all'arrivo della response
  showAjaxSpinner();
  new Ajax.Updater(container, url, options);
}

function doIframeRequest(form, options) {
  options = Object.clone(options);
  var onComplete = options.onComplete;
  options.onComplete = (function() {
    hideAjaxSpinner();
    if (Object.isFunction(onComplete)) onComplete();
  }).bind(this);
  
  showAjaxSpinner();
  new iframe(form, options).request();
}

function createDhtmlHistory() {
  window.dhtmlHistory.create({
    toJSON: function(o) {
      return Object.toJSON(o);
    },
    fromJSON: function(s) {
      return s.evalJSON();
    },
    blank: "/blank.htm"
  });
}

Lightview.images = window._contextPath + '/images/lightview/';

function ajaxOpen(uri, params, options) {
  var opt;
  if (options && options.container) {
    opt = {
      method: 'get',
      afterLoad: Prototype.emptyFunction
    };
    Object.extend(opt, options || {});
    doAjaxUpdate(opt.container, uri, {
      method: opt.method,
      parameters: params,
      evalScripts: true,
      onComplete: opt.afterLoad
    });
  } else {
    opt = {
      method: 'get',
      onShow: Prototype.emptyFunction,
      afterLoad: Prototype.emptyFunction,
      afterHide: Prototype.emptyFunction,
      afterResize: Prototype.emptyFunction,
      beforeLoad: Prototype.emptyFunction,
      onUpdate: Prototype.emptyFunction
    };
    Object.extend(opt, options || {});
    var afterLoad = opt.afterLoad;
    opt.afterLoad = function() {
      Modalbox.resizeToContent();
      afterLoad();
    };
    Modalbox.show(uri, {
      title: '',
      width: 720,
      height: 500,
      overlayDuration: .1,
      slideDownDuration: .2,
      slideUpDuration: .2,
      resizeDuration: .1,
      method: opt.method,
      params: params || {},
      onShow: opt.onShow,
      afterLoad: opt.afterLoad,
      afterHide: opt.afterHide,
      afterResize: opt.afterResize,
      beforeLoad: opt.beforeLoad,
      onUpdate: opt.onUpdate
    });
  }
}
var AbstractControl = Class.create({
  
  initialize: function(element, options) {
    this.options = {
      reloadUrl: null
    };
    Object.extend(this.options, options || { });
    
    this.element = $(element);
    this.element._control = this;
    var parentElement = this.element.ancestors().find(function(elt) {
      return '_control' in elt;
    });
    if (parentElement) {
      this.parent = parentElement._control;
      this.parent.element.fire('child:initialized', this);
    }
    this.children = [];
    if (this.options.decorator) this.options.decorator.attach(this);
    this.init();
  },
  
  init: function(response) {
    this.initDomReferences();
    this.addEventHandlers();
    this.element.show();
    this.element.fire('control:inited');
  },
  
  uninit: function() {
    this.element.fire('control:uniniting');
    this.element.hide();
    this.removeEventHandlers();
    this.children.each(function(child) {
      child.dispose();
    });
    this.children = [];
  },
  
  dispose: function() {
    if (this.parent) this.parent.element.fire('child:disposing', this);
    this.uninit();
  },
  
  initDomReferences: Prototype.emptyFunction,
  
  addEventHandlers: function() {
    this.element.observe('child:initialized', this.handleChildInitialized.bind(this));
	this.element.observe('child:disposing', this.handleChildDisposing.bind(this));
  },
  
  removeEventHandlers: function() {
    this.element.stopObserving('child:initialized');
    this.element.stopObserving('child:disposing');
  },
  
  handleChildInitialized: function(e) {
    this.children.push(e.memo);
  },
  
  handleChildDisposing: function(e) {
    this.children.filter(function(child) {
      return child != e.memo;
    });
  },
  
  reload: function(params) {
    this.uninit();
    var parameters = { elementId: this.element.id };
    Object.extend(parameters, Object.extend(this.getParams(), params));
    doAjaxUpdate(this.element, window._contextPath + '/' + this.options.reloadUrl, {
      method: 'get',
      parameters: parameters,
      evalScripts: true,
      onComplete: function(response) {
        this.init(response);
      }.bind(this)
    });
  },
  
  getParams: function() {
    return {};
  },

  click: function(n) {
    if (this[n]) this[n].observe('click', this['handle' + n.charAt(0).toUpperCase() + n.substring(1)].bindAsEventListener(this));
  }

});
var AbstractEditableControl = Class.create(AbstractControl, {
  
  initialize: function($super, element, id, options) {
    this.id = id;
    var opt = {
      newEditor: Prototype.emptyFunction,
      removeUrl: null
    };
    Object.extend(opt, options || {});
    $super(element, opt);
  },
  
  initDomReferences: function($super) {
    $super();
    this.heading = this.element.down('.heading');
    this.fumetto = this.element.down('div.fumetto');
    if (this.fumetto) {
      new Fumetto(this.heading, this.fumetto);
      this.modifica = this.fumetto.down('a.modifica');
      this.elimina = this.fumetto.down('a.elimina');
    }
  },
  
  addEventHandlers: function($super) {
    $super();
    if (this.modifica) this.modifica.observe('click', this.handleModifica.bindAsEventListener(this));
    if (this.elimina) this.elimina.observe('click', this.handleElimina.bindAsEventListener(this));
  },
  
  removeEventHandlers: function($super) {
    $super();
    if (this.modifica) this.modifica.stopObserving('click');
    if (this.elimina) this.elimina.stopObserving('click');
  },
  
  getParams: function($super) {
    return Object.extend($super(), { id: this.id });
  },
  
  handleModifica: function(e) {
    jslog.debug('AbstractEditableControl.handleModifica()');
    e.stop();
    if (!this.editor) this.editor = this.options.newEditor();
    this.editor.openEdit(this.id);
  },
  
  handleElimina: function(e) {
    jslog.debug('AbstractEditableControl.handleElimina()');
    e.stop();
    if (confirm('Procedere con l\'eliminazione?')) {
      doAjaxUpdate(new Element('div'), window._contextPath + '/' + this.options.removeUrl, {
        method: 'post',
        parameters: {
          idElemento: this.id,
          idParent: this.parent ? this.parent.id : null
        },
        evalScripts: true,
        onComplete: this.parent ? this.parent.reload.bind(this.parent) : Prototype.emptyFunction
        //this.element.remove.bind(this.element)
      });
    }
  }
  
});
if (!window.Pagina) {
  var Pagina = new Object();
}

Pagina.Methods = {

  idCategoria: null,

  uri: null,

  livello: null,

  layout: null,

  sito: null,

  setIdCategoria: function(idOrUri, skipHistory) {
    jslog.debug('Pagina.setIdCategoria(' + idOrUri + ')');
    if (this.busy || idOrUri == this.idCategoria || idOrUri == this.uri) return;
    this.busy = true;
    doAjaxUpdate(new Element('div'), window._contextPath + '/categoria/info2.html', {
      method: 'get',
      parameters: { idOrUri: idOrUri },
      onComplete: function(response, json) {
        jslog.debug('Pagina.setIdCategoria() onComplete()');
        this.busy = false;
        if (json.idCategoria == this.idCategoria) return;
        
        var change = {
          categoria: [ this.idCategoria, json.idCategoria ],
          sito: [ this.sito, json.sito ],
          layout: [ this.layout, json.layout ]
        };
        this.idCategoria = json.idCategoria;
        this.uri = json.uri;
        this.livello = json.livello;
        this.path = json.path;
        this.sito = json.sito;
        this.layout = json.layout;
        
        if (!skipHistory) {
          jslog.debug('dhtmlHistory.add(' + this.uri + ')');
          dhtmlHistory.add(this.uri);
        }

        this.fireEvents(change);
      }.bind(this)
    });
  },

  fireEvents: function(change) {
    for (var k in change) {
      if (change[k][1] != change[k][0]) document.fire(k + ':changed', change);
    }
  },

  registerCategoriaChangedHandler: function(handler) {
    document.observe('categoria:changed', handler);
  },

  unregisterCategoriaChangedHandler: function(handler) {
    document.stopObserving('categoria:changed', handler);
  },

  registerLayoutChangedHandler: function(handler) {
    document.observe('layout:changed', handler);
  },

  unregisterLayoutChangedHandler: function(handler) {
    document.stopObserving('layout:changed', handler);
  },

  registerSitoChangedHandler: function(handler) {
    document.observe('sito:changed', handler);
  },

  unregisterSitoChangedHandler: function(handler) {
    document.stopObserving('sito:changed', handler);
  },

  historyChange: function(newLocation) {
    jslog.debug('Pagina.historyChange(' + newLocation + ')');
    if (newLocation) this.setIdCategoria(decodeURIComponent(newLocation), true);
  },

  refresh: function(include, exclude) {
    var params = Object.extend(location.search.toQueryParams(), include);
    if (exclude) {
      exclude.each(function(n) {
        delete params[n];
      });
    }
    var query = Object.toQueryString(params);
    window.location = window._contextPath + '/app.html' + (query ? '?' + query : '') + '#' + encodeURIComponent(Pagina.uri);
  }

};

Object.extend(Pagina, Pagina.Methods);
var Colonna = Class.create(AbstractControl, {
  
  initialize: function($super, element, tipo, statica, sito, layout) {
    this.tipo = tipo;
    this.statica = statica;
    this.sito = sito;
    this.layout = layout;
    $super(element);
    if (!this.statica) {
      this.categoriaChangedHandler = this.handleCategoriaChanged.bind(this);
      jslog.debug('Colonna[' + this.element.id + ']: registering handler for categoria:change');
      Pagina.registerCategoriaChangedHandler(this.categoriaChangedHandler);
    }
  },
  
  handleCategoriaChanged: function() {
    if (Pagina.sito == this.sito && Pagina.layout == this.layout) {
      this.load();
    } else {
      jslog.debug('Colonna[' + this.element.id + ']: unregistering handler for categoria:change');
      Pagina.unregisterCategoriaChangedHandler(this.categoriaChangedHandler);
      this.dispose();
    }
  },
  
  load: function() {
    this.update('colonna/load.html', {
      tipo: this.tipo,
      idCategoria: Pagina.idCategoria,
      elementId: this.element.id
    });
  },
  
  reload: function(callback) {
    this.update('colonna/reload.html', {
      idColonna: this.id,
      elementId: this.element.id
    }, callback);
  },
  
  initDomReferences: function($super) {
    $super();
    this.heading = this.element.down('.heading');
    this.bubble = this.element.down('.fumetto');
    if (this.bubble) {
	    new Fumetto(this.heading, this.bubble);
	    this.crea = this.bubble.down('a.crea');
	    this.elimina = this.bubble.down('a.elimina');
	    this.aggiungi = this.bubble.down('a.aggiungi');
	    this.ordina = this.bubble.down('a.ordina');
    }
  },
  
  addEventHandlers: function($super) {
    $super();
    if (this.crea) this.crea.observe('click', this.handleCrea.bindAsEventListener(this));
    if (this.elimina) this.elimina.observe('click', this.handleElimina.bindAsEventListener(this));
    if (this.aggiungi) this.aggiungi.observe('click', this.handleAggiungi.bindAsEventListener(this));
    if (this.ordina) this.ordina.observe('click', this.handleOrdina.bindAsEventListener(this));
  },
  
  removeEventHandlers: function($super) {
    $super();
    if (this.crea) this.crea.stopObserving('click');
    if (this.elimina) this.elimina.stopObserving('click');
    if (this.aggiungi) this.aggiungi.stopObserving('click');
    if (this.ordina) this.ordina.stopObserving('click');
  },
  
  handleCrea: function(e) {
    e.stop();
    doAjaxUpdate(new Element('div'), window._contextPath + '/colonna/create.html', {
      method: 'post',
      parameters: { tipo: this.tipo, idCategoria: !this.statica ? Pagina.idCategoria : null },
      evalScripts: true,
      onComplete: function(response, json) {
        jslog.debug('Colonna.handleCrea() onComplete()');
        this.id = json.idColonna;
        this.reload(/*this.aggiungiOpenEditor1.bind(this)*/);
      }.bind(this)
    });
    
  },
  
  handleElimina: function(e) {
    e.stop();
    if (confirm('Sicuro?')) {
      doAjaxUpdate(new Element('div'), window._contextPath + '/colonna/delete.html', {
        method: 'post',
        parameters: { idColonna: this.id },
        evalScripts: true,
        onComplete: this.load.bind(this)
      });
    }
  },
  
  handleAggiungi: function(e) {
    e.stop();
    this.aggiungiOpenEditor1();
  },
  
  handleOrdina: function(e) {
    e.stop();
    new OrdinaElementi({ saved: function(response, json) {
      this.reload({ idCategoria: this.idCategoriaAttiva });
    }.bind(this) }).open(this.tipo, !this.statica ? Pagina.idCategoria : null);
  },
  
  aggiungiOpenEditor1: function() {
    new Colonna.ElementoEditor({
      closeAfterSave: false,
      saved: this.aggiungiOpenEditor2.bind(this)
    }).openNew();
  },
  
  aggiungiOpenEditor2: function(response) {
    if (!this.editors) {
      var options = {
        saved: this.elementoSalvato.bind(this)
      };
      this.editors = {
	    ARTICOLO: new Articolo.Editor(options),
	    FOTO: new Foto.Editor(options),
	    AGENDA: new Agenda.Editor(options),
	    GALLERIA: new Galleria.Editor(options),
	    COPERTINA: new Copertina.Editor(options),
	    DOWNLOAD: new Download.Editor(options),
	    JSP: new Jsp.Editor(options),
	    BLOG: new Blog.Editor(options),
        BACHECA: new Bakeka.Editor(options),
        YOUTUBE: new Youtube.Editor(options)
	  };
	}
    this.editors[response.getHeader('tipo')].openNew({ idColonna: this.id });
  },
  
  update: function(uri, params, callback) {
    this.dispose();
    doAjaxUpdate(this.element, window._contextPath + '/' + uri, {
      method: 'get',
      parameters: params,
      evalScripts: true,
      onComplete: function(response) {
        this.init();
        if (callback) callback();
      }.bind(this)
    });
  },
  
  elementoSalvato: function(response, json) {
    if (json && json.idElemento) {
      (Object.isArray(json.idElemento) ? json.idElemento : [ json.idElemento ]).each(function(id) {
        this.idElementoSalvato = id;
        this.aggiungiElemento(this.idElementoSalvato);
      }, this);
    } else {
      this.elementoModificato(this.idElementoSalvato);
    }
  },
  
  aggiungiElemento: function(idElemento) {
    doAjaxUpdate(new Element('div'), window._contextPath + '/colonna/addElemento.html', {
      method: 'post',
      parameters: {
        idColonna: this.id,
        idElemento: idElemento
      },
      evalScripts: true,
      onComplete: this.elementoAggiunto.bind(this, idElemento)
    });
  },
  
  elementoAggiunto: function(idElemento) {
    doAjaxUpdate(this.element, window._contextPath + '/colonna/elemento.html', {
      method: 'get',
      parameters: {
        idColonna: this.id,
        idElemento: idElemento
      },
      insertion: 'bottom',
      evalScripts: true
    });
  },
  
  elementoModificato: function(idElemento) {
    var elemento = this.children.find(function(el) { return el.id == idElemento; });
    elemento.reload();
  }
  
});
var Calendario = Class.create({
  
  initialize: function(element) {
    jslog.debug('Calendario.initialize(' + element + ')');
    this.element = $(element);
    this.element._control = this;
    this._init();
  },
  
  _init: function() {
    this._initDomReferences();
    this._initEventHandlers();
    this.giornoSelezionato = this.element.down('.selezionato');
  },
  
  _initDomReferences: function() {
    this.giorni = this.element.select('td.giorno');
    this.annoIndietro = this.element.down('.annoIndietro');
    this.meseIndietro = this.element.down('.meseIndietro');
    this.meseAvanti = this.element.down('.meseAvanti');
    this.annoAvanti = this.element.down('.annoAvanti');
  },
  
  _initEventHandlers: function() {
    this.giorni.each(function(giorno) {
      giorno.observe('click', this._giornoClickHandler.bindAsEventListener(this, giorno));
    }, this);
    this.annoIndietro.observe('click', this._annoIndietroClickHandler.bindAsEventListener(this));
    this.meseIndietro.observe('click', this._meseIndietroClickHandler.bindAsEventListener(this));
    this.meseAvanti.observe('click', this._meseAvantiClickHandler.bindAsEventListener(this));
    this.annoAvanti.observe('click', this._annoAvantiClickHandler.bindAsEventListener(this));
  },
  
  _giornoClickHandler: function(e, giorno) {
    e.stop();
    if (this.giornoSelezionato) this.giornoSelezionato.removeClassName('selezionato');
    this.giornoSelezionato = giorno;
    this.giornoSelezionato.addClassName('selezionato');
    this.setData(new Date(this.data.getFullYear(), this.data.getMonth(), this.giornoSelezionato.innerHTML));
  },
  
  _annoIndietroClickHandler: function(e) {
    e.stop();
    this.update('anno', -1);
  },
  
  _meseIndietroClickHandler: function(e) {
    e.stop();
    this.update('mese', -1);
  },
  
  _meseAvantiClickHandler: function(e) {
    e.stop();
    this.update('mese', +1);
  },

  _annoAvantiClickHandler: function(e) {
    e.stop();
    this.update('anno', +1);
  },
  
  setData: function(data) {
    jslog.debug('Calendario.setData(' + data + ')');
    if (!this.data || !data.equalsTo(this.data)) {
      this.data = data;
      jslog.debug('fire(data:changed)');
      this.element.fire('data:changed');
    }
  },
  
  update: function(attributo, variazione) {
    jslog.debug('Calendario.update(' + attributo + ', ' + variazione + ')');
    var params = {
      giorno: this.data.getDate(),
      mese: this.data.getMonth() + 1,
      anno: this.data.getFullYear()
    };
    if (attributo) {
      params.attributo = attributo;
      params.variazione = variazione;
    }
    this._update('calendario/reload.html', params);
  },
  
  _update: function(uri, params) {
    doAjaxUpdate(this.element, window._contextPath + '/' + uri, {
      method: 'get',
      parameters: Object.extend(params, { elementId: this.element.id }),
      evalScripts: true,
      onComplete: function(response) {
        this.setData(new Date(
          parseInt(response.getHeader('anno')),
          parseInt(response.getHeader('mese')) - 1,
          parseInt(response.getHeader('giorno'))));
        this._init();
        this.element.fire('calendario:updated');
      }.bind(this)
    });
  },
  
  highlight: function(giorni, className) {
    giorni.each(function(giorno) {
      this.giorni[giorno - 1].addClassName(className);
    }, this);
  }
  
});
var Appuntamenti = Class.create(AbstractControl, {
  
  initialize: function($super, element, data, modalita) {
    this.data = data;
    this.modalita = modalita;
    $super(element, { reloadUrl: 'agenda/appuntamenti.html' });
  },
  
  initDomReferences: function($super) {
    $super();
    this.selettoriModalita = this.element.down('div.modalita').select('a.cambia');
    this.ore = this.element.select('.ora');
    this.giorniSettimana = this.element.select('.giornoSettimana');
  },
  
  addEventHandlers: function($super) {
    $super();
    this.selettoriModalita.each(function(selettore) {
      selettore.observe('click', function(e, modalita) {
        e.stop();
        this.cambiaModalita(modalita);
      }.bindAsEventListener(this, selettore.name));
    }, this);
    this.ore.each(function(ora) {
      var aggiungi = ora.down('a.aggiungi');
      if (aggiungi) aggiungi.observe('click', this.handleAggiungi.bindAsEventListener(this, aggiungi.name));
      ora.select('a.modifica').each(function(modifica) {
        modifica.observe('click', this.handleModifica.bindAsEventListener(this, modifica.name));
      }, this);
      ora.select('a.elimina').each(function(elimina) {
        elimina.observe('click', this.handleElimina.bindAsEventListener(this, elimina.name));
      }, this);
    }, this);
    this.giorniSettimana.each(function(giorno) {
      var entra = giorno.down('a.entra');
      if (entra) entra.observe('click', function(e, formattedDate) {
        e.stop();
        this.entraGiorno(formattedDate);
      }.bindAsEventListener(this, entra.name));
    }, this);
  },

  removeEventHandlers: function($super) {
    $super();
    this.selettoriModalita.each(function(selettore) {
      selettore.stopObserving('click');
    }, this);
    this.ore.each(function(ora) {
      var aggiungi = ora.down('a.aggiungi');
      if (aggiungi) aggiungi.stopObserving('click');
      ora.select('a.modifica').each(function(modifica) {
        modifica.stopObserving('click');
      });
      ora.select('a.elimina').each(function(elimina) {
        elimina.stopObserving('click');
      });
    });
    this.giorniSettimana.each(function(giorno) {
      var entra = giorno.down('a.entra');
      if (entra) entra.stopObserving('click');
    });
  },

  init: function($super, response) {
    if (response) this.idGiornata = response.getHeader('idGiornata');
    $super();
    this.ore.each(function(ora) {
      ora.select('.appuntamento').each(function(appuntamento) {
        var bubble = appuntamento.next('.fumetto');
        if (bubble) new Fumetto(appuntamento, bubble);
      }, this);
    }, this);
  },

  entraGiorno: function(formattedDate) {
    this.modalita = 'GIORNO';
    var data = string2date(formattedDate);
    if (data.equalsTo(this.data)) this.reload();
    else this.setData(data);
  },
  
  cambiaModalita: function(modalita) {
    this.modalita = modalita;
    this.reload();
  },
  
  handleAggiungi: function(e, ora) {
    e.stop();
    new Appuntamenti.Editor({ saved: this.reload.bind(this, null) }).openNew(this.idAgenda, this.data, ora);
  },
  
  handleModifica: function(e, idAppuntamento) {
    e.stop();
    new Appuntamenti.Editor({ saved: this.reload.bind(this, null) }).openEdit(idAppuntamento);
  },
  
  handleElimina: function(e, idAppuntamento) {
    e.stop();
    if (confirm('Sicuro?')) {
      doAjaxUpdate(new Element('div'), window._contextPath + '/agenda/appuntamento/delete.html', {
        method: 'post',
        parameters: { idAppuntamento: idAppuntamento },
        evalScripts: true,
        onComplete: this.reload.bind(this, null)
      });
    }
  },
  
  setData: function(data) {
    jslog.debug('Appuntamenti.setData(' + data + ')');
    if (!this.data || !data.equalsTo(this.data)) {
      this.data = data;
      this.reload();
      jslog.debug('fire(data:changed)');
      this.element.fire('data:changed');
    }
  },

  getParams: function() {
    return {
      idAgenda: this.idAgenda,
      giorno: this.data.getDate(),
      mese: this.data.getMonth() + 1,
      anno: this.data.getFullYear(),
      modalita: this.modalita
    };
  }

});
var Login = Class.create(AbstractControl, {
  
  initialize: function($super, element, options) {
    var opt = { reloadUrl: 'login/reload.html' };
    Object.extend(opt, options || {});
    $super(element, opt);
  },
  
  initDomReferences: function($super) {
    $super();
    this.entra = this.element.down('a[name=entra]');
    this.form = this.element.down('form');
    if (this.form) {
      this.uri = this.form.down('input[name=uri]');
      this.cancel = this.form.down('input[name=cancel]');
    }
    this.welcome = this.element.down('.welcome');
    this.bubble = this.element.down('div.fumetto');
    if (this.bubble) {
      new Fumetto(this.welcome, this.bubble);
      this.modifica = this.bubble.down('a.modifica');
      this.users = this.bubble.down('a.users');
      this.roles = this.bubble.down('a.roles');
    }
  },
  
  addEventHandlers: function($super) {
    $super();
    this.click('entra');
    this.click('cancel');
    this.click('register');
    this.click('forgotPassword');
    this.click('modifica');
    this.click('users');
    this.click('roles');
    this.click('editProfile');
    if (this.form) this.form.observe('submit', this.handleLogin.bindAsEventListener(this));
  },
  
  handleEntra: function(e) {
    e.stop();
    this.entra.hide();
    this.form.show();
  },

  handleLogin: function(e) {
    this.uri.value = Pagina.uri;
  },

  handleCancel: function(e) {
    e.stop();
    this.form.hide();
    this.entra.show();
  },

  handleRegister: function(e) {
    e.stop();
    new RegistrationEditor({ closeAfterSave: false }).openNew();
  },

  handleForgotPassword: function(e) {
    e.stop();
  },

  handleModifica: function(e) {
    e.stop();
    new UserEditor({ saved: function() {
      this.parent.reload();
    }.bind(this) }).openEdit();
  },
  
  handleUsers: function(e) {
    e.stop();
    new UserEditor({ saved: function() {
      this.parent.reload();
    }.bind(this) }).openAdmin();
  },

  handleRoles: function(e) {
    e.stop();
    new RoleEditor({ saved: function() {
      this.parent.reload();
    }.bind(this) }).openAdmin();
  }

});
var App = Class.create({
  
  initialize: function(sito) {
    jslog.debug('App.initialize()');
    Pagina.sito = sito;
    createDhtmlHistory();
    
    document.observe('dom:loaded', this.handleDomLoaded.bind(this));
  },
  
  handleDomLoaded: function() {
    Pagina.registerLayoutChangedHandler(this.handleLayoutChanged.bind(this));
    Pagina.registerSitoChangedHandler(this.handleSitoChanged.bind(this));
    dhtmlHistory.initialize();
    dhtmlHistory.addListener(Pagina.historyChange.bind(Pagina));
    var match = document.location.href.match(/^[^#]*#(.*)$/, '$1');
    if (match) Pagina.historyChange(match[1]);
    else doAjaxUpdate(new Element('div'), window._contextPath + '/categoria/default.html', {
      method: 'get',
      parameters: { sito: Pagina.sito },
      onComplete: function(response, json) {
        if (json.uri) Pagina.historyChange(json.uri);
      }
    });
  },
  
  handleLayoutChanged: function(e) {
    jslog.debug('App.handleLayoutChanged()');
    var container = $('container');
    container.update('');
    container.removeClassName('layout_' + e.memo.layout[0]);
    container.addClassName('layout_' + e.memo.layout[1]);
    var params = location.search.toQueryParams();
    params.idCategoria = Pagina.idCategoria;
    doAjaxUpdate(container, window._contextPath + '/layout/cambia.html', {
      method: 'get',
      parameters: params,
      evalScripts: true
    });
  },
  
  handleSitoChanged: function(e) {
    jslog.debug('App.handleSitoChanged()');
    Pagina.refresh({ sito: Pagina.sito });
  }
  
});
var Layout = Class.create({
  
  initialize: function(layout, options) {
    jslog.debug('Layout.initialize()');
    this.layout = layout;
    
    this.options = {
      categoriaChanged: Prototype.emptyFunction,
      layoutChanged: Prototype.emptyFunction
    };
    Object.extend(this.options, options || { });
    
    jslog.debug('Layout: registering handler for categoria:change');
    this.categoriaChangedHandler = this.handleCategoriaChanged.bind(this);
    Pagina.registerCategoriaChangedHandler(this.categoriaChangedHandler);
  },
  
  handleCategoriaChanged: function() {
    jslog.debug('Layout.handleCategoriaChanged()');
    if (Pagina.layout == this.layout) {
      this.options.categoriaChanged();
    } else {
      jslog.debug('Layout: unregistering handler for categoria:change');
      Pagina.unregisterCategoriaChangedHandler(this.categoriaChangedHandler);
      this.options.layoutChanged();
    }
  }
  
});
var Agenda = Class.create(AbstractEditableControl, {

  initialize: function($super, element, idAgenda, options) {
    var opt = {
      reloadUrl: 'agenda/reload.html',
      newEditor: function() {
        return new Agenda.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idAgenda, opt);
  },

  init: function($super) {
    $super();
    this.calendario = this.calendarioElement._control;
    this.appuntamenti = this.appuntamentiElement._control;
    this.handleCalendarioUpdated();
  },

  initDomReferences: function($super) {
    $super();
    this.calendarioElement = $(this.element.id + '_calendario');
    this.appuntamentiElement = $(this.element.id + '_appuntamenti');
  },

  addEventHandlers: function($super) {
    this.calendarioElement.observe('data:changed', this.handleCalendarioDataChanged.bind(this));
    this.calendarioElement.observe('calendario:updated', this.handleCalendarioUpdated.bind(this));
    this.appuntamentiElement.observe('data:changed', this.handleAppuntamentiDataChanged.bind(this));
  },

  removeEventHandlers: function($super) {
    $super();
    this.calendarioElement.stopObserving('data:changed');
    this.calendarioElement.stopObserving('calendario:updated');
    this.appuntamentiElement.stopObserving('data:changed');
  },

  handleCalendarioDataChanged: function() {
    jslog.debug('Agenda.handleCalendarioDataChanged()');
    this.appuntamenti.setData(this.calendario.data);
  },

  handleAppuntamentiDataChanged: function() {
    jslog.debug('Agenda.handleAppuntamentiDataChanged()');
    this.calendario.setData(this.appuntamenti.data);
  },

  handleCalendarioUpdated: function() {
    doAjaxUpdate(new Element('div'), window._contextPath + '/agenda/giorniAppuntamenti.html', {
      method: 'get',
      parameters: {
        idAgenda: this.id,
        mese: this.calendario.data.getMonth() + 1,
	    anno: this.calendario.data.getFullYear()
      },
      evalScripts: true,
      onComplete: function(response, json) {
        this.calendario.highlight(json.giorni, 'conAppuntamenti');
      }.bind(this)
    });
  }

});
var Articolo = Class.create(AbstractEditableControl, {

  initialize: function($super, element, idArticolo, options) {
    var opt = {
      reloadUrl: 'articolo/reload.html',
      newEditor: function() {
        return new Articolo.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idArticolo, opt);
  },

  initDomReferences: function($super) {
    $super();
    if (this.fumetto) {
      this.sendMail = this.fumetto.down('a.send-mail');
    }
  },

  addEventHandlers: function($super) {
    $super();
    if (this.sendMail) this.sendMail.observe('click', this.handleSendMail.bindAsEventListener(this));
  },

  handleSendMail: function(e) {
    jslog.debug('Articolo.handleSendMail()');
    e.stop();
    if (confirm('Inviare una mail a ciascun iscritto?')) {
      doAjaxUpdate(new Element('div'), window._contextPath + '/newsletter/sendArticolo.html', {
        method: 'get',
        parameters: { idArticolo: this.id },
        evalScripts: true
      });
    }
  }

});
var Blog = Class.create(AbstractEditableControl, {
  
  initialize: function($super, element, idBlog, options) {
    var opt = {
      reloadUrl: 'blog/reload.html',
      newEditor: function() {
        return new Blog.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idBlog, opt);
  },
  
  init: function($super) {
    jslog.debug('Blog.init()');
    $super();
    this.handleCalendarioUpdated();
  },
  
  initDomReferences: function($super) {
    $super();
    this.calendarioElement = $(this.element.id + '_calendario');
    this.articoliElement = $(this.element.id + '_articoli');
  },
  
  addEventHandlers: function($super) {
    $super();
    this.calendarioElement.observe('data:changed', this.handleCalendarioDataChanged.bind(this));
    this.articoliElement.observe('data:changed', this.handleArticoliDataChanged.bind(this));
    this.calendarioElement.observe('calendario:updated', this.handleCalendarioUpdated.bind(this));
  },
  
  removeEventHandlers: function($super) {
    $super();
    this.calendarioElement.stopObserving('data:changed');
    this.articoliElement.stopObserving('data:changed');
    this.calendarioElement.stopObserving('calendario:updated');
  },
  
  handleCalendarioDataChanged: function() {
    jslog.debug('Blog.handleCalendarioDataChanged()');
    this.articoliElement._control.setData(this.calendarioElement._control.data);
  },
  
  handleArticoliDataChanged: function() {
    jslog.debug('Blog.handleAppuntamentiDataChanged()');
  },
  
  handleCalendarioUpdated: function() {
    doAjaxUpdate(new Element('div'), window._contextPath + '/blog/giorniArticoli.html', {
      method: 'get',
      parameters: {
        idBlog: this.id,
        mese: this.calendarioElement._control.data.getMonth() + 1,
	    anno: this.calendarioElement._control.data.getFullYear()
      },
      evalScripts: true,
      onComplete: function(response, json) {
        this.calendarioElement._control.highlight(json.giorni, 'conArticolo');
      }.bind(this)
    });
  }
  
});

Blog.Articoli = Class.create({
  
  initialize: function(element, data) {
    this.element = $(element);
    this.element._control = this;
    this.data = data;
    this.init();
  },
  
  init: function() {
    jslog.debug('Blog.Articoli.init()');
    this.initDomReferences();
    this.initEventHandlers();
  },
  
  initDomReferences: function() {
    jslog.debug('Blog.Articoli.initDomReferences()');
  },
  
  initEventHandlers: function() {
    jslog.debug('Blog.Articoli.initEventHandlers()');
  },
  
  setData: function(data) {
    jslog.debug('Blog.Articoli.setData(' + data + ')');
    if (!this.data || !data.equalsTo(this.data)) {
      this.data = data;
      this.reload();
      jslog.debug('fire(data:changed)');
      this.element.fire('data:changed');
    }
  },
  
  reload: function() {
    jslog.debug('Blog.Articoli.reload()');
    doAjaxUpdate(this.element, window._contextPath + '/blog/articoli.html', {
      method: 'get',
      parameters: {
        idBlog: this.idBlog,
        giorno: this.data.getDate(),
        mese: this.data.getMonth() + 1,
        anno: this.data.getFullYear(),
        elementId: this.element.id
      },
      evalScripts: true,
      onComplete: function(response) {
        this.init();
      }.bind(this)
    });
  }
  
});
var Copertina = Class.create(AbstractEditableControl, {
  
  initialize: function($super, element, idCopertina, options) {
    var opt = {
      reloadUrl: 'copertina/reload.html',
      newEditor: function() {
        return new Copertina.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idCopertina, opt);
  },
  
  initDomReferences: function($super) {
    $super();
    this.frammenti = this.element.select('div.frammento');
  },
  
  addEventHandlers: function($super) {
    $super();
    this.frammenti.each(function(frammento) {
      var highlight = frammento.down('div.highlight');
      if (highlight) {
        frammento.observe('mouseover', this.showHighlight.bind(this, highlight));
        frammento.observe('mouseout', this.hideHighlight.bind(this, highlight));
        var idCategoria = String(highlight.id).replace(/^.*_categoria(\d+).*$/, '$1');
        //var idSchema = String(highlight.id).replace(/^.*_schema(\d+).*$/, '$1');
        highlight.observe('click', Pagina.setIdCategoria.bind(Pagina, idCategoria, false));
      }
    }, this);
  },
  
  showHighlight: function(highlight) {
    highlight.previous().hide();
    highlight.show();
    highlight.next().show();
  },
  
  hideHighlight: function(highlight) {
    highlight.next().hide();
    highlight.hide();
    highlight.previous().show();
  }
  
});
var Download = Class.create(AbstractEditableControl, {

  initialize: function($super, element, idDownload, options) {
    var opt = {
      reloadUrl: 'download/reload.html',
      newEditor: function() {
        return new Download.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idDownload, opt);
  }
  
});
var Foto = Class.create(AbstractEditableControl, {

  initialize: function($super, element, idFoto, options) {
    var opt = {
      reloadUrl: 'foto/reload.html',
      newEditor: function() {
        return new Foto.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idFoto, opt);
  },

  initDomReferences: function($super) {
    $super();
    if (this.fumetto) this.offusca = this.fumetto.down('a.offusca');
  },

  addEventHandlers: function($super) {
    $super();
    this.click('offusca');
  },

  handleOffusca: function(e) {
    e.stop();
    new Foto.ObfuscateEditor({ saved: function() {
      this.reload();
    }.bind(this) }).open(window._contextPath + '/foto/obfuscate/form.html', { fotoId: this.id });
  }

});
var Galleria = Class.create(AbstractEditableControl, {
  
  initialize: function($super, element, idGalleria, options) {
    var opt = {
      reloadUrl: 'galleria/reload.html',
      newEditor: function() {
        return new Galleria.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idGalleria, opt);
  },
  
  initDomReferences: function($super) {
    $super();
    this.fotos = this.element.select('div.fotoDiGalleria');
    this.link = this.element.down('a.link');
  }

});
var Jsp = Class.create(AbstractEditableControl, {
  
  initialize: function($super, element, idJsp, options) {
    var opt = {
      reloadUrl: 'jsp/reload.html',
      newEditor: function() {
        return new Jsp.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idJsp, opt);
  }
  
});
var Siti = Class.create(AbstractControl, {
  
  initialize: function($super, element, options) {
    var opt = { reloadUrl: 'siti/reload.html' };
    Object.extend(opt, options || {});
    $super(element, opt);
  },
  
  init: function($super) {
    $super();
    if (this.bubbles)
      this.bubbles.each(function(bubble, index) {
        new Fumetto(this.liElements[index], bubble);
      }, this);
  },
  
  initDomReferences: function($super) {
    $super();
    this.liElements = this.element.select('li');
    this.bubbles = this.element.select('div.fumetto');
  },
  
  addEventHandlers: function($super) {
    $super();
    if (this.bubbles) {
      this.bubbles.each(function(bubble) {
        var predefinito = bubble.down('a.predefinito');
        if (predefinito) predefinito.observe('click', this.handlePredefinito.bindAsEventListener(this, predefinito.name));
      }, this);
    }
  },
  
  handlePredefinito: function(e, sito) {
    jslog.debug('Siti.handlePredefinito()');
    e.stop();
    doAjaxUpdate(new Element('div'), window._contextPath + '/siti/updatePredefinito.html', {
      method: 'post',
      parameters: { sito: sito },
      onComplete: function(response, json) {
        this.reload();
      }.bind(this)
    });
  }
  
});
var LightviewFotoDecorator = Class.create({

  initialize: function(foto) {
    var links = foto.element.select('a');
    links.last().addClassName('lightview');
    Lightview.updateViews();
  }
  
});
var RaiseEventFotoDecorator = Class.create({

  initialize: function(foto) {
    this.foto = foto;
    var a = this.foto.element.select('a').last();
    a.observe('click', this.handleClick.bindAsEventListener(this));
  },
  
  handleClick: function(e) {
    e.stop();
    this.foto.parent.element.fire('foto:selected', this.foto);
  }
  
});
var SlideshowGalleriaDecorator = Class.create({

  attach: function(galleria) {
    this.galleria = galleria;
    this.galleria.element.observe('control:inited', this.handleInited.bind(this));
    this.galleria.element.observe('control:uniniting', this.handleUniniting.bind(this));
    this.galleria.element.select('.fotoDiGalleria').each(function(fdg) {
      fdg.down('a').addClassName('lightview');
    });
    Lightview.updateViews();
  },
  
  handleInited: function() {
    this.galleria.fotos.each(function(foto) {
      foto.hide();
    });
    this.fotos = this.galleria.fotos.filter(function(foto) {
      return foto.down('img');
    });
    if (this.fotos.length > 0) {
      this.fotoIndex = -1;
      this.change();
      this.player = new PeriodicalExecuter(this.change.bind(this), 3);
    }
    this.galleria.link.observe('click', function(e) {
      e.stop();
      var foto = this.galleria.fotos[0];
      if (foto) {
        Lightview.show(foto.down('a'));
      }
    }.bindAsEventListener(this));
  },
  
  handleUniniting: function() {
    if (this.player) {
      this.player.stop();
      this.player = null;
    }
  },
  
  change: function() {
    if (this.fotoIndex >= 0) this.fotos[this.fotoIndex].hide();
    this.fotoIndex = (this.fotoIndex + 1) % this.fotos.length;
    this.fotos[this.fotoIndex].show();
  }
  
});
var SgbForm = Class.create({

  initialize: function(container, options) {
    this.container = $(container);
    this.options = {
      handleResponse: Prototype.emptyFunction
    };
    Object.extend(this.options, options || { });
  },

  show: function(uri, params) {
    jslog.debug('Form.show(' + uri + ')');
    doAjaxUpdate(this.container, uri, {
      method: 'get',
      parameters: params,
      evalScripts: true,
      onComplete: this.initForm.bind(this)
    });
  },

  initForm: function() {
    jslog.debug('Form.initForm()');
    this.form = this.container.down('form');
    if (this.form) this.form.observe('submit', this.handleSubmit.bindAsEventListener(this));
  },

  handleSubmit: function(e) {
    jslog.debug('Form.handleSubmit()');
    e.stop();
    this.form.stopObserving('submit');
    this.doRequest(this.form.action, this.form.serialize());
  },

  doRequest: function(uri, params) {
    jslog.debug('Form.doRequest()');
    doAjaxUpdate(this.container, uri, {
      method: 'post',
      parameters: params,
      evalScripts: true,
      onComplete: function(response, json) {
        jslog.debug('Form.doRequest() onComplete()');
        this.initForm();
        if (!this.form) this.handleResponse(response, json);
      }.bind(this)
    });
  },

  handleResponse: function(response, json) {
    jslog.debug('Form.afterSave()');
    this.options.handleResponse(response, json);
  }

});
var Newsletter = Class.create(AbstractControl, {

  initialize: function($super, element, options) {
    var opt = { reloadUrl: 'newsletter/reload.html' };
    Object.extend(opt, options || {});
    $super(element, opt);
    this.form = new SgbForm(this.formContainer);
  },

  initDomReferences: function($super) {
    $super();
    this.subscribe = this.element.down('a[name=subscribe]');
    this.editSubscription = this.element.down('a[name=edit-subscription]');
    this.unsubscribe = this.element.down('a[name=unsubscribe]');
    this.administer = this.element.down('a[name=administer]');
    this.formContainer = this.element.down('.form-container');
  },

  addEventHandlers: function($super) {
    $super();
    if (this.subscribe) this.subscribe.observe('click', this.handleSubscribe.bindAsEventListener(this));
    if (this.editSubscription) this.editSubscription.observe('click', this.handleEditSubscription.bindAsEventListener(this));
    if (this.unsubscribe) this.unsubscribe.observe('click', this.handleUnsubscribe.bindAsEventListener(this));
    if (this.administer) this.administer.observe('click', this.handleAdminister.bindAsEventListener(this));
  },

  handleSubscribe: function(e) {
    e.stop();
    this.form.show(window._contextPath + '/newsletter/subscriber/form.html', { act: 'subscribe', idCategoria: Pagina.idCategoria });
  },

  handleEditSubscription: function(e) {
    e.stop();
    this.form.show(window._contextPath + '/newsletter/subscriber/form.html', { act: 'edit-subscription', idCategoria: Pagina.idCategoria });
  },

  handleUnsubscribe: function(e) {
    e.stop();
    this.form.show(window._contextPath + '/newsletter/subscriber/form.html', { act: 'unsubscribe', idCategoria: Pagina.idCategoria });
  },

  handleAdminister: function(e) {
    e.stop();
    this.form.show(window._contextPath + '/newsletter/admin.html');
  },

  confirm: function(act, token) {
    switch (act) {
      case 'confirm-subscribe':
      case 'confirm-unsubscribe':
        ajaxOpen(window._contextPath + '/newsletter/subscriber/' + act + '.html', { token: token }, {
          method: 'post',
          afterHide: function() {
            Pagina.refresh({}, [ 'act', 'token' ]);
          }
        });
        break;
      case 'confirm-edit-subscription':
        this.form.doRequest(window._contextPath + '/newsletter/subscriber/form.html',
          { act: 'confirm-edit-subscription', token: token });
        break;
    }
  }

});
var AbstractEditor = Class.create({
  
  initialize: function(options) {
    this.options = {
      formId: null,
      saved: Prototype.emptyFunction,
      closeAfterSave: true
    };
    Object.extend(this.options, options || { });
    this.submitBtnClickHandler = this.handleSubmitBtnClick.bindAsEventListener(this);
  },
  
  open: ajaxOpen,
  
  initForm: function() {
    jslog.debug('AbstractEditor.initForm()');
    // ---
    Modalbox.focusableElements = Modalbox._findFocusableElements();
    Modalbox._setFocus();
    // ---
    this.form = $(this.options.formId);
    jslog.debug('form = ' + this.form);
    if (this.form) {
      this.form.observe('submit', this.submitHandler.bindAsEventListener(this));
      this.submitBtn = null;
      this.submitBtns = this.form.select('input[type=submit]');
      this.submitBtns.each(function(s) {
        s.observe('click', this.submitBtnClickHandler);
      }, this);
    }
  },
  
  submitHandler: function(e) {
    jslog.debug('AbstractEditor.submitHandler()');
    e.stop();
    this.form.stopObserving('submit');
    this.submitBtns.each(function(s) {
      s.stopObserving('click', this.submitBtnClickHandler);
    }, this);
    this.request(this.form.up(), this.form.action,
      this.form.serialize(this.submitBtn ? { submit: this.submitBtn.name } : null));
  },

  handleSubmitBtnClick: function(e) {
    this.submitBtn = e.element();
  },

  afterSave: function(response, json) {
    jslog.debug('AbstractEditor.afterSave()');
    if (this.options.closeAfterSave) {
      jslog.debug('hiding Modalbox');
      Modalbox.hide();
    }
    this.options.saved(response, json);
  },
  
  request: function(update, uri, params) {
    jslog.debug('AbstractEditor.request()');
    doAjaxUpdate(update, uri, {
      method: 'post',
      parameters: params,
      evalScripts: true,
      onComplete: function(response, json) {
        jslog.debug('AbstractEditor.request() onComplete()');
        this.initForm();
        if (!this.form) this.afterSave(response, json);
      }.bind(this)
    });
  }
  
});
var RegistrationEditor = Class.create(AbstractEditor, {

  initialize: function($super, options) {
    $super(Object.extend({ formId: 'registrationForm' }, options || {}));
  },

  initForm: function($super) {
    $super();
    if (this.form) {
      var cancel = this.form.down('input[name=cancel]');
      if (cancel) cancel.observe('click', this.handleCancelClick.bindAsEventListener(this));
    }
  },

  openNew: function() {
    this.open(window._contextPath + '/user/registration/form.html', { action: 'add', uri: Pagina.uri },
      { afterLoad: this.initForm.bind(this) });
  },

  openEdit: function() {
    this.open(window._contextPath + '/user/registration/form.html', { action: 'edit' },
      { afterLoad: this.initForm.bind(this) });
  },

  handleCancelClick: function(e) {
    e.stop();
    Modalbox.hide();
  },

  openConfirm: function(token) {
    this.open(window._contextPath + '/user/registration/confirm.html', { token: token }, {
      method: 'post',
      afterHide: function() {
        Pagina.refresh({}, [ 'act', 'token' ]);
      }
    });
  }

});
var ChangePasswordEditor = Class.create(AbstractEditor, {

  initialize: function($super, options) {
    $super(Object.extend({ formId: 'changePasswordForm' }, options || {}));
  },

  initForm: function($super) {
    $super();
    if (this.form) {
      var cancel = this.form.down('input[name=cancel]');
      if (cancel) cancel.observe('click', this.handleCancelClick.bindAsEventListener(this));
    }
  },

  openForm: function() {
    this.open(window._contextPath + '/user/change-password/form.html', { uri: Pagina.uri },
      { afterLoad: this.initForm.bind(this) });
  },

  handleCancelClick: function(e) {
    e.stop();
    Modalbox.hide();
  },

  openConfirm: function(token) {
    this.open(window._contextPath + '/user/change-password/confirm.html', { token: token }, {
      method: 'post',
      afterHide: function() {
        Pagina.refresh({}, [ 'act', 'token' ]);
      }
    });
  }

});
var RequestRoleEditor = Class.create(AbstractEditor, {

  initialize: function($super, options) {
    $super(Object.extend({ formId: 'requestRoleForm' }, options || {}));
  },

  initForm: function($super) {
    $super();
    if (this.form) {
      var cancel = this.form.down('input[name=cancel]');
      if (cancel) cancel.observe('click', this.handleCancelClick.bindAsEventListener(this));
      this.form.select('input[type=checkbox]').each(function(item) {
        item.disabled = item.checked;
      });
    }
  },

  openForm: function() {
    this.open(window._contextPath + '/user/request-role/form.html', {},
      { afterLoad: this.initForm.bind(this) });
  },

  handleCancelClick: function(e) {
    e.stop();
    Modalbox.hide();
  }

});
var UnregistrationEditor = Class.create(AbstractEditor, {

  initialize: function($super, options) {
    $super(Object.extend({ formId: 'unregistrationForm' }, options || {}));
  },

  initForm: function($super) {
    $super();
    if (this.form) {
      var cancel = this.form.down('input[name=cancel]');
      if (cancel) cancel.observe('click', this.handleCancelClick.bindAsEventListener(this));
    }
  },

  openForm: function() {
    this.open(window._contextPath + '/user/unregistration/form.html', { uri: Pagina.uri },
      { afterLoad: this.initForm.bind(this) });
  },

  handleCancelClick: function(e) {
    e.stop();
    Modalbox.hide();
  },

  openConfirm: function(token) {
    this.open(window._contextPath + '/user/unregistration/confirm.html', { token: token }, {
      method: 'post',
      afterHide: function() {
        Pagina.refresh({}, [ 'act', 'token' ]);
      }
    });
  }

});
var UserProfile = Class.create(AbstractControl, {

  initialize: function($super, element, options) {
    var opt = { reloadUrl: 'user-profile/reload.html' };
    Object.extend(opt, options || {});
    $super(element, opt);
  },

  initDomReferences: function($super) {
    $super();
    this.register = this.element.down('a[name=register]');
    this.forgotPassword = this.element.down('a[name=forgotPassword]');
    this.editProfile = this.element.down('a[name=editProfile]');
    this.requestRole = this.element.down('a[name=requestRole]');
    this.unregister = this.element.down('a[name=unregister]');
    this.manageRoleRequests = this.element.down('a[name=manageRoleRequests]');
  },

  addEventHandlers: function($super) {
    $super();
    this.click('register');
    this.click('forgotPassword');
    this.click('editProfile');
    this.click('requestRole');
    this.click('unregister');
    this.click('manageRoleRequests');
  },

  handleRegister: function(e) {
    e.stop();
    new RegistrationEditor({ closeAfterSave: false }).openNew();
  },

  handleEditProfile: function(e) {
    e.stop();
    new RegistrationEditor({ closeAfterSave: false }).openEdit();
  },

  handleForgotPassword: function(e) {
    e.stop();
    new ChangePasswordEditor({ closeAfterSave: false }).openForm();
  },

  handleRequestRole: function(e) {
    e.stop();
    new RequestRoleEditor({ closeAfterSave: false }).openForm();
  },

  handleUnregister: function(e) {
    e.stop();
    new UnregistrationEditor({ closeAfterSave: false }).openForm();
  },

  handleManageRoleRequests: function(e) {
    e.stop();
    new ManageRoleRequestsEditor({ closeAfterSave: false }).openForm();
  },

  confirm: function(act, token) {
    switch (act) {
      case 'confirm-registration':
        new RegistrationEditor({ closeAfterSave: false }).openConfirm(token);
        break;
      case 'confirm-change-password':
        new ChangePasswordEditor({ closeAfterSave: false }).openConfirm(token);
        break;
      case 'confirm-unregistration':
        new UnregistrationEditor({ closeAfterSave: false }).openConfirm(token);
        break;
    }
  }

});
var Youtube = Class.create(AbstractEditableControl, {

  initialize: function($super, element, idYoutube, options) {
    var opt = {
      reloadUrl: 'youtube/reload.html',
      newEditor: function() {
        return new Youtube.Editor({ saved: function() {
          this.reload();
        }.bind(this) });
      }.bind(this),
      removeUrl: 'colonna/removeElemento.html'
    };
    Object.extend(opt, options || {});
    $super(element, idYoutube, opt);

    var swfobject = new SWFObject(
      window._contextPath + '/swf/player.swf','player',
      this.options.width,
      this.options.height,
      '9',
      '#ffffff');
    swfobject.addParam('allowfullscreen','true');
    swfobject.addParam('allowscriptaccess','always');
    swfobject.addParam('wmode','opaque');
    swfobject.addParam('flashvars', Object.toQueryString({
      file: this.options.url,
      controlbar: 'over',
      type: 'youtube',
      image: 'http://img.youtube.com/vi/' + this.options.url.split('?')[1].toQueryParams()['v'] + '/0.jpg'
    }));
    var version = deconcept.SWFObjectUtil.getPlayerVersion();
    if (version["major"] == 0 || version["major"] < 9) {
     this.element.down('.no-player').setStyle('display','block');
    } else {
     swfobject.write(this.element.down('.preview'));
    }
  }
  
});
