iYIM.ycarousels = [];

iYIM.YCarousel = function(carouselElementID, carouselCfg, oArgs) {
  this.init(carouselElementID, carouselCfg, oArgs);
};

iYIM.YCarousel.prototype = {
  init: function(id, cfg, oargs) {  
    this.pageSize = cfg.numVisible || 3; 
    this.totalRecords = cfg.size || null;
    
    this.id = oargs.id;  
    this.currentCount = oargs.initCount || 0;
    this.remoteUrl = oargs.remoteUrl || null;
    this.remoteMinItems = oargs.remoteMinItems || this.pageSize;
    this.remoteUseQS = oargs.remoteUseQS || false;
    this.paginatorConfig = oargs.paginatorConfig || {};  
    this.className = oargs.className;
    this.prevElement = oargs.prevElement || null;
    this.nextElement = oargs.nextElement || null;
    this.autoPlay = cfg.autoPlay || null;
    
    this.pageChanging = false;
  
    var config = {
      loadInitHandler:   this.loadInitialItems,
      loadNextHandler:   this.loadNextItems,
      loadPrevHandler:   this.loadPrevItems,
      prevButtonStateHandler: this.handlePrevButtonState,
      nextButtonStateHandler: this.handleNextButtonState
    };
    if (oargs.prevElement) {
      config['prevElement'] = oargs.prevElement;      
    }
    if (oargs.nextElement) {
      config['nextElement'] = oargs.nextElement;      
    }
    for (var key in cfg) {
       if (!cfg.hasOwnProperty(key)) { 
        continue; 
       }
       config[key] = cfg[key];
    }
  
    this.carousel = new YAHOO.extension.Carousel(id, config);
    this.carousel.iYOwner = this;
    
    if (this.carousel.noitems) {
      this.carousel.reload();
    }
    
    if (oargs.createPaginator) {
      this.paginator = new iYW.Paginator({
        rowsPerPage: this.pageSize,
        totalRecords: this.totalRecords,
        containers: "ycarousel-paginator-"+this.id,
        template: this.paginatorConfig.template || "{PreviousPageLink} {CurrentPageReport} {NextPageLink}",
        previousPageLinkLabel: this.paginatorConfig.previousPageLinkLabel || "&lt;",
        nextPageLinkLabel: this.paginatorConfig.nextPageLinkLabel || "&gt;",
        pageReportTemplate: this.paginatorConfig.pageReportTemplate || "{currentPage} of {totalPages}"
      });
      this.paginator.YC = this;
      this.paginator.subscribe('pageChange', this.handlePageChange, this, true);
      this.paginator.subscribe('changeRequest', this.handlePagination, this, true);
      this.paginator.render();
      this.paginator.INIT = true;
      this.handlePagination(this.paginator.getState());
      this.paginator.INIT = false;      
    }
  },

  loadInitialItems: function(type, args) {
    var start = args[0];
    var last = args[1];
    var alreadyCached = args[2];
    
    if (!alreadyCached) {
      if (this.iYOwner) {      
        this.iYOwner.makeRequest(start, last-start+1);
      }
      else {
        this.noitems = true;
      }
    }
  },
  
  loadNextItems: function(type, args) {
    var start = args[0];
    var last = args[1];
    var alreadyCached = args[2];
    
    if (!alreadyCached) {
      this.iYOwner.makeRequest(start, last-start+1);
    }
    
    if (this.iYOwner.paginator && !this.iYOwner.pageChanging) {
      this.iYOwner.paginator.setPage(Math.floor((start-1)/this.iYOwner.pageSize)+1);
    }
  },
  
  loadPrevItems: function(type, args) {
    var start = args[0];
    var last = args[1];
    var alreadyCached = args[2];
    
    if (!alreadyCached) {
      this.iYOwner.makeRequest(start, last-start+1);    
    }
    
    if (this.iYOwner.paginator && !this.iYOwner.pageChanging) {
      this.iYOwner.paginator.setPage(Math.floor((start-1)/this.iYOwner.pageSize)+1);
    }
  },
  
  handlePrevButtonState: function(type, args) {
  },

  handleNextButtonState: function(type, args) {
  },
  
  getRemoteURL: function(rurl, st, cnt, useqs) {
    if (!useqs) {
      return rurl+'/'+(st-1)+'/'+cnt;
    }
    else {
      return rurl+'?start='+st+'&count='+cnt;
    }  
  },
  
  makeRequest: function(start, count) {
    var request_count = Math.max(count, this.remoteMinItems);
    var url = this.getRemoteURL(this.remoteUrl, start, request_count, this.remoteUseQS);
    iYUDm.setStyle("imedia-ycarousel-loading-"+this.id, "visibility", "visible");
    var myCB = this;
    iYU.Connect.asyncRequest("GET", url, {
      success: function (o) {
        var newitems = Drupal.parseJson(o.responseText);
        for (var i=0; i < newitems.length; i++) {
          myCB.carousel.addItem(start+i, newitems[i]);
        }
        iYUDm.setStyle("imedia-ycarousel-loading-"+myCB.id, "visibility", "hidden");
      },      
      failure: function (o) {
        iYUDm.setStyle("imedia-ycarousel-loading-"+myCB.id, "visibility", "hidden");
      }
    });
  },
  
  handlePagination: function(state) {
    this.pageChanging = true;
    if (!this.paginator.INIT && this.carousel._autoPlayTimer != null) {
      this.carousel.stopAutoPlay();
    }
    this.carousel.scrollTo(state.recordOffset+1);      
    this.paginator.setState(state);    
    this.pageChanging = false;
  },
  
  handlePageChange: function(a) {
    if (a.newState && a.newState.paginator && a.newState.paginator.YC && !a.newState.paginator.YC.autoPlay) {
      itunes_event();
      
    }
  },

  insertItem: function(data) {
    var item = data || null;
    if (item) {
      this.carousel.insertBefore(1, item);
    }
    else {
      var url = this.getRemoteURL(this.remoteUrl, 0, 1, this.remoteUseQS);
      var myCB = this;
      iYU.Connect.asyncRequest("GET", url, {
          success: function (o) {
              var newitems = Drupal.parseJson(o.responseText);
              if (newitems && newitems[0]) {
                var olditem = myCB.carousel.getItem(1);
                if (olditem) {
                  olditem = olditem.innerHTML;
                  olditem = olditem.replace(/[\s\n\r\/><]/g, "");
                  var checknewitem = newitems[0].replace(/[\s\n\r\/><]/g, "");
                }
                if (!olditem || checknewitem != olditem) {
                  myCB.carousel.insertBefore(1, newitems[0]);
                }
              }
          }
      });      
    }
  }
};

/**
 * Returns an array of ycarousels that their wrapper class is c
 *
 * @method findIMediaYCarouselByClassName
 * @param c {string} The name of the class to find
 * @return {Array}
 * @static
 */
iYIM.findIMediaYCarouselByClassName = function(c) {
  var res = [];
  if (iYIM && iYIM.ycarousels) {      
    for(var i = 0; i < iYIM.ycarousels.length; i++) {
      if (iYIM.ycarousels[i].className == c) {
        res.push(iYIM.ycarousels[i]);
      }
    }
  }
  return res;
}

