/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/

#ifndef SCCOLORSPACE_H
#define SCCOLORSPACE_H

#include <QSharedPointer>
#include <QWeakPointer>
#include "scribusapi.h"
#include "sccolorprofile.h"
#include "sccolorspacedata.h"
#include "sccolortransform.h"

class SCRIBUS_API ScColorSpace
{
public:
	ScColorSpace();
	explicit ScColorSpace(ScColorSpaceData*);
	explicit ScColorSpace(const QSharedPointer<ScColorSpaceData>&);

	ScColorMgmtEngine& engine() { return m_data->engine(); }
	const ScColorMgmtEngine& engine() const { return m_data->engine(); }

	void reset() { m_data.reset(); }
	bool isNull()    const { return m_data.isNull(); }
	operator bool () const { return !isNull(); }

	eColorType   type() const;
	eColorFormat colorFormat() const;
	ScColorProfile profile() const;

	uint  numChannels()     const;
	uint  bytesPerChannel() const;

	bool  hasAlphaChannel() const;
	uint  alphaIndex()      const;

	// Restore full opacity of alpha channel
	void flattenAlpha(void* dataIn, uint numElems);

	// Function to create transform to a specific output color space
	ScColorTransform createTransform(const ScColorSpace& outputSpace, eRenderIntent renderIntent, 
	                                 long transformFlags);
	ScColorTransform createTransform(const ScColorProfile& outputProfile, eColorFormat outputFormat,
	                                 eRenderIntent renderIntent, long transformFlags);

	// Function to create proofing transform to a specific output color space and a specific proofing device
	ScColorTransform createProofingTransform(const ScColorSpace& outputSpace, const ScColorProfile& proofing, 
	                                         eRenderIntent renderIntent,  eRenderIntent proofingIntent, 
											 long transformFlags);
	ScColorTransform createProofingTransform(const ScColorProfile& outputProfile, eColorFormat outputFormat,
											 const ScColorProfile& proofing, eRenderIntent renderIntent, 
	                                         eRenderIntent proofingIntent, long transformFlags);

	// Convert color data to a specific color space
	bool convert(ScColorSpace& data, eRenderIntent renderIntent, long transformFlags,
				 void* dataIn, void* dataOut, uint numElems, ScColorTransform* lastTrans = nullptr);
	bool convert(ScColorSpace& data, eRenderIntent renderIntent, long transformFlags, 
				 void* dataIn, QIODevice* device, uint numElems, ScColorTransform* lastTrans = nullptr);

	const ScColorSpaceData* data() const { return m_data.data(); }

	bool operator==(const ScColorSpace& other) const;

	ScColorSpace& operator=(const ScColorSpace& other) = default;
	ScColorSpace& operator=(std::nullptr_t) { m_data.reset(); return *this; }

private:
	QSharedPointer<ScColorSpaceData> m_data;

	QWeakPointer<ScColorSpaceData>   weakRef()   const { return m_data.toWeakRef(); }
	QSharedPointer<ScColorSpaceData> strongRef() const { return m_data; }
};

#endif
