/****************************************************************************
** qdvdauthor.h file.
**
** This file handles the user input to generate a DVD menu.
** Please note that this is work in progress and depends also oin the
** developement of dvdauthor, which is at the moment in version 0.67.
** Future versions of dvdauthort might need changes to this file.
**
*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <qimage.h>
#include <Magick++.h>

#include "global.h"
#include "qimagehelper.h"

QImageHelper::QImageHelper()
	: QImage ()
{
	Magick::Image theImage;
}

QImageHelper::QImageHelper (const QString &fileName, const char *format)
	: QImage (fileName, format)
{

}

QImageHelper::~QImageHelper ()
{ 

}

QStringList &QImageHelper::getAvailableResizeAlgorithms()
{
	static QStringList listAlgorithm;
	listAlgorithm << QT_RESIZE_ALGO << "Point" << "Box" << "Triangle" << "Hermite" << "Hanning" << "Hamming" << "Blackman" << "Gaussian" << "Quadratic" << "Cubic" << "Catrom" << "Mitchell" << "Lanczos" << "Bessel" << "Sinc";
	return listAlgorithm;
	/* */
}

bool QImageHelper::resize (int iWidth, int iHeight, int iResizeAlgorithm)
{
	Magick::Image *pImage = (Magick::Image *)getImageInLibraryFormat ();
	if (!pImage)
		iResizeAlgorithm = -1;
	if (iResizeAlgorithm == 1)
		pImage->filterType(Magick::PointFilter);
	else if (iResizeAlgorithm == 2)
		pImage->filterType(Magick::BoxFilter);
	else if (iResizeAlgorithm == 3)
		pImage->filterType(Magick::TriangleFilter);
	else if (iResizeAlgorithm == 4)
		pImage->filterType(Magick::HermiteFilter);
	else if (iResizeAlgorithm == 5)
		pImage->filterType(Magick::HanningFilter);
	else if (iResizeAlgorithm == 6)
		pImage->filterType(Magick::HammingFilter);
	else if (iResizeAlgorithm == 7)
		pImage->filterType(Magick::BlackmanFilter);
	else if (iResizeAlgorithm == 8)
		pImage->filterType(Magick::GaussianFilter);
	else if (iResizeAlgorithm == 9)
		pImage->filterType(Magick::QuadraticFilter);
	else if (iResizeAlgorithm == 10)
		pImage->filterType(Magick::CubicFilter);
	else if (iResizeAlgorithm == 11)
		pImage->filterType(Magick::CatromFilter);
	else if (iResizeAlgorithm == 12)
		pImage->filterType(Magick::MitchellFilter);
	else if (iResizeAlgorithm == 13)
		pImage->filterType(Magick::LanczosFilter);
	else if (iResizeAlgorithm == 14)
		pImage->filterType(Magick::BesselFilter);
	else if (iResizeAlgorithm == 15)
		pImage->filterType(Magick::SincFilter);
	else { // Qt - Resize is the default
		((QImage &)*this) = smoothScale(iWidth, iHeight);
		return true;
	}

	pImage->sample (Magick::Geometry(iWidth, iHeight));
	setImageFromLibraryFormat (pImage);
	return true;
}

void *QImageHelper::getImageInLibraryFormat()
{
// This function converts the QImage object into a ImageMagic++ Image object
	// So first we create a FreeImage - object.
	static Magick::Image theImage;
	// Here is the cheap and dirty method. We store the QImage as png
	char pTempFileName[] = "/tmp/qdvdXXXXXX";
	mkstemp(pTempFileName);
	char *pNewFileName = new char[strlen (pTempFileName) + 5];
	sprintf (pNewFileName, "%s.png", pTempFileName);
	save (QString(pNewFileName), "PNG");	// save the current image (remember this class is derived from QImage)
	theImage.read (pNewFileName);			// loads the image as ImageMagick object.
	system ((const char *) QString ("rm %1").arg(pNewFileName));
	delete []pNewFileName;
	return (void *)&theImage;
}

bool QImageHelper::setImageFromLibraryFormat(void *pInputImage)
{
// This function converts a ImageMagick++ image - object into a QImage object
	// So first we cast it to ImageMagick++ Image object
	Magick::Image *pImage = (Magick::Image *) pInputImage;
	// Here is the cheap and dirty method. We store the QImage as png
	char pTempFileName[] = "/tmp/qdvdXXXXXX";
	mkstemp(pTempFileName);
	char *pNewFileName = new char[strlen (pTempFileName) + 5];
	sprintf (pNewFileName, "%s.png", pTempFileName);
	pImage->write (pNewFileName);
	// And here we load the image in this object.
	load (pNewFileName, "PNG");
	system ((const char *) QString ("rm %1").arg(pNewFileName));
	delete []pNewFileName;
	return true;
}

bool QImageHelper::dither (int iMaxColors, bool bFloydSteinberg)
{
	Magick::Image *pImage = (Magick::Image *)getImageInLibraryFormat ();
	if (!pImage)
		return false;
	if (bFloydSteinberg)
		pImage->quantizeDither (true);
	else
		pImage->quantizeDither (false);

	// This reduces the number of colors without changing them
	// (when simply quantizing down ImageMagick seems to change
	// the colours to suit itself - bad if you need to retain the
	// bg color for passing to spumux) This method also results in
	// an indexed image which is good :)
//	pImage->colorMapSize(iMaxColors);
	pImage->quantizeColors (iMaxColors);
	pImage->type(Magick::PaletteType);
	pImage->quantize ();

	setImageFromLibraryFormat (pImage);
	return true;
}
/*
bool QImageHelper::dither (int iMaxColors, bool bFloydSteinberg)
{
	Magick::Image *pImage = (Magick::Image *)getImageInLibraryFormat ();
	if (!pImage)
		return false;

	// Make the image transparent - works nicely but spumux doesn't like this...
//	QColor transparentColor (TRANSPARENT_COLOR);
//	char s[] = "#000000";
//	sprintf(s, "#%02x%02x%02x",transparentColor.red(),transparentColor.green(),transparentColor.blue());
//	Magick::Color transparentMColor (s);
//	pImage->transparent(transparentMColor);

	if (bFloydSteinberg)
		pImage->quantizeDither (true);
	else
		pImage->quantizeDither (false);
//	pImage->quantizeColorSpace( GRAYColorspace );
//	pImage->quantizeTreeDepth ( const unsigned int treeDepth_ );

	// This reduces the number of colors without changing them
	// (when simply quantizing down ImageMagick seems to change
	// the colours to suit itself - bad if you need to retain the
	// bg color for passing to spumux) This method also results in
	// an indexed image which is good :)
	pImage->colorMapSize(iMaxColors);
	pImage->quantizeColors (iMaxColors);
	pImage->type(Magick::PaletteType);
	pImage->quantize ();

	setImageFromLibraryFormat (pImage);
	return true;
}
*/
