/* ====================================================================
 * Copyright (c) 2007-2008  Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "IconFactory.h"
#include "sublib/Utility.h"

// qt
#include <QtGui/QPixmap>
#include <QtGui/QImage>
#include <QtGui/QPainter>


/**
 * Create the "normal" @c QImage for the given @a iconImage. Just returns
 * the image as we get it from disk.
 */
static QPixmap loadPixmap( const QString& iconImage )
{
  return QPixmap( getIconDir() + iconImage );
}

/**
 * Create the "active" @c Pixmap for the given @a iconImage. The "active"
 * pixmap is created by making every pixel darker.
 */
static QPixmap createActive( const QPixmap& iconImage )
{
  QImage srcImage = iconImage.toImage();
  QSize  size     = srcImage.size();

  for( int y = 0; y < size.height(); y++ )
  {
    for( int x = 0; x < size.width(); x++ )
    {
      QRgb value = srcImage.pixel(x,y);
      int  alpha = qAlpha(value);

      if( !value && !alpha )
        continue;

      QColor c(value);
      c = c.dark(120);

      // darkening the color looses the alpha information so we have
      // to create the new rgb value by hand.
      QRgb newvalue = qRgba(c.red(),c.green(),c.blue(),alpha);
      srcImage.setPixel(x,y,newvalue);
    }
  }

  return QPixmap::fromImage(srcImage);
}

/**
 * Create the "disabled" @c Pixmap for the given @a iconImage. The "disabled"
 * pixmap is created by reducing the alpha value of each pixel to increase its
 * transparency.
 */
static QPixmap createDisabled( const QPixmap& iconImage )
{
  QImage srcImage   = iconImage.toImage();
  QImage srcImage32 = srcImage.convertToFormat(QImage::Format_ARGB32);
  QSize  size       = srcImage32.size();

  for( int y = 0; y < size.height(); y++ )
  {
    for( int x = 0; x < size.width(); x++ )
    {
      QRgb value = srcImage32.pixel(x,y);
      int  alpha = qAlpha(value);

      if( !value && !alpha )
        continue;

      QColor c(value);

      // => more or less greyscale
      int h, s, v;
      c.getHsv(&h,&s,&v);
      c.setHsv(h,15,v);

      // increase transparency
      double newalpha = alpha * 0.65;

      QRgb newvalue = qRgba(c.red(),c.green(),c.blue(),(int)newalpha);
      srcImage32.setPixel(x,y,newvalue);
    }
  }

  return QPixmap::fromImage(srcImage32);
}

/**
 * Create an @c Icon from the given @a iconImage. If an @a overlayImage is
 * given it is placed in the bottom right corner of the @a iconImage. 
 */
static QIcon createIcon( const QString& iconImage, const QString& overlayImage = QString() )
{
  QPixmap source = loadPixmap(iconImage);

  if( !overlayImage.isNull() )
  {
    QPixmap  overlay = loadPixmap(overlayImage);
    QPainter painter(&source);
    painter.drawPixmap( 16, 16, overlay );
  }

  QIcon icon;
  icon.addPixmap( source,                 QIcon::Normal );
  icon.addPixmap( createActive(source),   QIcon::Active );
  icon.addPixmap( createDisabled(source), QIcon::Disabled );
  return icon;
}

/*
 * Create an toggle @c Icon from the given @a iconImage. If an @a overlayImage
 * is given, it is placed in the bottom right corner of the @a iconImage as an
 * "On" marker. 
 */
static QIcon createToggleIcon( const QString& iconImage, const QString& overlayImage )
{
  QPixmap sourceOff = loadPixmap(iconImage);
  QPixmap sourceOn  = sourceOff.copy();

  QPixmap overlay = loadPixmap(overlayImage);
  QPainter painter(&sourceOn);
  painter.drawPixmap( 0, 0, overlay );

  QIcon icon;
  icon.addPixmap( sourceOff,                 QIcon::Normal, QIcon::Off );
  icon.addPixmap( sourceOn,                  QIcon::Normal, QIcon::On );
  icon.addPixmap( createActive(sourceOff),   QIcon::Active, QIcon::Off );
  icon.addPixmap( createActive(sourceOn),    QIcon::Active, QIcon::On );
  icon.addPixmap( createDisabled(sourceOff), QIcon::Disabled );
  return icon;
}

QIcon IconFactory::createIcon( const QString& iconImage, const QString& overlayImage )
{
  return ::createIcon( iconImage, overlayImage );
}

QIcon IconFactory::createToggleIcon( const QString& iconImage, const QString& overlayImage )
{
  return ::createToggleIcon( iconImage, overlayImage );
}
