/// Takes a background image, foreground image, and mask
/// (i.e. the alpha channel for the foreground), and
/// returns an new image where the foreground has been
/// overlaid onto the background using alpha-blending,
/// at location (xoff, yoff).
wxImage *OverlayImage(teBmps eBack, teBmps eForeground,
                      int xoff, int yoff)
{
   wxImage imgBack(theTheme.Image( eBack       ));
   wxImage imgFore(theTheme.Image( eForeground ));


   // TMP: dmazzoni - just so the code runs even though not all of
   // our images have transparency...
   if (!imgFore.HasAlpha())
      return new wxImage(imgBack);


   wxASSERT( imgFore.HasAlpha() );

   unsigned char *bg = imgBack.GetData();
   unsigned char *fg = imgFore.GetData();
   unsigned char *mk = imgFore.GetAlpha();

   int bgWidth = imgBack.GetWidth();
   int bgHeight = imgBack.GetHeight();
   int fgWidth = imgFore.GetWidth();
   int fgHeight = imgFore.GetHeight();


   //Now, determine the dimensions of the images to be masked together
   //on top of the background.  This should be equal to the area of the
   //smaller of the foreground and the mask, as long as it is 
   //within the area of the background, given the offset.

   //Make sure the foreground size is no bigger than the mask
   int wCutoff = fgWidth;
   int hCutoff = fgHeight;


   // If the masked foreground + offset is bigger than the background, masking
   // should only occur within these bounds of the foreground image
   wCutoff = (bgWidth - xoff > wCutoff) ? wCutoff : bgWidth - xoff;
   hCutoff = (bgHeight - yoff > hCutoff) ? hCutoff : bgHeight - yoff;

   //Make a new image the size of the background
   wxImage * dstImage = new wxImage(bgWidth, bgHeight);
   unsigned char *dst = dstImage->GetData();
   memcpy(dst, bg, bgWidth * bgHeight * 3);

   // Go through the foreground image bit by bit and mask it on to the
   // background, at an offset of xoff,yoff.
   // BUT...Don't go beyond the size of the background image,
   // the foreground image, or the mask 
   int x, y;
   for (y = 0; y < hCutoff; y++) {

      unsigned char *bkp = bg + 3 * ((y + yoff) * bgWidth + xoff);
      unsigned char *dstp = dst + 3 * ((y + yoff) * bgWidth + xoff);

      for (x = 0; x < wCutoff; x++) {

         int value = mk[(y * fgWidth + x)];// Don't multiply by 3...
         int opp = 255 - value;

         for (int c = 0; c < 3; c++)
            dstp[x * 3 + c] = 
               ((bkp[x * 3 + c] * opp) + 
                (fg[3 * (y * fgWidth + x) + c] * value)) / 255;
      }
   } 
   return dstImage;
}
/// Takes a background image, foreground image, and mask
/// (i.e. the alpha channel for the foreground), and
/// returns an NEW image where the foreground has been
/// overlaid onto the background using alpha-blending,
/// at location (xoff, yoff).
std::unique_ptr<wxImage> OverlayImage(teBmps eBack, teBmps eForeground,
                      int xoff, int yoff)
{
   wxImage imgBack(theTheme.Image( eBack       ));
   wxImage imgFore(theTheme.Image( eForeground ));


   // TMP: dmazzoni - just so the code runs even though not all of
   // our images have transparency...
   if (!imgFore.HasAlpha())
      return std::make_unique<wxImage>(imgBack);


   wxASSERT( imgFore.HasAlpha() );

   unsigned char *bg = imgBack.GetData();
   unsigned char *fg = imgFore.GetData();
   unsigned char *mk = imgFore.GetAlpha();

   int bgWidth = imgBack.GetWidth();
   int bgHeight = imgBack.GetHeight();
   int fgWidth = imgFore.GetWidth();
   int fgHeight = imgFore.GetHeight();


   //Now, determine the dimensions of the images to be masked together
   //on top of the background.  This should be equal to the area of the
   //smaller of the foreground and the mask, as long as it is
   //within the area of the background, given the offset.

   //Make sure the foreground size is no bigger than the mask
   int wCutoff = fgWidth;
   int hCutoff = fgHeight;


   // If the masked foreground + offset is bigger than the background, masking
   // should only occur within these bounds of the foreground image
   wCutoff = (bgWidth - xoff > wCutoff) ? wCutoff : bgWidth - xoff;
   hCutoff = (bgHeight - yoff > hCutoff) ? hCutoff : bgHeight - yoff;

   //Make a NEW image the size of the background
   auto dstImage = std::make_unique<wxImage>(bgWidth, bgHeight);
   unsigned char *dst = dstImage->GetData();
   memcpy(dst, bg, bgWidth * bgHeight * 3);

   // If background image has tranparency, then we want to blend with the 
   // current backgorund colour.
   if( imgBack.HasAlpha() ){
      unsigned char *pAlpha = imgBack.GetAlpha();
      wxColour c = theTheme.Colour( clrMedium  );
      unsigned char onePixImage[3];
      // GetData() guarantees RGB order [wxWidgets does the ocnversion]
      onePixImage[ 0 ] = c.Red();
      onePixImage[ 1 ] = c.Green();
      onePixImage[ 2 ] = c.Blue();
      for( int i=0;i< bgWidth*bgHeight;i++){
         unsigned char * pPix = &dst[ 3*i];
         float alpha = 1.0 - (pAlpha[i]/255.0);
         pPix[0] = pPix[0] + alpha *( (int)onePixImage[0]-(int)pPix[0]);
         pPix[1] = pPix[1] + alpha *( (int)onePixImage[1]-(int)pPix[1]);
         pPix[2] = pPix[2] + alpha *( (int)onePixImage[2]-(int)pPix[2]);
      }
   }

   // Go through the foreground image bit by bit and mask it on to the
   // background, at an offset of xoff,yoff.
   // BUT...Don't go beyond the size of the background image,
   // the foreground image, or the mask
   int x, y;
   for (y = 0; y < hCutoff; y++) {

      unsigned char *bkp = bg + 3 * ((y + yoff) * bgWidth + xoff);
      unsigned char *dstp = dst + 3 * ((y + yoff) * bgWidth + xoff);

      for (x = 0; x < wCutoff; x++) {

         int value = mk[(y * fgWidth + x)];// Don't multiply by 3...
         int opp = 255 - value;

         for (int c = 0; c < 3; c++)
            dstp[x * 3 + c] =
               ((bkp[x * 3 + c] * opp) +
                (fg[3 * (y * fgWidth + x) + c] * value)) / 255;
      }
   }
   return dstImage;
}