var NewsrollNS = {
  _instance: null,

  initialize: function(container) {
    var id = 'newsroller';
    var el = $(id);
    if(!$defined(el))
      throw new Error('No element #' + id + ' defined');
    NewsrollNS._instance = new NewsrollNS.Newsroller(el, 7000).run();
  },

  Newsroller: new Class({
    /* Create a new Newsroller.
     * container - the HTML element where the news of the newsroller have to go
     */
    initialize: function(container, delay) {
      this.container = container;
      this.delay = delay;
      this.container.setStyles({
        overflow: 'hidden',
        position: 'relative'}); // "relative" as workaround to IE bug: http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/RelPosChildNotClippedByParentOverflowHidden.html
    },

    /* Run the Newsroller. Request for the newslist, and then make it start. */
    run: function() {
      // get out all data
      var get_list_bridge = false;
      var url = get_list_bridge ? get_list_bridge : "http://www.friendlysalento.it/newsroll/get_list";
      new Ajax(url, {onComplete: this.elementListLoaded.bind(this)}).request();
      return this;
    },

    /* Called upon reception of the list of news in the expected format. Load the first news and start the cycling. */
    elementListLoaded: function(text, xml) {
      // load the element list in the object
      var res = Json.evaluate(text);
      this.newsIds = res[1];
      this.currentIndex = 0;
      this.elementList = [res[0]];
      // prepare the HTML structure
      this.container.empty();
      var rootElement = this._createNewsContainer()
        .setHTML(this.elementList[0])
        .injectInside(this.container);
      this.container.setStyle('height', this.container.getSize().size.y); // needed for IE6 + workaround
      // start the motion
      this.moving = 0;
      this._switchFunction = this.switchElement.periodical(this.delay, this);
      return this;
    },

    /* Timeout arrived, must switch between news. Check if we already have the news, or load it from the
       server in case. */
    switchElement: function() {
      if(this.elementList.length < this._numNews())
      {
        // list is not complete, we'll have to load a new element
        var get_news_bridge = false;
        var url = get_news_bridge ? get_news_bridge : "http://www.friendlysalento.it/newsroll/get_news";
        new Ajax(url, {
          data: Object.toQueryString({id: this.newsIds[this.currentIndex+1]}),
          onComplete: function(text, xml) {
            this.elementList.push(Json.evaluate(text));
            this.loadNextElement();
          }.bind(this)
        }).request();
      }
      else
        this.loadNextElement();
      return this;
    },

    /* Load the next news providing a smooth transation. The news must have already been loaded. */
    loadNextElement: function() {
      // are we still switching some element...?
      if(this.moving > 0) return;
      this.moving += 2;
      // get out old div
      var oldElement = this.container.getChildren()[0];
      // create and put the new element at the bottom
      this.currentIndex = (this.currentIndex + 1) % this._numNews();
      var newElement = this._createNewsContainer()
        .setHTML(this.elementList[this.currentIndex])
        .injectInside(this.container);
      // make the elements move up
      var delta = newElement.getPosition().y - oldElement.getPosition().y;
      for(var i = 0; i < 2; i++) {
        var el = [oldElement, newElement][i];
        new Fx.Style(el, 'top', {
          duration: 500, 
          transition: Fx.Transitions.Sine.easeInOut,
          onComplete: function(el) {
            this.moving -= 1;
            if(this.moving == 0) {
              oldElement.remove();
              newElement.setStyle('top', '0px');
            }
          }.bind(this)
        }).start(-delta);
      }
      return this;
    },

    // create the div which contains the news
    _createNewsContainer: function() {
      return new Element('div', {
        'class': 'news_list clear',
        styles: {
          position: 'relative',
          top: '0px'
        }});
    },

    // get the total number of news
    _numNews: function() {
     return this.newsIds.length;
    }
  })

};

window.addEvent('domready', NewsrollNS.initialize);
