var AbstractCart = new Class({
  initialize: function(cart, items) {
    this.cart = cart;
    this.cart._control = this;
    this.items = items;
    this.items.each(function(item) {
      item.addEvent('mousedown', this.handleItemMousedown.bindWithEvent(this, item));
    }, this);
    this.init();
  },
  
  init: function() {
    this.drops = [];
    this.dropFxs = [];
    this.getDroppables().each(function(drop) {
      this.addDrop(drop);
    }, this);
  },
  
  uninit: function() {
  },
  
  getDroppables: function() {
    return [ this.cart ];
  },
  
  addDrop: function(drop) {
    this.drops.push(drop);
    this.dropFxs.push(drop.effect('background-color', {wait: false}));
  },

  handleItemMousedown: function(e, item) {
    e = new Event(e).stop();
    
    var clone = item.clone()
      .setStyles(item.getCoordinates()) // this returns an object with left/top/bottom/right, so its perfect
      .setStyles({'opacity': 0.7, 'position': 'absolute'})
      .addEvent('emptydrop', function() {
        clone.remove();
        this.drops.each(function(drop) {
          drop.removeEvents();
        }, this);
        this.fireEvent('emptydrop', item);
      }.bind(this)).inject(document.body);

    this.drops.each(function(drop, i) {
      drop.addEvents({
        'drop': function() {
          this.drops.each(function(drop) {
            drop.removeEvents();
          }, this);
          clone.remove();
          this.dropItem(item, i);
        }.bind(this),
        'over': function() {
          this.drops[i].setStyle('background-color', '#FFFFFF');
          this.dropFxs[i].start('98B5C1');
        }.bind(this),
        'leave': function() {
          this.dropFxs[i].start('FFFFFF');
        }.bind(this)
      });
    }, this);

    var drag = clone.makeDraggable({
      droppables: this.drops
    }); // this returns the dragged element

    drag.start(e); // start the event manual
  },
  
  dropItem: function(item, i) {
    item.clone().inject(this.drops[i]);
    this.dropFxs[i].start('7389AE').chain(this.dropFxs[i].start.pass('ffffff', this.dropFxs[i]));
    this.fireEvent('dropped', [ item, this.drops[i] ]);
  }
});
AbstractCart.implement(new Events);
