function Basket(id, aGroups) {
  Basket.superclass.call(this, id, aGroups);
  this.apples = [];
}
extend(Basket, YAHOO.util.DDTarget);

// need an insertion marker so during drag it is apparent where
// the dragged apple would be inserted if dropped at that moment.
Basket.createMarker = function() {
  Basket.markerDiv = document.createElement("div");
  Basket.markerDiv.id = "basketMarker";
  var s = Basket.markerDiv.style;
  s.position = "absolute";
  s.visibility = "hidden";
  s.zIndex = 998; // one lower in stack than DDProxy proxy
  s.background = "black";
  s.height = "4px";
  document.body.appendChild(Basket.markerDiv);
};
YAHOO.util.Event.addListener(window, 'load', Basket.createMarker);

Basket.prototype.addApple = function(apple) {
  this.apples.push(apple);
};

Basket.prototype.findApples = function(tagName, aGroups) {
  var child, i;
  var children = this.getEl().childNodes;
  for (i=0; i<children.length; i++) {
    child = children[i];
    if (child.tagName 
        && child.tagName.toLowerCase() === tagName.toLowerCase()) {
      this.addApple(new Apple(child, aGroups));      
    }
  }
};

Basket.prototype.getApples = function() {
  return this.apples;
};

// Override methods and helpers below ----------------------------------

Basket.prototype.onDragEnter = function() {
  YAHOO.util.Dom.addClass(this.getEl(), 'hovered');
};

Basket.prototype.onDragOutOrDrop = function() {
  YAHOO.util.Dom.removeClass(this.getEl(), 'hovered');
  Basket.markerDiv.style.visibility = "hidden";
};

Basket.prototype.onDragOut = function() {
  this.onDragOutOrDrop();
};


// The business of my sortable list idea is below here-----------

// Cache the regions of each related basket and it's contained apples

Basket.prototype.cacheRegion = function() {
  this._region = YAHOO.util.Dom.getRegion(this.getEl());
};

Basket.prototype.getCachedRegion = function() {
  return this._region;  
};

Basket.startDrag = function(draggedApple) {
  var i, j, basket, apples, apple;
  var baskets = YAHOO.util.DragDropMgr.getRelated(draggedApple, true);
  for (i=0; i<baskets.length; i++) {
    basket = baskets[i];
    // Cache the basket region
    basket.cacheRegion();
    apples = basket.getApples();
    for (j=0; j<apples.length; j++) {
      // Cache the apple region
      apples[j].cacheRegion();
    }
  }
};

// During a dragover, determine if currently the pointer
// wants to place dragged apple above another apple or
// at the end of the list.
Basket.prototype.findWhich = function(e) {
  var apple, i, midline, apple_region;
  var y = YAHOO.util.Event.getPageY(e);
  var apples = this.getApples();
  // assume that we are trying to move dragged apple to bottom of list
  var which = this;
  var min = this.getCachedRegion().bottom;
  for (i=0; i<apples.length; i++) {
    apple = apples[i];
    // calculate the midline of the apple and
    apple_region = apple.getCachedRegion();
    midline = (apple_region.bottom-apple_region.top)/2 + apple_region.top;
    // check if cursor is above midline of apple and if this midline
    // is the heighest midline checked. This means apples do not have to 
    // be stored in order in this.apples.
    if (y<midline && y<min) {
      which = apple;
      min = y;
    }
  }
  // Return either this basket or the apple above which
  // the user wants to insert the dragged apple.
  return which;
};

// show the insertion marker in the appropriate location
Basket.prototype.onDragOver = function(e) {
  var which = this.findWhich(e);
  var which_region = which.getCachedRegion();
  // Note that the marker is never inserted into the list.
  // The marker floats above.
  if (which === this) {
    Basket.markerDiv.style.top = (which_region.bottom-6)+"px";  
  } else {
    Basket.markerDiv.style.top = (which_region.top-2)+"px";    
  }
  Basket.markerDiv.style.visibility = "visible";
  Basket.markerDiv.style.width = (which_region.right-which_region.left)+"px";
  Basket.markerDiv.style.left = which_region.left+"px";
};


// Insert a div where the drop occured. This could be used as a loading
// indicator to show that the client has sent an AJAX request to the server
// for approval of this move. The actual move could occur after
// a positive response
Basket.prototype.onDragDrop = function(e, apples) {
  this.onDragOutOrDrop();
  var which = this.findWhich(e);
  var temp = document.createElement("div");
  temp.appendChild(document.createTextNode("Verifying Move"));
  if (which === this) {
    which.getEl().appendChild(temp);
  } else {
    which.getEl().parentNode.insertBefore(temp, which.getEl());
  }
  // Do AJAX request here
};