void pixelBox(const PixelBox& box, isab::MapPlotter* plotter)
{
   std::vector<MC2Point> points;

   points.push_back(box.getTopLeft());
   points.push_back(box.getTopRight());
   points.push_back(box.getBottomRight());
   points.push_back(box.getBottomLeft());
   points.push_back(box.getTopLeft());

   plotter->setPenColor(255, 0, 0);
   plotter->setLineWidth(3);
   
   plotter->drawPolyLine(points.begin(), points.end());
}
void ExternalRenderer::drawBitmapBlock(TriStorageBlock& block,
                                       unsigned int pass,
                                       vec4x* triangleData,
                                       const MC2BoundingBox& box,
                                       OverlapDetector<MC2BoundingBox>& detector,
                                       TileMapContainer& tileMapCont,
                                       TileMapFormatDesc& formatDesc,
                                       bool skipOutlines)
{
   if(pass == 0) {
      return;
   }
   
   for(std::vector<TriSection>::iterator sectIt = block.primitives.begin();
       sectIt != block.primitives.end(); sectIt++){
      TriSection& section = *sectIt;
      TilePrimitiveFeature& feat = *section.src;


      const TileFeatureArg* arg = feat.getArg( TileArgNames::coord );
      const CoordArg* coordArg = static_cast<const CoordArg*>( arg );
      MC2Coordinate coord = coordArg->getCoord();
      
      if( box.contains( coord ) ) {
         const StringArg* bitMapName =
            static_cast<const StringArg*> (
               feat.getArg(TileArgNames::image_name) );
         
         if ( bitMapName == NULL ) {
            continue;
         }
         
         TextureBlock* texture = 
            static_cast<TextureBlock*>(
               m_impl->mapHandler->getOrRequestBitMap(
                  bitMapName->getValue() ) );
         
         if ( texture != NULL ) {
            MC2Point position;
            transform(position, coord);
            
            /**
             *   We subtract the anchor position, to position the texture
             *   on the anchor instead of the top left corner. */
            PixelBox overlapBox = texture->boundingBox;
            MC2Point topLeft = overlapBox.getTopLeft();
            MC2Point bottomRight = overlapBox.getBottomRight();
            
            overlapBox.set( topLeft, bottomRight );

            overlapBox.move(
               MC2Point( position.getX(), position.getY() ) );

            bool notOverlapping = true;

            notOverlapping = detector.addIfNotOverlapping( overlapBox );

            if (notOverlapping) {
               drawSprite( texture,
                           position,
                           0.0f,
                           texture->centerOffset,
                           1.0f, 1.0f);
               
               feat.setDrawn( true );
            }
         }
      }
   }
}
void StackedSet::update()
{
   clear();

   // Since overlap should be calculated using the precision scaled dimensions
   // we need to precision scale the bounding box for the screen.
   PixelBox screenBox = m_projection.getPixelBoundingBox();

   MC2Point topLeft(screenBox.getTopLeft().getX() * SCALING_CONSTANT,
                    screenBox.getTopLeft().getY() * SCALING_CONSTANT);
   MC2Point bottomRight(screenBox.getBottomRight().getX() * SCALING_CONSTANT,
                        screenBox.getBottomRight().getY() * SCALING_CONSTANT);
   PixelBox screenBoxScaled(topLeft, bottomRight);
   
   for( OverlayViewLayerInterface::LayerMap::iterator itr =
           m_layerInterface.begin();
        itr != m_layerInterface.end(); itr++)
   {
      Layer& l = *itr->second;

      if(!l.getVisible()) {
         // We don't need to detect any overlaps with invisible layers.
         continue;
      }

      for(Layer::const_iterator itemItr = l.items_begin();
          itemItr != l.items_end(); itemItr++)
      {
         OverlayItemInternal* item = *itemItr;
         
         initItem(item);
         
         if (!screenBoxScaled.overlaps(item->getPrecisionScaledPixelBox())) {
            // The item lies outside the screen, do NOT add it to the stacks.
            continue;
         }
         
         addToStackSet(item);
      }
   }

   
#ifdef USE_SMOOTHING
   // Smooth the positions of the stacks to represent the average
   // of the contained items' positions.
   smoothPositions();
#endif 
   
#ifdef USE_SMOOTHING
#ifdef USE_ITERATIVE_SMOOTHING
   // Since we have changed the position of the stacks, we run another
   // pass of overlap detection.
   unsigned int prevSize = 0; 
   unsigned int iterationCap = ITERATIVE_SMOOTHING_CAP;

   // If the number of stacks has not changed, no stacks overlapped
   // so the iteration should terminate.
   while (prevSize != m_stacks.size() && iterationCap > 0) {
      StackVec tempVec = m_stacks;
      prevSize = m_stacks.size();

      clear();
   
      for(StackVec::iterator itr = tempVec.begin();
          itr != tempVec.end(); itr++) {
         addToStackSet(*itr);
         
      }
   
      smoothPositions();
      --iterationCap;
   }
#endif
#endif
   
   OverlayItemInternal* currClosest = NULL;
   if ( m_stacks.size() != 0 && m_automaticHighlightMode){
      // Find out which item is closest to the center of the screen
      
      MC2Point screenCenter;
      m_projection.transform(screenCenter, m_projection.getCenter());
   
      WFAPI::wf_float64 closestDistSq = 0;

      currClosest = *m_stacks.begin();
      closestDistSq = getSquareScreenDistance(screenCenter, currClosest);
         
      for(StackedSet::StackVec::const_iterator itr = m_stacks.begin();
          itr != m_stacks.end(); itr++)
      {
         WFAPI::wf_float64 currDistSq = getSquareScreenDistance(screenCenter,
                                                                *itr);
         if (currDistSq < closestDistSq){
            currClosest = *itr;
            closestDistSq = currDistSq;
         }
      }
      // If the currently closest item is further away than RADIUS pixels,
      // disregard it.
      const unsigned int RADIUS = 75;
      if (closestDistSq > RADIUS * RADIUS){
         currClosest = NULL;
         closestDistSq = 0;
      }
   }
   updateClosest(currClosest);
   
   if (m_closest.item && automaticHighlightEnabled()){
      m_closest.item->m_isHighlighted = true;
      // Since we don't care pixel scale the item is on, we
      // use 0 as the current pixel scale.
      const WFAPI::OverlayItemVisualSpec* highlighted =
         OverlayItemUtil::getCurrentVisualSpec(m_closest.item, 0);
      
      if(highlighted) {
         updateItemPixelBox(m_closest.item, highlighted,
                            m_closest.item->m_adjustedPosition);
      }
   }
   
}